自定义数据对象。 QD提供了Daily,Bar,Quote,Trade等数据对象,但可以自己定义一些数据类型。 下面的代码定义一个复权数据对象(含日期、复权因子序列): Code: using System; using System.Collections.Generic; using System.Text; using SmartQuant; using SmartQuant.Data; namespace SmartQuant.Data { [Serializable] public class PriceFactor: IDataObject,ISeriesObject,ICloneable { private DateTime dateTime; private double factor; private byte providerId; public PriceFactor(DateTime datetime, double factor) { this.providerId = 0; this.dateTime = datetime; this.factor = factor; } public PriceFactor(PriceFactor pricefactor):this(pricefactor.dateTime,pricefactor.factor) { } public PriceFactor():this(DateTime.MinValue,0) { } public override string ToString() { return string.Format("{0} , Factor = {1}", this.dateTime, this.factor); } [View] public double Factor { get { return this.factor; } set { this.factor = value; } } #region IDataObject 成员 public DateTime DateTime { get { return this.dateTime; } set { this.dateTime = value; } } public byte ProviderId { get { return this.providerId; } set { this.providerId = value; } } #endregion #region ISeriesObject 成员 public ISeriesObject NewInstance() { return new PriceFactor(); } public void ReadFrom(System.IO.BinaryReader reader) { byte num = reader.ReadByte(); //switch (num) //{ // case 1: // this.dateTime = new System.DateTime(reader.ReadInt64()); // this.factor = Math.Round((double)reader.ReadSingle(), 4); // this.providerId = reader.ReadByte(); // return; // case 2: this.dateTime = new System.DateTime(reader.ReadInt64()); this.factor = reader.ReadDouble(); this.providerId = reader.ReadByte(); return; //} //throw new Exception("Unknown version - " + num); } public void WriteTo(System.IO.BinaryWriter writer) { writer.Write((byte)2); writer.Write(this.dateTime.Ticks); writer.Write(this.factor); writer.Write(this.providerId); } #endregion #region ICloneable 成员 public object Clone() { return new PriceFactor(this); } #endregion } } 下面是一个复权类: Code: using System; using System.Collections.Generic; using System.Text; using SmartQuant; using SmartQuant.Instruments; namespace SmartQuant.Data { public class FqBar { SortedList<DateTime, double> factorList = new SortedList<DateTime, double>(); double maxfqyz = 1.0F;//最大复权因子 double curr_fqyz = 1.0F;//当前复权因子 int fqyzIndex = 0; public FqBar(string symbol) { Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { IDataSeries series = instrument.GetDataSeries("PriceFactor"); if (series != null) { foreach (PriceFactor factor in series) { if (!factorList.ContainsKey(factor.DateTime)) factorList.Add(factor.DateTime, factor.Factor); } } } if (factorList.Count > 0) { maxfqyz = factorList.Values[factorList.Count - 1]; factorList.Add(new DateTime(2100, 1, 1), 1);//增加一个无限大日期, } } public Bar GetFqBar(Bar bar) { if (factorList.Count > 0) { if (bar.DateTime < factorList.Keys[0]) { curr_fqyz = 1 / maxfqyz;//前复权因子 fqyzIndex = 0; } else { for (int j = fqyzIndex; j < factorList.Count - 1; j++) { if (factorList.Keys[j] <= bar.DateTime && bar.DateTime < factorList.Keys[j + 1]) { curr_fqyz = factorList.Values[j] / maxfqyz; //前复权因子 fqyzIndex = j; break; } } } //复权 bar.Open = bar.Open * curr_fqyz; bar.High = bar.High * curr_fqyz; bar.Low = bar.Low * curr_fqyz; bar.Close = bar.Close * curr_fqyz; //bar.Volume = (int)(bar.Volume * curr_fqyz); } //复权处理结束 return bar; } } }
这是一个读POBO(澎博)本地数据(不是实时数据)的Provider: Code: using System; using System.Drawing; using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing.Design; using System.Windows.Forms; using System.Collections; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Threading; using System.Reflection.Emit; using System.Reflection; using System.Net; using System.IO; using System.Net.Sockets; using SmartQuant.FIX; using SmartQuant.Providers; using SmartQuant.Instruments; using SmartQuant.Data; using SmartQuant.File; namespace SmartQuant.Pobo { public class PoboLocalProvider : IProvider, IHistoryProvider { private string poboPath = @"D:\GLPobo\Pobo\"; private string poboBlocks = "我的板块"; public PoboLocalProvider() { ProviderManager.Add(this); } [Category("设置"),DefaultValue(@"D:\GLPobo\Pobo\")] public string PoboPath { get { return this.poboPath; } set { this.poboPath = value; } } [Category("设置"),Description("自动添加到Instrument的板块;\n多个板块以半角分号隔开。"), DefaultValue("我的板块")] public string PoboBlocks { get { return this.poboBlocks; } set { this.poboBlocks = value; } } #region IProvider 成员 private bool isConnected = false; public void Connect(int timeout) { this.Connect(); ProviderManager.WaitConnected(this, timeout); } public void Connect() { if (System.IO.Directory.Exists(this.poboPath)) { PoboReader.PoboPath = this.PoboPath; SortedList<string, PoboSymbol> poboSymbolList = PoboReader.PoboSymbolList; string[] blockArray = this.poboBlocks.Split(';'); for (int i = 0; i < blockArray.Length;i++ ) { Dictionary<string, string> dict = PoboReader.GetBlockSymbols(blockArray[i]); foreach (string symbol in dict.Keys) { if (poboSymbolList.ContainsKey(symbol) && !InstrumentManager.Instruments.Contains(symbol)) { PoboSymbol pbsymbol = poboSymbolList[symbol]; Instrument instrument = new Instrument(symbol, "Futures"); instrument.SecurityDesc = pbsymbol.Name; //instrument.SecurityExchange = pbsymbol.FolderName; instrument.Save(); } } } isConnected = true; if (Connected != null) Connected(this, new EventArgs()); } else { this.EmitError(-1, -1, this.poboPath+"的Pobo文件夹不存在!"); } } public event EventHandler Connected; public void Disconnect() { isConnected = false; if (Disconnected != null) Disconnected(this, new EventArgs()); } public event EventHandler Disconnected; public event ProviderErrorEventHandler Error; [Category("信息")] public byte Id { get { return 132; } } [Category("信息")] public bool IsConnected { get { return isConnected; } } [Category("信息")] public string Name { get { return "PoboLocal"; } } public void Shutdown() { return; } [Category("信息")] public ProviderStatus Status { get { if (!IsConnected) return ProviderStatus.Disconnected; else return ProviderStatus.Connected; } } public event EventHandler StatusChanged; [Category("信息")] public string Title { get { return "Pobo's 本地数据 Provider"; } } [Category("信息")] public string URL { get { return ""; } } #endregion private void EmitError(int id, int code, string message) { if (Error != null) Error(new ProviderErrorEventArgs(new ProviderError(Clock.Now, this, id, code, message))); } #region IHistoryProvider 成员 [Category("支持类型")] public bool BarSupported { get { return false; } } [Category("支持类型")] public bool DailySupported { get { return true; } } [Category("支持类型")] public bool QuoteSupported { get { return false; } } [Category("支持类型")] public bool TradeSupported { get { return false; } } public Bar[] GetBarHistory(IFIXInstrument instrument, DateTime datetime1, DateTime datetime2, int barSize) { throw new NotImplementedException(); } public Daily[] GetDailyHistory(IFIXInstrument instrument, DateTime datetime1, DateTime datetime2, bool dividendAndSplitAdjusted) { lock (this) { List<Daily> list = new List<Daily>(); string symbol = instrument.Symbol; SortedList<string, PoboSymbol> poboSymbolList = PoboReader.PoboSymbolList; if (poboSymbolList.ContainsKey(symbol)) { PoboSymbol pbsymbol = poboSymbolList[symbol]; list = PoboReader.GetDailyList(pbsymbol); } return (list.ToArray()); } } public Quote[] GetQuoteHistory(IFIXInstrument instrument, DateTime datetime1, DateTime datetime2) { throw new NotImplementedException(); } public Trade[] GetTradeHistory(IFIXInstrument instrument, DateTime datetime1, DateTime datetime2) { throw new NotImplementedException(); } #endregion } /// <summary> /// 读取Pobo本地数据。 /// </summary> public class PoboReader { private static string poboPath = ""; public static string PoboPath { get { return poboPath; } set { poboPath = value; } } public static SortedList<string, PoboSymbol> PoboSymbolList { get { SortedList<string, PoboSymbol> poboSymbolList = new SortedList<string, PoboSymbol>(); SortedList<string, PoboMarketInfo> mktList = GetMarketInfo(); for (int m = 0; m < mktList.Count; m++) { SortedList<string, PoboSymbol> list = GetSymbolList(mktList.Values[m].FolderName); for (int i = 0; i < list.Count; i++) { PoboSymbol pbSymbol = list.Values[i]; pbSymbol.FolderName = mktList.Values[m].FolderName; if (!poboSymbolList.ContainsKey(list.Keys[i])) poboSymbolList.Add(list.Keys[i], pbSymbol); } } return poboSymbolList; } } /// <summary> /// 从mkinfo.cfg获取PoboMarketInfo /// </summary> /// <returns></returns> public static SortedList<string, PoboMarketInfo> GetMarketInfo() { SortedList<string, PoboMarketInfo> list = new SortedList<string, PoboMarketInfo>(); FileStream fs = new FileStream(Path.Combine(poboPath, @"cfg\mkinfo.cfg"), FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); long pos = 0; long l = fs.Length; while (pos < l) { fs.Position = pos; PoboMarketInfo mktInfo = new PoboMarketInfo(); mktInfo.ID = br.ReadByte(); fs.Position += 1; string s = Encoding.Default.GetString(br.ReadBytes(15)); s = s.Substring(0, s.IndexOf("\0") + 1).Replace("\0", ""); mktInfo.Name = s; mktInfo.FolderName = Encoding.Default.GetString(br.ReadBytes(8)).Replace("\0", ""); list.Add(mktInfo.FolderName, mktInfo); pos += 1590; } br.Close(); fs.Close(); return list; } /// <summary> /// 从Nametbl.pb 获取PoboSymbol /// </summary> /// <param name="marketFolder"></param> /// <returns></returns> public static SortedList<string, PoboSymbol> GetSymbolList(string marketFolder) { SortedList<string, PoboSymbol> list = new SortedList<string, PoboSymbol>(); FileStream fs = new FileStream(Path.Combine(poboPath, @"data\" + marketFolder + @"\NAMETBL.PB"), FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); long pos = 0; long l = fs.Length; //sas:input u1 ib2. dm $6. u2 ib1. jc $8. u3 ib1. bs ib2. ; while (pos < l) { fs.Position = pos + 2; PoboSymbol poboSymbol = new PoboSymbol(); string s = Encoding.Default.GetString(br.ReadBytes(6)); poboSymbol.Symbol = s.Trim().Replace("\0", ""); fs.Position += 1; s = Encoding.Default.GetString(br.ReadBytes(8)); poboSymbol.Name = s.Trim().Replace("\0", ""); fs.Position += 1; poboSymbol.Divisor = br.ReadInt16(); fs.Position += 6; poboSymbol.PriceDigits = br.ReadByte(); //offset:1A fs.Position += 1; poboSymbol.No = br.ReadByte(); poboSymbol.FolderName = marketFolder; if (!list.ContainsKey(poboSymbol.Symbol)) list.Add(poboSymbol.Symbol, poboSymbol); pos += 32; } br.Close(); fs.Close(); return list; } /// <summary> /// 取板块中的代码及其所处目录名 /// </summary> /// <param name="blockName">板块名称</param> /// <returns>代码及其所处目录名</returns> public static Dictionary<string, string> GetBlockSymbols(string blockName) { Dictionary<string, string> dict = new Dictionary<string, string>(); string userPath = IniFile.ReadIniData("PATH", "userpath", "", Path.Combine(PoboPath, @"cfg\userpath.ini")); string s = ""; int blockID = 1; do { s = IniFile.ReadIniData(blockName, "i" + blockID.ToString().Trim(), "", Path.Combine(userPath, @"blocks.ini")); string[] ss = s.Split('\x20'); if (ss.Length >= 2) { if (!dict.ContainsKey(ss[1])) dict.Add(ss[1], ss[0]); } blockID++; } while (s != ""); return dict; } public static List<Daily> GetDailyList(PoboSymbol pbSymbol) { List<Daily> dailyList = new List<Daily>(); string filePath = Path.Combine(poboPath, @"data\" + pbSymbol.FolderName + @"\Day\" + pbSymbol.Symbol.Trim() + @".DAY"); if (System.IO.File.Exists(filePath)) { FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); double div = pbSymbol.Divisor * 1.0; int pd = pbSymbol.PriceDigits; long pos = 0; long filelen = fs.Length; while (pos < filelen) { fs.Position = pos; uint rq = br.ReadUInt32(); int sp = br.ReadInt32(); int kp = br.ReadInt32(); int zg = br.ReadInt32(); int zd = br.ReadInt32(); long sl = (long)Math.Round(br.ReadSingle(), 0); long cc = (long)Math.Round(br.ReadSingle(), 0); int y = int.Parse((rq >> 20).ToString()); int m = int.Parse((rq << 12 >> 28).ToString()); int d = int.Parse((rq << 16 >> 27).ToString()); Daily daily = new Daily(new DateTime(y, m, d), Math.Round(kp / div, pd), Math.Round(zg / div, pd), Math.Round(zd / div, pd), Math.Round(sp / div, pd), sl, cc); dailyList.Add(daily); pos += 32; } br.Close(); fs.Close(); } return dailyList; } } public struct PoboMarketInfo { public byte ID; public string Name; public string FolderName; } public struct PoboSymbol { public string Symbol; public string Name; public short Divisor; public byte PriceDigits; public byte No; public string FolderName; } public class IniFile { #region API函数声明 [System.Runtime.InteropServices.DllImport("kernel32")]//返回0表示失败,非0为成功 private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); [System.Runtime.InteropServices.DllImport("kernel32")]//返回取得字符串缓冲区的长度 private static extern long GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath); #endregion #region 读Ini文件 public static string ReadIniData(string Section, string Key, string NoText, string iniFilePath) { if (System.IO.File.Exists(iniFilePath)) { StringBuilder temp = new StringBuilder(1024); GetPrivateProfileString(Section, Key, NoText, temp, 1024, iniFilePath); return temp.ToString(); } else { return String.Empty; } } #endregion #region 写Ini文件 public static bool WriteIniData(string Section, string Key, string Value, string iniFilePath) { if (System.IO.File.Exists(iniFilePath)) { long OpStation = WritePrivateProfileString(Section, Key, Value, iniFilePath); if (OpStation == 0) { return false; } else { return true; } } else { return false; } } #endregion } }
这是自动导入WIND金融终端本地数据的Provider,不是真正的HistoryProvider.. connect时自动导入数据: Code: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Microsoft.Win32; using System.Threading; using System.Text.RegularExpressions; using System.IO; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Drawing.Design; using SmartQuant; using SmartQuant.Data; using SmartQuant.Series; using SmartQuant.Providers; using SmartQuant.Instruments; namespace Drzwz { public class Wind2SQ : IProvider, IHistoryProvider { public Wind2SQ() { ProviderManager.Add(this); } #region 导入数据的方法 private string windPath = @"D:\Wind\Wind.NET.Client\WindNET\"; private string symbolRegex = @"(\d{6}\.S[HZ])"; private bool autoImport = true; [Category("设置"), Description("Wind.NET安装目录"), DefaultValue(@"D:\Wind\Wind.NET.Client\WindNET\"), Editor(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))] public string WindPath { get { return this.windPath; } set { this.windPath = value.Trim(); } } [Category("设置"), Description("要导入数据的代码的正则表达式;若为空则导入WIND数据目录下所有代码的数据。"), DefaultValue(@"(\d{6}\.S[HZ])")] public string SymbolRegex { get { return this.symbolRegex; } set { this.symbolRegex = value.Trim(); } } [Category("设置"), Description("true-连接后自动导入;false-连接后不导入,若运行中,则中断导入。"), DefaultValue("")] public bool AutoImport { get { return this.autoImport; } set { this.autoImport = value; } } private void doWork() { try { WindData wd = new WindData(); wd.IncludeZeroVolume = false;//不含停牌数据 wd.HistoryDataType = 0;//0--原始数据 List<Daily> lst; SortedList<string, string> nameList = wd.GetSecurityNames(); DailySeries ds; IDataSeries ids; Instrument instrument; List<string> symbolList; symbolList = wd.GetStocklist(this.symbolRegex);//代码REGEX int i = 0; DateTime dt1, maxDateFqyz; //string securitytype; StringBuilder sb = new StringBuilder(); sb.AppendLine(); Console.WriteLine("{0} 开始导入数据...", DateTime.Now); int num = 0; foreach (string symbol in symbolList) { Application.DoEvents(); if (!this.autoImport) { Console.WriteLine("{0} 处理了{1}个代码后,用户中断操作(AutoImport被设为False)。", DateTime.Now, num); break; } //securitytype = Drzwz.SQCommon.GetSecurityType(symbol); //Console.WriteLine("{0} 正在读取{1}...", DateTime.Now, symbol); //判断该symbol是否已存在 instrument = InstrumentManager.Instruments[symbol]; if (instrument == null) { instrument = new Instrument(symbol, "Z"); instrument.SecurityExchange = symbol.Substring(symbol.LastIndexOf(".") + 1, symbol.Length - symbol.LastIndexOf(".") - 1); ; if (nameList != null && nameList.Count > 0) { if (nameList.ContainsKey(symbol)) { instrument.SecurityDesc = nameList[symbol]; } } instrument.Save(); sb.Append(symbol + "(新)"); //Console.WriteLine("{0} 添加SYMBOL {1}。", DateTime.Now, symbol); } else { sb.Append( symbol+" "); } num++; if (num % 10 == 0) sb.AppendLine(); //导入Daily数据 //Console.WriteLine("{0} 准备导入{1}的数据。", DateTime.Now, symbol); ds = DataManager.GetDailySeries(instrument); if (ds != null && ds.Count > 0)//Daily 已经存在 { dt1 = ds.LastDateTime; } else { dt1 = new DateTime(1901, 1, 1); } if (symbol.EndsWith(".HK") || symbol.EndsWith(".HI")) wd.IncludeZeroVolume = true; else wd.IncludeZeroVolume = false; lst = wd.getDailyList(symbol, dt1, DateTime.Now.AddDays(1)); if (lst != null && lst.Count > 0) { Daily daily; foreach (Daily d in lst) { //Console.WriteLine("{0} {1} {2} {3} {4} {5} ",daily.dt, daily.open, daily.high, daily.low, daily.close, daily.volume); daily = new Daily(d.DateTime,d.Open,d.High,d.Low,d.Close,d.Volume,d.OpenInt); instrument.Add(daily); //Console.WriteLine(" debug: {0} {1}",symbol,daily.DateTime.ToString()); } } } Console.WriteLine("{0} 导入完成,共导入{1}个代码。\n {2}", DateTime.Now,num,sb.ToString()); this.Disconnect(); } catch (Exception ex) { Console.WriteLine(ex.Message); } } #endregion #region IProvider 成员 private bool isConnected = false; public void Connect(int timeout) { this.Connect(); ProviderManager.WaitConnected(this, timeout); } public void Connect() { isConnected = true; Console.WriteLine("{0} Connected!",DateTime.Now); if (Connected != null) Connected(this, new EventArgs()); this.doWork(); //Thread th = new Thread(new ThreadStart(this.doWork)); //th.Start(); } public event EventHandler Connected; public void Disconnect() { try { Console.WriteLine("{0} Disconnected!",DateTime.Now); isConnected = false; if (Disconnected != null) Disconnected(this, new EventArgs()); } catch (Exception ex) { Console.WriteLine("Disconnect:" + ex.Message); } } public event EventHandler Disconnected; public event ProviderErrorEventHandler Error; [Category("信息")] public byte Id { get { return 112; } } [Category("信息")] public bool IsConnected { get { return isConnected; } } [Category("信息")] public string Name { get { return "Wind2SQ"; } } [Category("信息")] public string Title { get { return "Wind2SQ 自动将Wind Daily行情数据导入SQ;会自动添加Instrument。"; } } [Category("信息")] public string URL { get { return String.Empty; } } public void Shutdown() { } [Category("信息")] public ProviderStatus Status { get { if (!IsConnected) return ProviderStatus.Disconnected; else return ProviderStatus.Connected; } } public event EventHandler StatusChanged; #endregion #region IHistoryProvider 成员 [Category("信息")] public bool BarSupported { get { return false; } } [Category("信息")] public bool DailySupported { get { return false; } } public Bar[] GetBarHistory(SmartQuant.FIX.IFIXInstrument instrument, DateTime datetime1, DateTime datetime2, int barSize) { throw new NotImplementedException(); } public Daily[] GetDailyHistory(SmartQuant.FIX.IFIXInstrument instrument, DateTime datetime1, DateTime datetime2, bool dividendAndSplitAdjusted) { throw new NotImplementedException(); } public Quote[] GetQuoteHistory(SmartQuant.FIX.IFIXInstrument instrument, DateTime datetime1, DateTime datetime2) { throw new NotImplementedException(); } public Trade[] GetTradeHistory(SmartQuant.FIX.IFIXInstrument instrument, DateTime datetime1, DateTime datetime2) { throw new NotImplementedException(); } [Category("信息")] public bool QuoteSupported { get { return false; } } [Category("信息")] public bool TradeSupported { get { return false; } } #endregion } #region WIND数据操作类 public class WindData { public WindData() { } private string windPath = @"D:\Wind\Wind.NET.Client\WindNET\"; private string WWTPath = @"D:\Windin\WWT\"; [Category("设置"), Description("Wind安装路径")] public string WindPath { get { return windPath; } set { string t = value.Trim(); if (t.EndsWith(@"\") == false) t = t + @"\"; if (Directory.Exists(t) == false) MessageBox.Show("路径" + t + " 不存在!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); else if (Directory.Exists(t + @"data\") == false || Directory.Exists(t + @"etc\") == false) MessageBox.Show("路径" + t + " 不是有效的WIND安装路径", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); else windPath = t; } } private bool includeZeroVolume = false;//包含停牌日数据 [Category("设置"), Description("是否包含成交量为0的数据:True--包括停牌数据,False--剔除停牌数据")] public bool IncludeZeroVolume { get { return includeZeroVolume; } set { includeZeroVolume = value; } } public enum DataTypeStruct { data原始数据 = 0, data向前复权 = 1, data向后复权 = 2 } int historyDataType = 1; [Description("历史行情数据类型(0-原始数据,1-向前复权,2-向后复权)"), Category("设置")] public DataTypeStruct HistoryDataType { get { if (historyDataType == 1) return DataTypeStruct.data向前复权; else if (historyDataType == 2) return DataTypeStruct.data向后复权; else return DataTypeStruct.data原始数据; } set { if (value == DataTypeStruct.data向前复权) historyDataType = 1; else if (value == DataTypeStruct.data向后复权) historyDataType = 2; else historyDataType = 0; } } public List<string> GetStocklist(string symboRegexl) { List<string> stockList = new List<string>(); try { SortedList<string,string> lst; lst = this.GetSecurityNames(); for(int i=0;i<lst.Count;i++) { if (Regex.IsMatch(lst.Keys[i], symboRegexl ) == true) { stockList.Add(lst.Keys[i]); } } } catch (Exception ex) { Console.WriteLine("GetStocklist error {0}", ex.Message); } return stockList; } public List<Daily> getDailyList(string symbol,DateTime dt1, DateTime dt2) { List<Daily> hqList = new List<Daily>(); try { int dataType=this.historyDataType; string dm = symbol.Trim().ToUpper(); int iDt1, iDt2; DateTime dt1900 = new DateTime(1900, 1, 1); DateTime dt2100 = new DateTime(2100, 1, 1); if (dt1 > dt1900) iDt1 = dt1.Year * 10000 + dt1.Month * 100 + dt1.Day; else iDt1 = 19000101; if (dt2 > dt1900) iDt2 = dt2.Year * 10000 + dt2.Month * 100 + dt2.Day; else iDt2 = 21000101; #region x读取原始数据 if (dataType == 0) { bool isFundNav = false; if (dm.EndsWith("NV.SH") || dm.EndsWith("NV.SZ") || dm.EndsWith(".OF")) isFundNav = true; string windFileName = getFullName(windPath, symbol); if (!File.Exists(windFileName)) return null; FileStream fs = new FileStream(windFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); BinaryReader br = new BinaryReader(fs); long recordCount; if (isFundNav) recordCount = fs.Length / 8; else recordCount = fs.Length / 28; int rq, sl; double kp, zg, zd, sp,je; for (long r = 0; r < recordCount; r++) { if (isFundNav) { fs.Position = r * 8; rq = br.ReadInt32();if (rq < iDt1 || rq > iDt2) continue; kp = (double)br.ReadSingle(); zg = kp; zd = kp; sp = kp; sl = 0; je = 0; } else { fs.Position = r * 28; rq = br.ReadInt32(); if (rq < iDt1 || rq > iDt2) continue; kp = (double)br.ReadSingle();zg = (double)br.ReadSingle(); zd = (double)br.ReadSingle();sp = (double)br.ReadSingle(); je = (double)br.ReadSingle(); sl = (int)br.ReadSingle(); } string rqs = rq.ToString().Trim(); DateTime date = new DateTime(int.Parse(rqs.Substring(0, 4)), int.Parse(rqs.Substring(4, 2)), int.Parse(rqs.Substring(6, 2)));//日期 Daily bar = new Daily(); bar.DateTime = date;bar.Open = kp;bar.High = zg; bar.Low = zd; bar.Close = sp; bar.Volume = sl; bar.OpenInt = (long) Math.Round(je,0); if (isFundNav || includeZeroVolume) hqList.Add(bar); else if(sl>0) hqList.Add(bar); } fs.Close(); br.Close(); return hqList; } #endregion #region x读取复权数据 else { //读复权因子 SortedList<DateTime, double> lst; double maxfqyz=1.0;//最大复权因子 double fqyz=1.0;//当前复权因子 int fqyzIndex = 0; string filename = WWTPath +@"etc\hqafhis.dat"; lst = GetFqyz(filename, dm); filename = WWTPath +@"etc\hqafdelt.dat"; SortedList<DateTime, double> lst2 = GetFqyz(filename, dm); if(lst==null) lst=lst2; foreach (DateTime dt in lst2.Keys) if (!lst.ContainsKey(dt)) lst.Add(dt, lst2[dt]); if (lst!=null && lst.Count > 0) { maxfqyz = lst.Values[lst.Count - 1]; lst.Add(new DateTime(2100, 1, 1), maxfqyz);//增加一个无限大日期, } bool isFundNav = false; if (dm.EndsWith("NV.SH") || dm.EndsWith("NV.SZ") || dm.EndsWith(".OF")) { isFundNav = true; } string windFileName = getFullName(windPath, dm); if (!File.Exists(windFileName)) { return null; } FileStream fs = new FileStream(windFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); BinaryReader br = new BinaryReader(fs); long recordCount; if (isFundNav) recordCount = fs.Length / 8; else recordCount = fs.Length / 28; int rq, sl; double kp, zg, zd, sp,je; for (long r = 0; r < recordCount; r++) { if (isFundNav) { fs.Position = r * 8; rq = br.ReadInt32();if (rq < iDt1 || rq > iDt2) continue; kp = (double)br.ReadSingle(); zg = kp; zd = kp; sp = kp; je = kp; sl = 0; } else { fs.Position = r * 28; rq = br.ReadInt32();if (rq < iDt1 || rq > iDt2) continue; kp = (double)br.ReadSingle();zg = (double)br.ReadSingle();zd = (double)br.ReadSingle(); sp = (double)br.ReadSingle();je = (double)br.ReadSingle();sl = (int)br.ReadSingle(); } string rqs = rq.ToString().Trim(); DateTime date = new DateTime(int.Parse(rqs.Substring(0, 4)), int.Parse(rqs.Substring(4, 2)), int.Parse(rqs.Substring(6, 2)));//日期 //Console.WriteLine(symbol+" "+rqs); //复权处理 if (lst.Count > 0) { if (date < lst.Keys[0]) { fqyz = 1; //后复权因子 if (dataType == 1) //向前复权 { fqyz = 1 / maxfqyz;//前复权因子 } kp = kp * fqyz; zg = zg * fqyz; zd = zd * fqyz; sp = sp * fqyz; fqyzIndex = 0; } else { for (int j = fqyzIndex; j < lst.Count-1; j++) { if (lst.Keys [j] <= date && date < lst.Keys[j + 1]) { fqyz = lst.Values[j]; //后复权因子 if (dataType == 1) //向前复权 { fqyz = lst.Values[j] / maxfqyz; //前复权因子 } kp = kp * fqyz; zg = zg * fqyz; zd = zd * fqyz; sp = sp * fqyz; fqyzIndex = j; break; } } } } //复权处理结束 Daily bar = new Daily(); bar.DateTime = date; bar.Open = kp; bar.High = zg; bar.Low = zd; bar.Close = sp; bar.Volume = sl; bar.OpenInt = (long)Math.Round(je,0); if (isFundNav || includeZeroVolume) hqList.Add(bar); else if (sl > 0 ) hqList.Add(bar); } fs.Close(); br.Close(); return hqList; } #endregion } catch (Exception ex) { Console.WriteLine("GetDailyList error: {0}", ex.Message); return null; } } public SortedList <DateTime, double > GetFqyz(string filename, string Symbol) { try { SortedList<DateTime, double> mylst = new SortedList<DateTime, double>(); string windFileName = filename; if (File.Exists(windFileName) == false) { Console.WriteLine("错误:文件不存在"); return null; } FileStream fs = new FileStream(windFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); BinaryReader br = new BinaryReader(fs); //string s = "";string ss=""; fs.Position=18; long recordCount = br.ReadUInt32();//第18字节开始的4B保存记录个数,接下来是每个记录,以0x09开头 for(int record=0;record<recordCount;record++) { byte flag = br.ReadByte(); if (flag == '\x09') { string dm = new string(br.ReadChars(9));//代码 string rqs = new string(br.ReadChars(8));//日期 double yz = br.ReadSingle();//复权因子 fs.Position=fs.Position+1; //有个00字节 short notelen = br.ReadInt16(); //备注字符串长度 fs.Position=fs.Position+notelen; //s=System.Text.Encoding.Default.GetString(br.ReadBytes(notelen));//备注字符串 //s=s.Replace("\x0D","").Replace("\x0A",""); //ss=dm+","+rq+","+yz.ToString() ; //Console.WriteLine(ss); if (dm==Symbol) { DateTime rq =new DateTime(int.Parse(rqs.Substring(0, 4)), int.Parse(rqs.Substring(4, 2)), int.Parse(rqs.Substring(6, 2))); if(!mylst.ContainsKey(rq)) mylst.Add(rq,yz); } } } fs.Close(); br.Close(); return mylst; } catch { return null; } } public SortedList <DateTime, double > GetFactorList(string symbol) { string filename = WWTPath +@"etc\hqafhis.dat"; SortedList<DateTime, double> lst = GetFqyz(filename, symbol); filename = WWTPath +@"etc\hqafdelt.dat"; SortedList<DateTime, double> lst2 = GetFqyz(filename, symbol); if(lst==null) {lst=lst2; } else { foreach (DateTime dt in lst2.Keys) if (!lst.ContainsKey(dt)) lst.Add(dt, lst2[dt]); } return lst; } public DateTime GetMaxDateFqyz(string symbol) { DateTime maxDate=new DateTime(1990,1,1); string filename = WWTPath +@"etc\hqafhis.dat"; SortedList<DateTime, double> lst = GetFqyz(filename, symbol); if(lst!=null && lst.Count>0) maxDate=lst.Keys[lst.Count-1]; filename = WWTPath +@"etc\hqafdelt.dat"; lst = GetFqyz(filename, symbol); if (lst!=null && lst.Count > 0) { DateTime maxDate2 = lst.Keys[lst.Count - 1]; if(maxDate2>maxDate) maxDate=maxDate2; } return maxDate; } public string getFullName(string windPath, string symbol) { string windFileName = null; string windDayPath = ""; string dm = symbol.Trim().ToUpper(); if (dm.EndsWith("NV.SH") || dm.EndsWith("NV.SZ") || dm.EndsWith(".OF")) { windDayPath = windPath + @"DATA\HQ\FUND\DAY\"; } else if (dm.EndsWith(".SH") || dm.EndsWith(".SZ")) windDayPath = windPath + @"DATA\HQ\STOCK\DAY\"; else if (dm.EndsWith(".OC")) windDayPath = windPath + @"DATA\HQ\OC\DAY\"; else if (dm.EndsWith("I") || dm.EndsWith(".CS") || dm.EndsWith(".BOC") || dm.EndsWith(".IL") || dm.EndsWith(".RB")) windDayPath = windPath + @"DATA\HQ\INDEX\DAY\"; else if (dm.EndsWith(".FX")) windDayPath = windPath + @"DATA\HQ\FX\DAY\"; else if (dm.EndsWith(".HK") || dm.EndsWith(".US")) windDayPath = windPath + @"DATA\HQ\HK\DAY\"; else windDayPath = windPath + @"DATA\HQ\STOCK\DAY\"; windFileName = windDayPath + symbol.Trim() + ".DAY"; //Console.WriteLine(windFileName); if (windPath.Trim().Length == 0) { windFileName = symbol.Trim() + ".Day"; } return windFileName; } public string getWindCode(string code) { string myCode = code.Trim().ToUpper(); if (Regex.IsMatch(myCode, @"(4[02]\d{4}.SZ)") == true) myCode.Replace(".SZ", ".OC"); return myCode; } public string getMyCode(string code) { string myCode = code.Trim().ToUpper(); if (myCode.EndsWith(".OC")) myCode = myCode.Replace(".OC", ".SZ"); return myCode; } //public string GetSecurityType(string symbol) //{ // string code = getMyCode(symbol.Trim().ToUpper()); // if (Regex.IsMatch(code, @"(000300.SH)|(000017.SH)|(00090\d.SH)|(\d*.GI)|(\d*.HI)") == true) // { // return "Index";//指数 // } // if (Regex.IsMatch(code, @"(60[0-8]\d{3}.SH)|(90\d{4}.SH)|(00[01256789]\d{3}.SZ)|(20\d{4}.SZ)|(4\d{5}.SZ)|(\d{4}.HK)") == true) // { // return "Stock";//股票 // } // else if (Regex.IsMatch(code, @"(00000\d\.SH)|(00001[0-6]\.SH)") == true) // { // return "Index"; // } // else if (Regex.IsMatch(code, @"([012]\d{5}.SH)|(1[0123]\d{4}.SZ)") == true && Regex.IsMatch(code, @"(181\d{3}.SH)") == false && Regex.IsMatch(code, @"(190\d{3}.SH)") == false) // { // return "Bond";//债券,FIX中细分各种债券,这里未区分 // } // else if (Regex.IsMatch(code, @"(510\d{3}.SH)|(159\d{3}.SZ)") == true) // { // return "ETF";// ETF // } // else if (Regex.IsMatch(code, @"(5[01]\d{4}.SH)|(184\d{3}.SZ)|(\d{6}.OF)|(\d{6}NV.OF)|(1[56]\d{4}.SZ)") == true) // { // return "Fund"; //封闭及开放基金,LOF // } // else if (Regex.IsMatch(code, @"(58\d{4}.SH)|(03\d{4}.SZ)") == true) // { // return "Warrant";//权证 // } // else if (Regex.IsMatch(code, @"(000\d{3}.SH)|(399\d{3}.SZ)|(8[013]\d{4}.SH)") == true) // { // return "Index"; // } // return "Z"; //} public string GetSecurityName(string Symbol) { try { string windFileName = windPath + @"ETC\SECBASICS.DAT"; if (File.Exists(windFileName) == false) { return ""; } FileStream fs = new FileStream(windFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); BinaryReader br = new BinaryReader(fs); string s = "", code = "", name = ""; long recordCount = fs.Length / 35; for (long r = 0; r < recordCount; r++) { fs.Position = r * 35; s = System.Text.Encoding.Default.GetString(br.ReadBytes(32)); code = s.Substring(0, s.IndexOf("\0")).ToUpper(); if (code == Symbol.ToUpper()) { name = s.Substring(12); name = name.Substring(0, name.IndexOf("\0")); return name; } } fs.Close(); br.Close(); return ""; } catch { return ""; } } public SortedList<string,string> GetSecurityNames() { SortedList<string,string> list = new SortedList<string,string>(); try { string windFileName = windPath + @"ETC\SECBASICS.DAT"; if (File.Exists(windFileName) == false) { Console.WriteLine("读取证券简称错误:文件不存在"); return null; } FileStream fs = new FileStream(windFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); BinaryReader br = new BinaryReader(fs); string s = "", code = "", name = ""; long recordCount = fs.Length / 35; for (long r = 0; r < recordCount; r++) { fs.Position = r * 35; s = System.Text.Encoding.Default.GetString(br.ReadBytes(32)); code = s.Substring(0,12).ToUpper().Replace("\0","").Trim(); if (code.Length>0) { name = s.Substring(12).Replace("\0","").Trim(); if(!list.Keys.Contains(code)) list.Add(code,name); //Console.WriteLine("{0} ,{1}",code,name); } } fs.Close(); br.Close(); return list; } catch(Exception ex) { Console.WriteLine("读取证券简称错误:{0}",ex.Message); return null; } } } //public struct barStruct //{ // public DateTime dt; // public double open; //开盘价 // public double high; //最高价 // public double low; //最低价 // public double close; //收盘价 // public int volume; //成交量 //} #endregion }
下面代码好象是把QD设为数据中心(DC),用了WCF,效率不高: Code: . using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Microsoft.Win32; using System.Threading; using System.Text.RegularExpressions; using System.IO; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Drawing.Design; using System.ServiceModel; using System.ServiceModel.Description; using SmartQuant; using SmartQuant.Data; using SmartQuant.Series; using SmartQuant.Providers; using SmartQuant.Instruments; namespace Drzwz { public class SQServiceProvider : IProvider, IHistoryProvider { public SQServiceProvider() { ProviderManager.Add(this); if (this.autoStartup) this.Connect(); } #region 提供服务的方法 private bool autoStartup = false; [Category("设置"), Description("true-自动启动;false-不启动。") ] public bool AutoStartup { get { return this.autoStartup; } set { this.autoStartup = value; } } private ServiceHost serviceHost = null; private string baseAddressUri = "http://localhost:3009/SQ"; string pipeaddress = "net.pipe://localhost/SQService"; [Category("信息")] public bool IsStarted { get { if (this.serviceHost == null) return false; return (this.serviceHost.State == CommunicationState.Opened); } } [Category("信息"), Description("Host状态,点击刷新。")] public CommunicationState HostState { get { return serviceHost.State; } } [Category("设置"), Description("")] public string BaseAddress { get { return this.baseAddressUri; } set { this.baseAddressUri = value; } } [Category("设置"), Description("")] public string PipeAddress { get { return this.pipeaddress; } set { this.pipeaddress = value; } } public void Restart() { this.Stop(); this.Start(); } public void Start() { try { //Console.WriteLine("CreateServiceHost..."); Uri baseAddress = new Uri(this.baseAddressUri); serviceHost = new ServiceHost(typeof(SQService), baseAddress); NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None); binding.MaxReceivedMessageSize = 6553600; serviceHost.AddServiceEndpoint(typeof(ISQService), binding, pipeaddress); ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); smb.HttpGetEnabled = true; serviceHost.Description.Behaviors.Add(smb); serviceHost.Open(); if (this.Started != null) { this.Started(this, EventArgs.Empty); } } catch (CommunicationException exception) { serviceHost.Abort(); if (Trace.IsLevelEnabled(TraceLevel.Error)) { Trace.WriteLine(exception.ToString()); } if (Environment.UserInteractive) { MessageBox.Show(null, "启动SQService时出错:" + Environment.NewLine + Environment.NewLine + "Please check connector's settings like TCP port, network address, etc and try again." + Environment.NewLine + Environment.NewLine + "See log file for details.", "Cannot start service.", MessageBoxButtons.OK, MessageBoxIcon.Hand); } } } public event EventHandler Started; public void Stop() { if (this.IsStarted) { serviceHost.Close(); if (this.Stopped != null) { this.Stopped(this, EventArgs.Empty); } } } public event EventHandler Stopped; #endregion #region IProvider 成员 private bool isConnected = false; public void Connect(int timeout) { this.Connect(); ProviderManager.WaitConnected(this, timeout); } public void Connect() { this.Start(); isConnected = true; Console.WriteLine("{0} {1} Connected!",DateTime.Now,this.Name); if (Connected != null) Connected(this, new EventArgs()); //Thread th = new Thread(new ThreadStart(this.doWork)); //th.Start(); } public event EventHandler Connected; public void Disconnect() { try { this.Stop(); Console.WriteLine("{0} {1} Disconnected!", DateTime.Now,this.Name); isConnected = false; if (Disconnected != null) Disconnected(this, new EventArgs()); } catch (Exception ex) { Console.WriteLine("Disconnect:" + ex.Message); } } public event EventHandler Disconnected; public event ProviderErrorEventHandler Error; [Category("信息")] public byte Id { get { return 115; } } [Category("信息")] public bool IsConnected { get { return isConnected; } } [Category("信息")] public string Name { get { return "SQService"; } } [Category("信息")] public string Title { get { return "数据服务。"; } } [Category("信息")] public string URL { get { return String.Empty; } } public void Shutdown() { try { this.Stop(); } catch { } } [Category("信息")] public ProviderStatus Status { get { if (!IsConnected) return ProviderStatus.Disconnected; else return ProviderStatus.Connected; } } public event EventHandler StatusChanged; #endregion #region IHistoryProvider 成员 [Category("信息")] public bool BarSupported { get { return false; } } [Category("信息")] public bool DailySupported { get { return false; } } public Bar[] GetBarHistory(SmartQuant.FIX.IFIXInstrument instrument, DateTime datetime1, DateTime datetime2, int barSize) { throw new NotImplementedException(); } public Daily[] GetDailyHistory(SmartQuant.FIX.IFIXInstrument instrument, DateTime datetime1, DateTime datetime2, bool dividendAndSplitAdjusted) { throw new NotImplementedException(); } public Quote[] GetQuoteHistory(SmartQuant.FIX.IFIXInstrument instrument, DateTime datetime1, DateTime datetime2) { throw new NotImplementedException(); } public Trade[] GetTradeHistory(SmartQuant.FIX.IFIXInstrument instrument, DateTime datetime1, DateTime datetime2) { throw new NotImplementedException(); } [Category("信息")] public bool QuoteSupported { get { return false; } } [Category("信息")] public bool TradeSupported { get { return false; } } #endregion } } Code: using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Runtime.CompilerServices; using System.ServiceModel; using System.ServiceModel.Description; using System.Windows.Forms; using System.Runtime.Serialization; using SmartQuant; using SmartQuant.Data; using SmartQuant.Charting; using SmartQuant.FIX; using SmartQuant.Instruments; using SmartQuant.Series; using SmartQuant.DataCenterLib; namespace Drzwz { [ServiceContract] public interface ISQService { [OperationContract] bool SetSymbol(string symbol, string securityName, string securityType, string securityExchange);//zzz [OperationContract] bool SetDailyList(string symbol, List<Daily> list);//zzz [OperationContract] bool SetPriceFactorList(string symbol, List<PriceFactor> list);//zzz [OperationContract] bool SetBarList(string symbol, List<Bar> list);//zzz [OperationContract] bool SetQuoteList(string symbol, List<Quote> list);//zzz [OperationContract] bool SetTradeList(string symbol, List<Trade> list);//zzz [OperationContract] DataSeriesInfo GetSeriesInfo(string series);//zzz [OperationContract] List<DataSeriesInfo> GetDataSeriesInfo(); [OperationContract] IDataSeriesEnumerator GetEnumerator(string series, DateTime datetime1, DateTime datetime2); [OperationContract] ArrayList GetSecurityDefinitionList(string symbol, string securityType, string securityExchange); [OperationContract] List<string> GetSymbolList(string symbol, string securityType, string securityExchange);//zzz [OperationContract] SortedList<string, string> GetSecurityNameList(string symbol, string securityType, string securityExchange); //zzz [OperationContract] SortedList<string, string> GetSecurityTypeList(string symbol, string securityType, string securityExchange); //zzz [OperationContract] SortedList<DateTime, double> GetPriceFactorList(string symbol);//zzz [OperationContract] List<Daily> GetDailyList(string symbol, DateTime datetime1, DateTime datetime2); [OperationContract] List<Daily> GetDailyAdjList(string symbol, DateTime datetime1, DateTime datetime2);//zzz [OperationContract] List<Bar> GetBarList(string symbol, DateTime datetime1, DateTime datetime2, int barSize); [OperationContract] List<Quote> GetQuoteList(string symbol, DateTime datetime1, DateTime datetime2); [OperationContract] List<Trade> GetTradeList(string symbol, DateTime datetime1, DateTime datetime2); } [ServiceBehavior(MaxItemsInObjectGraph = 6553600)] public class SQService : ISQService { public bool SetSymbol(string symbol, string securityName, string securityType, string securityExchange) { if (InstrumentManager.Instruments[symbol] == null) { Instrument instrument; instrument = new Instrument(symbol, securityType); instrument.SecurityDesc = securityName; instrument.SecurityExchange = securityExchange; instrument.Save(); //Console.WriteLine( string.Format("添加Symbol:{0}",symbol) ); } return true; } public bool SetDailyList(string symbol, List<Daily> list) { Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { if (list.Count > 0) { try { foreach (Daily d in list) instrument.Add(d); //Console.WriteLine(string.Format("添加Daily:{0},{1}", symbol,list.Count)); } catch { return false; } } } return true; } public bool SetPriceFactorList(string symbol, List<PriceFactor> list) { Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { if (list.Count > 0) { try { IDataSeries ids = instrument.GetDataSeries("PriceFactor"); if (ids == null) ids = instrument.AddDataSeries("PriceFactor"); foreach (PriceFactor f in list) { if (ids.Count > 0) { if (f.DateTime <= ids.LastDateTime) continue; } ids.Add(f.DateTime, f); } //Console.WriteLine(string.Format("添加PriceFactor:{0},After {1}", symbol, ids.LastDateTime)); } catch { return false; } } } return true; } public bool SetBarList(string symbol, List<Bar> list) { Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { if (list.Count > 0) { try { foreach (Bar d in list) instrument.Add(d); //Console.WriteLine(string.Format("添加Bar:{0},{1}", symbol, list.Count)); } catch { return false; } } } return true; } public bool SetQuoteList(string symbol, List<Quote> list) { Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { if (list.Count > 0) { try { foreach (Quote d in list) instrument.Add(d); //Console.WriteLine(string.Format("添加Quote:{0},{1}", symbol, list.Count)); } catch { return false; } } } return true; } public bool SetTradeList(string symbol, List<Trade> list) { Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { if (list.Count > 0) { try { foreach (Trade d in list) instrument.Add(d); //Console.WriteLine(string.Format("添加Trade:{0},{1}", symbol, list.Count)); } catch { return false; } } } return true; } public DataSeriesInfo GetSeriesInfo(string series) { DataSeriesInfo info = null; IDataSeries s = DataManager.Server.GetDataSeries(series); if (s == null) { //System.Windows.Forms.MessageBox.Show("s==null"); return null; } if (s.Count == 0) { info = new DataSeriesInfo(s.Name, s.Description); } else { info = new DataSeriesInfo(s.Name, s.Description, s.Count, s.FirstDateTime, s.LastDateTime); } return info; } public IDataSeriesEnumerator GetEnumerator(string series, DateTime datetime1, DateTime datetime2) { return new DataSeriesEnumerator(series, datetime1, datetime2); } public List<DataSeriesInfo> GetDataSeriesInfo() { List<DataSeriesInfo> list = new List<DataSeriesInfo>(); foreach (IDataSeries series in DataManager.Server.GetDataSeries()) { DataSeriesInfo info = null; if (series.Count == 0) { info = new DataSeriesInfo(series.Name, series.Description); } else { info = new DataSeriesInfo(series.Name, series.Description, series.Count, series.FirstDateTime, series.LastDateTime); } list.Add(info); } return (list); } public ArrayList GetSecurityDefinitionList(string symbol, string securityType, string securityExchange) { ArrayList list = new ArrayList(); foreach (Instrument instrument in InstrumentManager.Instruments) { if ((((symbol != null) && (instrument.Symbol != symbol)) || ((securityType != null) && (instrument.SecurityType != securityType))) || ((securityExchange != null) && (instrument.SecurityExchange != securityExchange))) { continue; } Hashtable hashtable = new Hashtable(); foreach (FIXField field in instrument.Fields.Values) { hashtable.Add(field.Tag, field.ToInvariantString()); } list.Add(hashtable); } return list; } public List<string> GetSymbolList(string symbol, string securityType, string securityExchange) { List<string> list = new List<string>(); foreach (Instrument instrument in InstrumentManager.Instruments) { if ((((symbol != null) && (instrument.Symbol != symbol)) || ((securityType != null) && (instrument.SecurityType != securityType))) || ((securityExchange != null) && (instrument.SecurityExchange != securityExchange))) { continue; } list.Add(instrument.Symbol); } return list; } public SortedList<string, string> GetSecurityTypeList(string symbol, string securityType, string securityExchange) { SortedList<string, string> list = new SortedList<string, string>(); foreach (Instrument instrument in InstrumentManager.Instruments) { if ((((symbol != null) && (instrument.Symbol != symbol)) || ((securityType != null) && (instrument.SecurityType != securityType))) || ((securityExchange != null) && (instrument.SecurityExchange != securityExchange))) { continue; } if (!list.ContainsKey(instrument.Symbol)) list.Add(instrument.Symbol, instrument.SecurityType); } return list; } public SortedList<string, string> GetSecurityNameList(string symbol, string securityType, string securityExchange) { SortedList<string, string> list = new SortedList<string, string>(); foreach (Instrument instrument in InstrumentManager.Instruments) { if ((((symbol != null) && (instrument.Symbol != symbol)) || ((securityType != null) && (instrument.SecurityType != securityType))) || ((securityExchange != null) && (instrument.SecurityExchange != securityExchange))) { continue; } if (!list.ContainsKey(instrument.Symbol)) list.Add(instrument.Symbol, instrument.SecurityDesc); } return list; } public List<Daily> GetDailyList(string symbol, DateTime datetime1, DateTime datetime2) { //Console.WriteLine("GetDailyList({0},{1},{2})", symbol,datetime1,datetime2); List<Daily> list = new List<Daily>(); //Daily daily = new Daily(new DateTime(2008,2,18),5,8,2,6,100); //list.Add(daily); Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { DailySeries dailySeries = instrument.GetDailySeries(datetime1, datetime2); if (dailySeries != null) { //foreach (Daily daily in dailySeries) //{ // list.Add(daily); //} for (int i = 0; i < dailySeries.Count; i++) { //Console.WriteLine("{0} {1}", dailySeries[i].DateTime, dailySeries[i].Close); list.Add(dailySeries[i]); } //Console.WriteLine("Counts:{0}", dailySeries.Count); } } return (list); } public SortedList<DateTime, double> GetPriceFactorList(string symbol) { SortedList<DateTime, double> list = new SortedList<DateTime, double>(); Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { IDataSeries series = instrument.GetDataSeries("PriceFactor"); if (series != null) { foreach (PriceFactor bar in series) { if (!list.ContainsKey(bar.DateTime)) list.Add(bar.DateTime, bar.Factor); } } } return list; } public List<Daily> GetDailyAdjList(string symbol, DateTime datetime1, DateTime datetime2) { //zzz 获取向前复权Daily List<Daily> list = new List<Daily>(); Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { DailySeries dailySeries = instrument.GetDailySeries(datetime1, datetime2); if (dailySeries != null) { SortedList<DateTime, double> factorList = GetPriceFactorList(symbol); if (factorList.Count > 0) { double fqyz = 1.0;//当前复权因子 double maxfqyz = 1.0;//最大复权因子 int fqyzIndex = 0; maxfqyz = factorList.Values[factorList.Keys.Count - 1]; factorList.Add(DateTime.MaxValue, maxfqyz); foreach (Daily daily in dailySeries) { #region 复权计算 DateTime date = daily.DateTime; double kp = daily.Open; double zg = daily.High; double zd = daily.Low; double sp = daily.Close; if (date < factorList.Keys[0]) { fqyz = 1 / maxfqyz;//前复权因子 kp = daily.Open * fqyz; zg = daily.High * fqyz; zd = daily.Low * fqyz; sp = daily.Close * fqyz; fqyzIndex = 0; } else { for (int j = fqyzIndex; j < factorList.Count - 1; j++) { if (factorList.Keys[j] <= date && date < factorList.Keys[j + 1]) { fqyz = factorList.Values[j] / maxfqyz; //前复权因子 kp = daily.Open * fqyz; zg = daily.High * fqyz; zd = daily.Low * fqyz; sp = daily.Close * fqyz; fqyzIndex = j; break; } } } daily.Open = kp; daily.High = zg; daily.Low = zd; daily.Close = sp; #endregion list.Add(daily); } } else { foreach (Daily daily in dailySeries) { list.Add(daily); } } } } return (list); } public List<Bar> GetBarList(string symbol, DateTime datetime1, DateTime datetime2, int barSize) { List<Bar> list = new List<Bar>(); Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { BarSeries series = instrument.GetBarSeries(datetime1, datetime2, BarType.Time, (long)barSize); if (series != null) { foreach (Bar bar in series) { list.Add(bar); } } } return (list); } public List<Quote> GetQuoteList(string symbol, DateTime datetime1, DateTime datetime2) { List<Quote> list = new List<Quote>(); Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { QuoteArray quoteArray = instrument.GetQuoteArray(datetime1, datetime2); if (quoteArray != null) { foreach (Quote quote in quoteArray) { list.Add(quote); } } } return (list); } public List<Trade> GetTradeList(string symbol, DateTime datetime1, DateTime datetime2) { List<Trade> list = new List<Trade>(); Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { TradeArray tradeArray = instrument.GetTradeArray(datetime1, datetime2); if (tradeArray != null) { foreach (Trade trade in tradeArray) { list.Add(trade); } } } return (list); } } internal class DataSeriesEnumerator : IDataSeriesEnumerator { private int currentIndex; private IDataSeries dataSeries; private int firstIndex; private int lastIndex; internal DataSeriesEnumerator(string series, DateTime datetime1, DateTime datetime2) { this.dataSeries = DataManager.Server.GetDataSeries(series); if (this.dataSeries != null) { this.firstIndex = this.dataSeries.IndexOf(datetime1, SearchOption.Next); this.lastIndex = this.dataSeries.IndexOf(datetime2, SearchOption.Exact); if (this.lastIndex == -1) { this.lastIndex = this.dataSeries.IndexOf(datetime2, SearchOption.Prev); } else { this.lastIndex--; } if (this.firstIndex > this.lastIndex) { this.firstIndex = -1; this.lastIndex = -1; } this.currentIndex = this.firstIndex; } else { this.firstIndex = -1; this.lastIndex = -1; this.currentIndex = -1; } } public SmartQuant.Data.IDataObject[] GetNextObjects(int count) { ArrayList list = new ArrayList(); while (count-- > 0) { if (this.currentIndex > this.lastIndex) { break; } list.Add(this.dataSeries[this.currentIndex]); this.currentIndex++; } return (SmartQuant.Data.IDataObject[])list.ToArray(typeof(SmartQuant.Data.IDataObject)); } public int Count { get { if (this.firstIndex != -1) { return ((this.lastIndex - this.firstIndex) + 1); } return 0; } } } } 测试代码(部分): Code: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using testSQService.Service1; using SmartQuant.Data; using SmartQuant.Series; namespace testSQService { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { SQServiceClient c = new SQServiceClient(); List<Daily> dailyList = c.GetDailyList("000001.SZ",new DateTime(2008,1,1),new DateTime(2008,4,4)); StringBuilder sb = new StringBuilder(); foreach (Daily d in dailyList) { sb.AppendLine(d.DateTime.ToString() + " " +d.Close.ToString("F2") ); } textBox1.Text=sb.ToString(); } } }
DC改用WCF协议通讯:? Code: using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Runtime.CompilerServices; using System.ServiceModel; using System.ServiceModel.Description; using System.Windows.Forms; using SmartQuant; using SmartQuant.Data; using SmartQuant.Charting; using SmartQuant.FIX; using SmartQuant.Instruments; using SmartQuant.Series; using SmartQuant.DataCenterLib; namespace Drzwz.DC { public class DCServiceConnector:IConnector { private ConnectorStartupType startupType = ConnectorStartupType.Automatic; private ServiceHost serviceHost=null; private string baseAddressUri = "http://localhost:3009/DC"; string pipeaddress = "net.pipe://localhost/DC/DCService"; public DCServiceConnector() { ConnectorManager.Add(this); } #region IConnector 成员 [Category("信息")] public string Name { get { return "DCService"; } } [Category("信息")] public string Description { get { return "提供WCF服务的DC Connector。"; } } [Category("信息")] public bool IsStarted { get { if (this.serviceHost == null) return false; return (this.serviceHost.State == CommunicationState.Opened ); } } [Category("信息"), Description("Host状态,点击刷新。")] public CommunicationState HostState { get { return serviceHost.State; } } [Category("设置"), Description("启动类型:自动/手动"), DefaultValue(0)] public ConnectorStartupType StartupType { get { return this.startupType; } set { this.startupType = value; } } [Category("设置"), Description("")] public string BaseAddress { get { return this.baseAddressUri; } set { this.baseAddressUri = value; } } [Category("设置"), Description("")] public string PipeAddress { get { return this.pipeaddress; } set { this.pipeaddress = value; } } public void Restart() { this.Stop(); this.Start(); } public void Start() { try { //Console.WriteLine("CreateServiceHost..."); Uri baseAddress = new Uri(this.baseAddressUri); serviceHost = new ServiceHost(typeof(DCService), baseAddress); NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None); binding.MaxReceivedMessageSize = 6553600; serviceHost.AddServiceEndpoint(typeof(IDCService), binding, pipeaddress); ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); smb.HttpGetEnabled = true; serviceHost.Description.Behaviors.Add(smb); serviceHost.Open(); if (this.Started != null) { this.Started(this, EventArgs.Empty); } } catch (CommunicationException exception) { serviceHost.Abort(); if (Trace.IsLevelEnabled(TraceLevel.Error)) { Trace.WriteLine(exception.ToString()); } if (Environment.UserInteractive) { MessageBox.Show(null, "启动DCServiceConnector时出错:" + Environment.NewLine + Environment.NewLine + "Please check connector's settings like TCP port, network address, etc and try again." + Environment.NewLine + Environment.NewLine + "See log file for details.", "Cannot start connector.", MessageBoxButtons.OK, MessageBoxIcon.Hand); } } } public event EventHandler Started; public void Stop() { if (this.IsStarted) { serviceHost.Close(); if (this.Stopped != null) { this.Stopped(this, EventArgs.Empty); } } } public event EventHandler Stopped; #endregion } } Code: using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Runtime.CompilerServices; using System.ServiceModel; using System.ServiceModel.Description; using System.Windows.Forms; using System.Runtime.Serialization; using SmartQuant; using SmartQuant.Data; using SmartQuant.Charting; using SmartQuant.FIX; using SmartQuant.Instruments; using SmartQuant.Series; using SmartQuant.DataCenterLib; namespace Drzwz.DC { [ServiceContract] public interface IDCService { [OperationContract] bool SetSymbol(string symbol, string securityName, string securityType, string securityExchange);//zzz [OperationContract] bool SetDailyList(string symbol, List<Daily> list);//zzz [OperationContract] bool SetPriceFactorList(string symbol, List<PriceFactor> list);//zzz [OperationContract] bool SetBarList(string symbol, List<Bar> list);//zzz [OperationContract] bool SetQuoteList(string symbol, List<Quote> list);//zzz [OperationContract] bool SetTradeList(string symbol, List<Trade> list);//zzz [OperationContract] DataSeriesInfo GetSeriesInfo(string series);//zzz [OperationContract] List<DataSeriesInfo> GetDataSeriesInfo(); [OperationContract] IDataSeriesEnumerator GetEnumerator(string series, DateTime datetime1, DateTime datetime2); [OperationContract] ArrayList GetSecurityDefinitionList(string symbol, string securityType, string securityExchange); [OperationContract] List<string> GetSymbolList(string symbol, string securityType, string securityExchange);//zzz [OperationContract] SortedList<string, string> GetSecurityNameList(string symbol, string securityType, string securityExchange); //zzz [OperationContract] SortedList<string, string> GetSecurityTypeList(string symbol, string securityType, string securityExchange); //zzz [OperationContract] SortedList<DateTime, double> GetPriceFactorList(string symbol);//zzz [OperationContract] List<Daily> GetDailyList(string symbol, DateTime datetime1, DateTime datetime2); [OperationContract] List<Daily> GetDailyAdjList(string symbol, DateTime datetime1, DateTime datetime2);//zzz [OperationContract] List<Bar> GetBarList(string symbol, DateTime datetime1, DateTime datetime2, int barSize); [OperationContract] List<Quote> GetQuoteList(string symbol, DateTime datetime1, DateTime datetime2); [OperationContract] List<Trade> GetTradeList(string symbol, DateTime datetime1, DateTime datetime2); } [ServiceBehavior(MaxItemsInObjectGraph=6553600)] public class DCService : IDCService { public bool SetSymbol(string symbol, string securityName, string securityType, string securityExchange) { if (InstrumentManager.Instruments[symbol] == null) { Instrument instrument; instrument = new Instrument(symbol, securityType); instrument.SecurityDesc = securityName; instrument.SecurityExchange = securityExchange; instrument.Save(); //Console.WriteLine( string.Format("添加Symbol:{0}",symbol) ); } return true; } public bool SetDailyList(string symbol, List<Daily> list) { Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { if (list.Count > 0) { try { foreach (Daily d in list) instrument.Add(d); //Console.WriteLine(string.Format("添加Daily:{0},{1}", symbol,list.Count)); } catch { return false; } } } return true; } public bool SetPriceFactorList(string symbol, List<PriceFactor> list) { Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { if (list.Count > 0) { try { IDataSeries ids = instrument.GetDataSeries("PriceFactor"); if (ids == null) ids = instrument.AddDataSeries("PriceFactor"); foreach (PriceFactor f in list) { if (ids.Count > 0) { if (f.DateTime <= ids.LastDateTime) continue; } ids.Add(f.DateTime, f); } //Console.WriteLine(string.Format("添加PriceFactor:{0},After {1}", symbol, ids.LastDateTime)); } catch { return false; } } } return true; } public bool SetBarList(string symbol, List<Bar> list) { Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { if (list.Count > 0) { try { foreach (Bar d in list) instrument.Add(d); //Console.WriteLine(string.Format("添加Bar:{0},{1}", symbol, list.Count)); } catch { return false; } } } return true; } public bool SetQuoteList(string symbol, List<Quote> list) { Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { if (list.Count > 0) { try { foreach (Quote d in list) instrument.Add(d); //Console.WriteLine(string.Format("添加Quote:{0},{1}", symbol, list.Count)); } catch { return false; } } } return true; } public bool SetTradeList(string symbol, List<Trade> list) { Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { if (list.Count > 0) { try { foreach (Trade d in list) instrument.Add(d); //Console.WriteLine(string.Format("添加Trade:{0},{1}", symbol, list.Count)); } catch { return false; } } } return true; } public DataSeriesInfo GetSeriesInfo(string series) { DataSeriesInfo info = null; IDataSeries s = DataManager.Server.GetDataSeries(series); if (s == null) { //System.Windows.Forms.MessageBox.Show("s==null"); return null; } if (s.Count == 0) { info = new DataSeriesInfo(s.Name, s.Description); } else { info = new DataSeriesInfo(s.Name, s.Description, s.Count, s.FirstDateTime, s.LastDateTime); } return info; } public IDataSeriesEnumerator GetEnumerator(string series, DateTime datetime1, DateTime datetime2) { return new DataSeriesEnumerator(series, datetime1, datetime2); } public List<DataSeriesInfo> GetDataSeriesInfo() { List<DataSeriesInfo> list = new List<DataSeriesInfo>(); foreach (IDataSeries series in DataManager.Server.GetDataSeries()) { DataSeriesInfo info = null; if (series.Count == 0) { info = new DataSeriesInfo(series.Name, series.Description); } else { info = new DataSeriesInfo(series.Name, series.Description, series.Count, series.FirstDateTime, series.LastDateTime); } list.Add(info); } return (list); } public ArrayList GetSecurityDefinitionList(string symbol, string securityType, string securityExchange) { ArrayList list = new ArrayList(); foreach (Instrument instrument in InstrumentManager.Instruments) { if ((((symbol != null) && (instrument.Symbol != symbol)) || ((securityType != null) && (instrument.SecurityType != securityType))) || ((securityExchange != null) && (instrument.SecurityExchange != securityExchange))) { continue; } Hashtable hashtable = new Hashtable(); foreach (FIXField field in instrument.Fields.Values) { hashtable.Add(field.Tag, field.ToInvariantString()); } list.Add(hashtable); } return list; } public List<string> GetSymbolList(string symbol, string securityType, string securityExchange) { List<string> list = new List<string>(); foreach (Instrument instrument in InstrumentManager.Instruments) { if ((((symbol != null) && (instrument.Symbol != symbol)) || ((securityType != null) && (instrument.SecurityType != securityType))) || ((securityExchange != null) && (instrument.SecurityExchange != securityExchange))) { continue; } list.Add(instrument.Symbol); } return list; } public SortedList<string, string> GetSecurityTypeList(string symbol, string securityType, string securityExchange) { SortedList<string, string> list = new SortedList<string, string>(); foreach (Instrument instrument in InstrumentManager.Instruments) { if ((((symbol != null) && (instrument.Symbol != symbol)) || ((securityType != null) && (instrument.SecurityType != securityType))) || ((securityExchange != null) && (instrument.SecurityExchange != securityExchange))) { continue; } if (!list.ContainsKey(instrument.Symbol)) list.Add(instrument.Symbol, instrument.SecurityType); } return list; } public SortedList<string, string> GetSecurityNameList(string symbol, string securityType, string securityExchange) { SortedList<string, string> list = new SortedList<string, string>(); foreach (Instrument instrument in InstrumentManager.Instruments) { if ((((symbol != null) && (instrument.Symbol != symbol)) || ((securityType != null) && (instrument.SecurityType != securityType))) || ((securityExchange != null) && (instrument.SecurityExchange != securityExchange))) { continue; } if (!list.ContainsKey(instrument.Symbol)) list.Add(instrument.Symbol, instrument.SecurityDesc); } return list; } public List<Daily> GetDailyList(string symbol, DateTime datetime1, DateTime datetime2) { //Console.WriteLine("GetDailyList({0},{1},{2})", symbol,datetime1,datetime2); List<Daily> list = new List<Daily>(); //Daily daily = new Daily(new DateTime(2008,2,18),5,8,2,6,100); //list.Add(daily); Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { DailySeries dailySeries = instrument.GetDailySeries(datetime1, datetime2); if (dailySeries != null) { //foreach (Daily daily in dailySeries) //{ // list.Add(daily); //} for (int i = 0; i < dailySeries.Count; i++) { //Console.WriteLine("{0} {1}", dailySeries[i].DateTime, dailySeries[i].Close); list.Add(dailySeries[i]); } //Console.WriteLine("Counts:{0}", dailySeries.Count); } } return (list); } public SortedList<DateTime, double> GetPriceFactorList(string symbol) { SortedList<DateTime, double> list = new SortedList<DateTime, double>(); Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { IDataSeries series = instrument.GetDataSeries("PriceFactor"); if (series != null) { foreach (PriceFactor bar in series) { if (!list.ContainsKey(bar.DateTime)) list.Add(bar.DateTime, bar.Factor); } } } return list; } public List<Daily> GetDailyAdjList(string symbol, DateTime datetime1, DateTime datetime2) { //zzz 获取向前复权Daily List<Daily> list = new List<Daily>(); Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { DailySeries dailySeries = instrument.GetDailySeries(datetime1, datetime2); if (dailySeries != null) { SortedList<DateTime, double> factorList = GetPriceFactorList(symbol); if (factorList.Count > 0) { double fqyz = 1.0;//当前复权因子 double maxfqyz = 1.0;//最大复权因子 int fqyzIndex = 0; maxfqyz = factorList.Values[factorList.Keys.Count - 1]; factorList.Add(DateTime.MaxValue, maxfqyz); foreach (Daily daily in dailySeries) { #region 复权计算 DateTime date = daily.DateTime; double kp = daily.Open; double zg = daily.High; double zd = daily.Low; double sp = daily.Close; if (date < factorList.Keys[0]) { fqyz = 1 / maxfqyz;//前复权因子 kp = daily.Open * fqyz; zg = daily.High * fqyz; zd = daily.Low * fqyz; sp = daily.Close * fqyz; fqyzIndex = 0; } else { for (int j = fqyzIndex; j < factorList.Count - 1; j++) { if (factorList.Keys[j] <= date && date < factorList.Keys[j + 1]) { fqyz = factorList.Values[j] / maxfqyz; //前复权因子 kp = daily.Open * fqyz; zg = daily.High * fqyz; zd = daily.Low * fqyz; sp = daily.Close * fqyz; fqyzIndex = j; break; } } } daily.Open = kp; daily.High = zg; daily.Low = zd; daily.Close = sp; #endregion list.Add(daily); } } else { foreach (Daily daily in dailySeries) { list.Add(daily); } } } } return (list); } public List<Bar> GetBarList(string symbol, DateTime datetime1, DateTime datetime2, int barSize) { List<Bar> list = new List<Bar>(); Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { BarSeries series = instrument.GetBarSeries(datetime1, datetime2, BarType.Time, (long)barSize); if (series != null) { foreach (Bar bar in series) { list.Add(bar); } } } return (list); } public List<Quote> GetQuoteList(string symbol, DateTime datetime1, DateTime datetime2) { List<Quote> list = new List<Quote>(); Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { QuoteArray quoteArray = instrument.GetQuoteArray(datetime1, datetime2); if (quoteArray != null) { foreach (Quote quote in quoteArray) { list.Add(quote); } } } return (list); } public List<Trade> GetTradeList(string symbol, DateTime datetime1, DateTime datetime2) { List<Trade> list = new List<Trade>(); Instrument instrument = InstrumentManager.Instruments[symbol]; if (instrument != null) { TradeArray tradeArray = instrument.GetTradeArray(datetime1, datetime2); if (tradeArray != null) { foreach (Trade trade in tradeArray) { list.Add(trade); } } } return (list); } } internal class DataSeriesEnumerator : IDataSeriesEnumerator { private int currentIndex; private IDataSeries dataSeries; private int firstIndex; private int lastIndex; internal DataSeriesEnumerator(string series, DateTime datetime1, DateTime datetime2) { this.dataSeries = DataManager.Server.GetDataSeries(series); if (this.dataSeries != null) { this.firstIndex = this.dataSeries.IndexOf(datetime1, SearchOption.Next); this.lastIndex = this.dataSeries.IndexOf(datetime2, SearchOption.Exact); if (this.lastIndex == -1) { this.lastIndex = this.dataSeries.IndexOf(datetime2, SearchOption.Prev); } else { this.lastIndex--; } if (this.firstIndex > this.lastIndex) { this.firstIndex = -1; this.lastIndex = -1; } this.currentIndex = this.firstIndex; } else { this.firstIndex = -1; this.lastIndex = -1; this.currentIndex = -1; } } public SmartQuant.Data.IDataObject[] GetNextObjects(int count) { ArrayList list = new ArrayList(); while (count-- > 0) { if (this.currentIndex > this.lastIndex) { break; } list.Add(this.dataSeries[this.currentIndex]); this.currentIndex++; } return (SmartQuant.Data.IDataObject[])list.ToArray(typeof(SmartQuant.Data.IDataObject)); } public int Count { get { if (this.firstIndex != -1) { return ((this.lastIndex - this.firstIndex) + 1); } return 0; } } } }
张兄你有 POBO(澎博)本地数据的分钟数据文件的结构吗?看了一下上面有关POBO(澎博)的好像也只是日线。 另外我也共享一下POBO(澎博)本地日线数据转换成csv或者txt文件的VBSricpt代码,是从网上找到的,我稍做了修改。 main Sub Main() '脚本主程序,请在此下写入主程序代码 dateNum=10 '0代表全部导入,初始化的时候,全部导入,以后建议只更新最近几天的数据, 10代表只导出最近10天 strFile="E:\证券数据\pobo\Data\nyefut\Day\CONC.day" '博易大师日线文件(美国原油连续) fileName="F:\TXTDAY\IDIDCONC.TXT" '导出的文件(飞狐交易师标准文本文件) PoboToFoxtraderTXT strFile,fileName,dateNum End Sub '脚本主程序结束 Sub PoboToFoxtraderTXT(strFile,fileName,dateNum) Const ForReading = 1, ForWriting = 2, ForAppending = 8 Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0 Dim objStream, fso, jiaGe(10) Set objStream = CreateObject("ADODB.Stream") objStream.Type = 1 objStream.Open objStream.LoadFromFile strFile If dateNum=0 Then dateNum= objStream.Size/32 ElseIf dateNum < objStream.Size/32 Then dateNum=dateNum Else dateNum=objStream.Size/32 End If objStream.position = objStream.Size-dateNum*32 For i = 1 To dateNum readFile = AscB(objStream.Read(1))+AscB(objStream.Read(1))*256+AscB(objStream.Read(1))*256*256+AscB(objStream.Read(1))*256*256*256 nian = readFile\1048576 yue = readFile\65536-nian*16+100 ri = (readFile Mod 65536)\256\8+100 riQi = CStr(nian)+"-"+Right(CStr(yue),2)+"-"+Right(CStr(ri),2) For j = 1 To 4 readFile = AscB(objStream.Read(1))+AscB(objStream.Read(1))*256+AscB(objStream.Read(1))*256*256+AscB(objStream.Read(1))*256*256*256 jiaGe(j) =CStr(readFile/1000)+"" Next objStream.position = objStream.position+12 '成交量和持仓量数据结构未知,暂时不导出! shuChu = shuChu+riQi+","+jiaGe(2)+","+jiaGe(3)+","+jiaGe(4)+","+jiaGe(1)+vbCrLf riQi="" Next objStream.Close Set objStream = Nothing Set fso=CreateObject("Scripting.FileSystemObject") If fso.FolderExists("F:\TXTDAY") Then i=0 Else fso.CreateFolder ("F:\TXTDAY") End If Set MyFile=fspenTextFile(fileName,ForWriting,True,TristateFalse) MyFile.WriteLine shuChu MyFile.close Set MyFile = Nothing Set fso = Nothing End Sub
我大概看了一下,觉得分钟的结构应该在日期的数据后面,不过没有很好的分析出来。 就上面的VBS的例子来看,时分的数据应该在(readFile Mod 65536)的后面。不过后面的位数还是很多,POBO也没有秒的数据,还没发现时和分的位置应该在哪里,怎么解析出来。
分钟数据与日数据一般是以相同的结构保存的。 我大概看了一下,POBO的一分钟也是如此。每32B为一记录,共8个字段,每字段4B(8*4=32),其中第1个字段为时间,第2,3,4,5,6,7字段为收、开、高、低、量、持仓量,第8字段未使用。关键是时间是怎么保存的。对于日线,日期分别用第一个字段的几位来保存年、月、日,我猜时、分、秒也差不多,你自己先分析一下。 下面是POBO日线结构的C#代码: public static List<Daily> GetDailyList(PoboSymbol pbSymbol) { List<Daily> dailyList = new List<Daily>(); string filePath = Path.Combine(poboPath, @"data\" + pbSymbol.FolderName + @"\Day\" + pbSymbol.Symbol.Trim() + @".DAY"); if (System.IO.File.Exists(filePath)) { FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); double div = pbSymbol.Divisor * 1.0; int pd = pbSymbol.PriceDigits; long pos = 0; long filelen = fs.Length; while (pos < filelen) { fs.Position = pos; uint rq = br.ReadUInt32(); int sp = br.ReadInt32(); int kp = br.ReadInt32(); int zg = br.ReadInt32(); int zd = br.ReadInt32(); long sl = (long)Math.Round(br.ReadSingle(), 0); long cc = (long)Math.Round(br.ReadSingle(), 0); int y = int.Parse((rq >> 20).ToString()); int m = int.Parse((rq << 12 >> 28).ToString()); int d = int.Parse((rq << 16 >> 27).ToString()); Daily daily = new Daily(new DateTime(y, m, d), Math.Round(kp / div, pd), Math.Round(zg / div, pd), Math.Round(zd / div, pd), Math.Round(sp / div, pd), sl, cc); dailyList.Add(daily); pos += 32; } br.Close(); fs.Close(); } return dailyList; } }