public List <DZHExDividend> RequestExDividends(DZHSymbol symbol) { SetMarket(symbol.Market); long pos = GetIndex(symbol); if (pos == -1) { return(null); } else { List <DZHExDividend> results = new List <DZHExDividend>(); fileStream.Position = pos + 10; byte x = reader.ReadByte(); if (x > 0) { for (int i = 0; i < x; i++) { fileStream.Position = pos + 248 + i * 20; DZHExDividend aEx = new DZHExDividend(); aEx.Time = date19700101.AddSeconds(reader.ReadUInt32()); aEx.RateForPresented = reader.ReadSingle() * 10; aEx.RateForPlacement = reader.ReadSingle() * 10; aEx.PriceForPlacement = reader.ReadSingle(); aEx.Dividend = reader.ReadSingle() * 10; results.Add(aEx); } } results.Sort();//大智慧除权除息数据是倒序放置的,故而排序了下 return(results); } }
protected void SetSymbol(DZHSymbol symbol) { if ((currentSymbol == null) || (!currentSymbol.Equals(symbol))) { currentSymbol = symbol; OnSymbolChanged(); } }
//以下两个重写的方法是为了symbol能在字典上做主键,实现主键的查找 public override bool Equals(object obj) { if (obj is DZHSymbol) { DZHSymbol other = (DZHSymbol)obj; return((this.Market == other.Market && this.Code == other.Code) ? true : false); } else { return(false); } }
public DZHQuote RequestQuote(DZHSymbol symbol) { SetMarket(symbol.Market); long pos = GetIndex(symbol); if (pos == -1) { return(null); } else { return(ReadARecord(pos)); } }
public List <DZHTick> RequestLastTicks(DZHSymbol symbol) { if (symbol.Equals(currentSymbol)) { long pos = indexBuffer[symbol.Market][symbol.Code]; fileStream.Position = pos + 10; recordCount = reader.ReadInt32(); if (recordCount > recordCountReaded)//有新记录 { int recordsPerBlock = dataBlockSize / dataRecordSize; if (recordCount / recordsPerBlock > blockNumberReaded)//有新块号 { fileStream.Position += blockNumberReaded * 2; for (int j = blockNumberReaded; j < 25; j++) { blocks[j] = reader.ReadInt16(); } } int iRecord = 0; //记录 int iBlock = 0; //第iBlock块 iRecord = recordCountReaded; iBlock = iRecord / recordsPerBlock; List <DZHTick> results = new List <DZHTick>(); while (iBlock < 25 && blocks[iBlock] != -1) { int r = iRecord % recordsPerBlock;//块内记录号 while (iRecord < recordCount && r < recordsPerBlock) { results.Add(ReadARecord(dataStartOffset + blocks[iBlock] * dataBlockSize + r * dataRecordSize)); r = r + 1; iRecord = iRecord + 1; } iBlock = iBlock + 1; } recordCountReaded = recordCount; blockNumberReaded = iBlock; return(results); } else { return(null); } } else { return(RequestTicks(symbol)); } }
protected long GetIndex(DZHSymbol symbol) { Dictionary <string, long> indexs = indexBuffer[symbol.Market]; long pos = 0; bool find = false; if (indexs.ContainsKey(symbol.Code)) { pos = indexs[symbol.Code]; find = true; } else { int indexCount = indexs.Count; pos = indexStartOffset + indexCount * indexRecordSize; while (pos + indexRecordSize < indexStartOffset + securityCount * indexRecordSize) { if (pos <= fileStream.Length) { fileStream.Position = pos; //大智慧用10个字节保存代码,一般用8个字节 string code0 = System.Text.Encoding.Default.GetString(reader.ReadBytes(10)); code0 = code0.Replace("\0", ""); indexs.Add(code0, pos); if (symbol.Code == code0) { find = true; break; } else { pos += indexRecordSize; } } } } if (find) { return(pos); } else { return(-1); } }
public List <DZHTick> RequestTicks(DZHSymbol symbol, DateTime?startTime, DateTime?endTime) { SetMarket(symbol.Market); SetSymbol(symbol); currentSymbol = symbol; int iRecord = 0; //记录 int iBlock = 0; //第iBlock块 int recordsPerBlock = dataBlockSize / dataRecordSize; int iEndRecord = recordCount - 1; if (startTime.HasValue) { iRecord = GetStartIRecord(startTime.Value); iBlock = iRecord / recordsPerBlock; } if (endTime.HasValue) { iEndRecord = GetEndIRecord(endTime.Value); } List <DZHTick> results = new List <DZHTick>(); while (iBlock < 25 && blocks[iBlock] != -1) { int r = iRecord % recordsPerBlock;//块内记录号 while (iRecord <= iEndRecord && r < recordsPerBlock) { results.Add(ReadARecord(dataStartOffset + blocks[iBlock] * dataBlockSize + r * dataRecordSize)); r = r + 1; iRecord = iRecord + 1; } iBlock = iBlock + 1; } recordCountReaded = iEndRecord + 1; blockNumberReaded = iBlock; //Debug.WriteLine(results.Count.ToString()); return(results); }
public List <ISeriesObject> GetHistoricalData(Instrument instrument, HistoricalDataType dataType, int barSize, DateTime startTime, DateTime endTime) { List <ISeriesObject> results = new List <ISeriesObject>(); DZHSymbol symbol = new DZHSymbol(instrument.SecurityExchange, instrument.SecurityID); List <DZHBar> bars; List <DZHTick> ticks; switch (dataType) { case HistoricalDataType.Bar: if (barSize == 300) { if (min5Reader == null) { min5Reader = new DZHMin5BarReader(dzhDataPath); } bars = min5Reader.RequestBars(symbol, startTime, endTime); } else if (barSize == 60) { if (min1Reader == null) { min1Reader = new DZHMin1BarReader(dzhDataPath); } bars = min1Reader.RequestBars(symbol, startTime, endTime); } else { throw new ArgumentException("Unknowm bar size:" + barSize.ToString()); } if ((bars != null) && (bars.Count > 0)) { /*前复权调整*/ if (forwardAdjust) { if (financeReader == null) { financeReader = new DZHFinanceReader(dzhDataPath); } List <DZHExDividend> exDivs = financeReader.RequestExDividends(symbol); financeReader.ForwardAdjustedPrice(bars, exDivs); } foreach (DZHBar aBar in bars) { results.Add(new Bar(aBar.Time, aBar.Open, aBar.High, aBar.Low, aBar.Close, (long)aBar.Volume, barSize)); } } break; case HistoricalDataType.Daily: if (dayReader == null) { dayReader = new DZHDayBarReader(dzhDataPath); } bars = dayReader.RequestBars(symbol, startTime, endTime); if ((bars != null) && (bars.Count > 0)) { /*前复权调整*/ if (forwardAdjust) { if (financeReader == null) { financeReader = new DZHFinanceReader(dzhDataPath); } List <DZHExDividend> exDivs = financeReader.RequestExDividends(symbol); financeReader.ForwardAdjustedPrice(bars, exDivs); } foreach (DZHBar aBar in bars) { results.Add(new Daily(aBar.Time, aBar.Open, aBar.High, aBar.Low, aBar.Close, (long)aBar.Volume)); } } break; case HistoricalDataType.Trade: if (tickReader == null) { tickReader = new DZHTickReader(dzhDataPath); } ticks = tickReader.RequestTicks(symbol, startTime, endTime); if ((ticks != null) && (ticks.Count > 0)) { int prevVol = 0; foreach (DZHTick aTick in ticks) { results.Add(new Trade(aTick.Time, aTick.Price, (int)aTick.Volume - prevVol)); prevVol = (int)aTick.Volume; } } break; default: throw new ArgumentException("Unknown data type: " + dataType.ToString()); } return(results); }
/*定时器执行更新报价*/ private void tickTimer_Elapsed(object sender, ElapsedEventArgs e) { /*如果只在开市时读数据,在非开市时间直接退出*/ if (onlyReadInMarket && (DateTime.Now < DateTime.Today.Add(beginTime) || DateTime.Now > DateTime.Today.Add(endTime))) { return; } /*当运行到第二天时,清空报价缓存*/ if (lastDateOfQuote < DateTime.Today) { lastDateOfQuote = DateTime.Today; lastQuotes.Clear(); } if (quoteReader == null) { quoteReader = new DZHQuoteReader(dzhDataPath); } try { foreach (string symbol in subscribedSymbols.ToArray()) { if (!subscribedSymbols.Contains(symbol)) { continue; } Instrument curInstrument = InstrumentManager.Instruments[symbol]; if (curInstrument == null) { this.EmitError(-1, -1, "Symbol " + symbol + " was not found in list of requested symbols."); } else { DZHSymbol dzhSymbol = new DZHSymbol(curInstrument.SecurityExchange, curInstrument.SecurityID); DZHQuote newQuote = quoteReader.RequestQuote(dzhSymbol); bool flag1 = false; bool flag2 = false; bool first = false;//是否是请求的第一笔数据 if (this.lastQuotes.ContainsKey(symbol)) { DZHQuote oldQuote = this.lastQuotes[symbol]; /*这里注释掉和下面一样,大智慧发送来的数据存在同一时刻多笔交易的现象 * 所以不能用时间来排除 */ //if (newQuote.Time != oldQuote.Time) //{ if ((newQuote.Bid1 != oldQuote.Bid1) || (newQuote.Bid1Vol != oldQuote.Bid1Vol) || (newQuote.Ask1 != oldQuote.Ask1) || (newQuote.Ask1Vol != oldQuote.Ask1Vol)) { flag1 = true; } if ((newQuote.TotalVolume != oldQuote.TotalVolume) || (newQuote.Price != oldQuote.Price)) { flag2 = true; } // } this.lastQuotes[symbol] = newQuote; } else { first = true; if ((newQuote.Ask1 > 0.0) || (newQuote.Bid1 > 0.0)) { flag1 = true; } if ((newQuote.Price > 0.0) || (newQuote.Volume > 0.0)) { flag2 = true; } this.lastQuotes.Add(symbol, newQuote); } /*这里注释掉是,不做时间检查,因为不使用市场数据提供者存储数据,市场数据提供者只用于实时交易 *而要获取过去的数据存储起来,使用历史数据提供者 */ //if ((flag1) && ((curInstrument.GetQuoteArray(newQuote.Time, newQuote.Time)).Count == 0)) if (flag1) { this.EmitNewQuote(new Quote(newQuote.Time, newQuote.Bid1, (int)newQuote.Bid1Vol, newQuote.Ask1, (int)newQuote.Ask1Vol), curInstrument); } /*大智慧有可能在同一时刻有多笔交易,QD不允许这样,所以有可能丢失某些笔交易 * 如果不作同一时刻的检查,则有可能在数据中保存重复的交易 * 这里注释掉是,不做时间检查,因为不使用市场数据提供者存储数据,市场数据提供者只用于实时交易 *而要获取过去的数据存储起来,使用历史数据提供者 */ //if ((flag2) && ((curInstrument.GetTradeArray(newQuote.Time, newQuote.Time)).Count == 0)) if (flag2) { this.EmitNewTrade(new Trade(newQuote.Time, newQuote.Price, (int)newQuote.Volume), curInstrument); /*以下代码是为了产生日线*/ if (first && buildDailyBar) { lock (this) { DateTime barDateTime = newQuote.Time.Date; if (!dailyBars.ContainsKey(curInstrument)) { dailyBars.Add(curInstrument, new Dictionary <DateTime, Daily>()); } Dictionary <DateTime, Daily> dailyBox = dailyBars[curInstrument]; if (!dailyBox.ContainsKey(barDateTime)) { Daily daily = new Daily(barDateTime, newQuote.Open, newQuote.High, newQuote.Low, newQuote.Price, (long)newQuote.TotalVolume); dailyBox.Add(barDateTime, daily); ((DZHBarFactory)this.factory).EmitNewBarOpen(daily, curInstrument); } DateTime realyEndTime = Clock.Now.Add(this.endTime - newQuote.Time.TimeOfDay); Clock.AddReminder(new ReminderEventHandler(OnReminder), realyEndTime, null); } } } } } } catch (Exception exception) { this.EmitError(-1, -1, exception.ToString()); } }
public List <DZHTick> RequestTicks(DZHSymbol symbol) { return(this.RequestTicks(symbol, null, null)); }
public List <DZHBar> RequestBars(DZHSymbol symbol) { return(this.RequestBars(symbol, null, null)); }
protected long GetIndex(DZHSymbol symbol) { Dictionary <string, long> indexs = indexBuffer[symbol.Market]; long pos = 0; bool find = false; if (indexs.ContainsKey(symbol.Code)) { pos = indexs[symbol.Code]; find = true; } else { if (indexs.Count == 0) { pos = indexStartOffset; } else { KeyValuePair <string, long> lastVP = indexs.Last <KeyValuePair <string, long> >(); pos = lastVP.Value; } while (indexs.Count <= securityCount) { if (pos + 11 < fileStream.Length) { fileStream.Position = pos; //这文件中好像只用8个字节表示代码 string code0 = System.Text.Encoding.Default.GetString(reader.ReadBytes(8)); code0 = code0.Replace("\0", ""); if (!indexs.ContainsKey(code0)) { indexs.Add(code0, pos); } if (symbol.Code == code0) { find = true; break; } else { fileStream.Position = pos + 11; Byte flag = reader.ReadByte(); byte x; switch (flag) { case 0x80: pos = pos + 216; break; case 0xc0: fileStream.Position = pos + 10; x = reader.ReadByte(); pos = pos + 216 + 32 + x * 20; break; case 0x40: fileStream.Position = pos + 10; x = reader.ReadByte(); pos = pos + 12 + 32 + x * 20; break; case 0x00: pos = pos + 12; break; default: //Debug.WriteLine(pos.ToString()); throw new Exception("invalid flag in reading finance data:" + flag.ToString("D")); } } } else { break; } } } if (find) { return(pos); } else { return(-1); } }
protected bool GetBlocks(DZHSymbol symbol) { Dictionary <string, long> indexs = indexBuffer[symbol.Market]; long pos = 0; bool find = false; if (indexs.ContainsKey(symbol.Code)) { pos = indexs[symbol.Code]; find = true; } else { int indexCount = indexs.Count; pos = indexStartOffset + indexCount * indexRecordSize; while (pos + indexRecordSize < indexStartOffset + securityCount * indexRecordSize) { if (pos < fileStream.Length) { fileStream.Position = pos; //大智慧用10个字节保存代码,一般用8个字节 string code0 = System.Text.Encoding.Default.GetString(reader.ReadBytes(10)); code0 = code0.Replace("\0", ""); if (!indexs.ContainsKey(code0)) { indexs.Add(code0, pos); } if (symbol.Code == code0) { find = true; break; } else { pos += indexRecordSize; } } } } if (!find) { for (int j = 0; j < 25; j++) { blocks[j] = -1; //块号记录清空 } return(false); } else { fileStream.Position = pos + 10; recordCount = reader.ReadInt32(); for (int j = 0; j < 25; j++) { blocks[j] = reader.ReadInt16(); } return(true); } }