private void OnRtnDepthMarketData_callback(object sender, ref DepthMarketDataNClass marketData) { if (null != OnRtnDepthMarketData) { OnRtnDepthMarketData(this, new OnRtnDepthMarketDataNEventArgs(ref marketData)); } }
public void Write(ref DepthMarketDataNClass pDepthMarketData) { // 如果盘中不小心把服务端关了也不再开启 if (null == c) { return; } string dateTime = pDepthMarketData.ExchangeDateTime().ToString("yyyy.MM.ddTHH:mm:ss.fff"); string symbol = pDepthMarketData.InstrumentID; double price = pDepthMarketData.LastPrice; long volume = (long)(pDepthMarketData.Volume); long openint = (long)(pDepthMarketData.OpenInterest); double bid = 0; double ask = 0; int bsize = 0; int asize = 0; string trade_str = string.Format("`trade insert({0};`$\"{1}\";{2}f;{3}j;{4}j)", dateTime, symbol, price, volume, openint); string quote_str = null; if (SaveQuote) { if (pDepthMarketData.Bids.Length > 0) { bid = pDepthMarketData.Bids[0].Price; bsize = pDepthMarketData.Bids[0].Size; } if (pDepthMarketData.Asks.Length > 0) { ask = pDepthMarketData.Asks[0].Price; asize = pDepthMarketData.Asks[0].Size; } quote_str = string.Format("`quote insert({0};`$\"{1}\";{2}f;{3}f;{4};{5})", dateTime, symbol, bid, ask, bsize, asize); } // 有一个问题 lock (this) { try { // trade c.ks(trade_str); // quote if (SaveQuote) { c.ks(quote_str); } } catch (Exception e) { // 保存失败,通常是因为网络断开了 Log.Error(e.Message); c.Close(); c = null; } } }
private void _onRtnDepthMarketData(object sender, ref DepthMarketDataNClass marketData) { Tick tick = new Tick() { InstrumentID = marketData.InstrumentID , AskPrice = marketData.Asks.Length > 0 ? marketData.Asks[0].Price : -1 , AskVolume = marketData.Asks.Length > 0 ? marketData.Asks[0].Size : -1 , BidPrice = marketData.Bids.Length > 0 ? marketData.Bids[0].Price : -1 , BidVolume = marketData.Bids.Length > 0 ? marketData.Bids[0].Size : -1 , LastPrice = marketData.LastPrice , OpenInterest = marketData.OpenInterest , UpdateTime = new DateTime( marketData.ActionDay / 10000 , marketData.ActionDay / 100 % 100 , marketData.ActionDay % 100 , marketData.UpdateTime / 10000 , marketData.UpdateTime / 100 % 100 , marketData.UpdateTime % 100 , marketData.UpdateMillisec) , Volume = Convert.ToInt32(marketData.Volume) }; }
private void OnRtnDepthMarketData_callback(object sender, ref DepthMarketDataNClass pDepthMarketData) { if (!_enableEmitData) { return; } try { // 传过来的Symbol,有可能是不带点,有可能是带点的 // 要同时存成完整版,因为下单时 MarketDataRecord record; if (!marketDataRecords.TryGetValue(pDepthMarketData.Symbol, out record)) { return; } // 取出上次的行情记录 DepthMarketDataNClass depthMarket = record.DepthMarket; //将更新字典的功能提前,因为如果一开始就OnTrade中下单,涨跌停没有更新 record.DepthMarket = pDepthMarketData; _dateTime = DateTime.Now; try { _exchangeDateTime = pDepthMarketData.ExchangeDateTime(); } catch { _exchangeDateTime = _dateTime; (sender as XApi).GetLog().Error("{0} ExchangeDateTime有误,现使用LocalDateTime代替,请找API开发人员处理API中的时间兼容问题。", pDepthMarketData.ToFormattedStringExchangeDateTime()); } if (_emitBidAskFirst) { if (_emitBidAsk) { FireBid(record.Instrument.Id, _dateTime, _exchangeDateTime, pDepthMarketData, depthMarket); FireAsk(record.Instrument.Id, _dateTime, _exchangeDateTime, pDepthMarketData, depthMarket); } FireTrade(record.Instrument.Id, _dateTime, _exchangeDateTime, pDepthMarketData, depthMarket); } else { FireTrade(record.Instrument.Id, _dateTime, _exchangeDateTime, pDepthMarketData, depthMarket); if (_emitBidAsk) { FireBid(record.Instrument.Id, _dateTime, _exchangeDateTime, pDepthMarketData, depthMarket); FireAsk(record.Instrument.Id, _dateTime, _exchangeDateTime, pDepthMarketData, depthMarket); } } } catch (Exception ex) { (sender as XApi).GetLog().Error(ex); } }
private void _OnRtnDepthMarketData(IntPtr ptr1, int size1, double double1) { // 求快,这个地方不判断 //if (OnRtnDepthMarketData_ == null) // return; DepthMarketDataNClass cls = PInvokeUtility.GetDepthMarketDataNClass(ptr1); OnRtnDepthMarketData(this, ref cls); }
private void OnRtnDepthMarketData(object sender, ref DepthMarketDataNClass marketData) { Input_pd0.Post(marketData); if (null == KdbWriter) { return; } Input_kdb.Post(marketData); }
public bool Write(ref DepthMarketDataNClass pDepthMarketData) { QuantBox.Data.Serializer.V2.TickWriter.WriterDataItem item; if (Items.TryGetValue(pDepthMarketData.Symbol, out item)) { item.Tick = CreateTick(ref pDepthMarketData, item.Serializer.Codec); base.Write(item, item.Tick); return true; } return false; }
private void _onRtnDepthMarketData(object sender, ref DepthMarketDataNClass marketData) { Instrument inst = InstrumentManager.GetInstrument(marketData.InstrumentID); if (inst == null) { return; } //计算量的差值 double vol = 0; double difVol = 0; if (volumeMap.TryGetValue(marketData.InstrumentID, out vol)) { if (marketData.Volume < vol) { return; } difVol = marketData.Volume - vol; vol = marketData.Volume; } else { volumeMap.Add(marketData.InstrumentID, marketData.Volume); return; } // Tick tick = new Tick(inst , marketData.LastPrice , marketData.Bids.Length > 0 ? marketData.Bids[0].Price : 0 , marketData.Bids.Length > 0 ? marketData.Bids[0].Size : 0 , marketData.Asks.Length > 0 ? marketData.Asks[0].Price : 0 , marketData.Asks.Length > 0 ? marketData.Asks[0].Size : 0 , difVol , marketData.OpenInterest , new DateTime( marketData.ActionDay / 10000 , marketData.ActionDay / 100 % 100 , marketData.ActionDay % 100 , marketData.UpdateTime / 10000 , marketData.UpdateTime / 100 % 100 , marketData.UpdateTime % 100 , marketData.UpdateMillisec) , marketData.UpperLimitPrice , marketData.LowerLimitPrice); // mOnTick?.Invoke(tick); }
void OnRtnDepthMarketData(object sender, ref DepthMarketDataNClass marketData) { Debugger.Log(0, null, "CTP:C#"); Console.WriteLine(marketData.InstrumentID); //Console.WriteLine(marketData.Exchange); Console.WriteLine(marketData.LastPrice); //Console.WriteLine(marketData.OpenInterest); if (marketData.Bids.Count() > 0) { Console.WriteLine(marketData.Bids[0].Price); } if (marketData.Asks.Count() > 0) { Console.WriteLine(marketData.Asks[0].Price); } }
public bool Write(ref DepthMarketDataNClass pDepthMarketData) { //if(IsHdf5) //{ // // 输出 // return true; //} //else { QuantBox.Data.Serializer.V2.TickWriter.WriterDataItem item; if (Items.TryGetValue(pDepthMarketData.Symbol, out item)) { item.Tick = CreateTick(ref pDepthMarketData, item.Serializer.Codec); base.Write(item, item.Tick); return(true); } return(false); } }
private void FireLevel2Snapshot(SortedSet <int> Ids, DateTime _dateTime, DateTime _exchangeDateTime, DepthMarketDataNClass pDepthMarketData, DepthMarketDataNClass DepthMarket) { //行情过来时是今天累计成交量,得转换成每个tick中成交量之差 double volume = pDepthMarketData.Volume - DepthMarket.Volume; // 以前第一条会导致集合竞价后的第一条没有成交量,这种方法就明确了上一笔是空数据 if (0 == DepthMarket.TradingDay && 0 == DepthMarket.ActionDay) { //没有接收到最开始的一条,所以这计算每个Bar的数据时肯定超大,强行设置为0 volume = 0; } else if (volume < 0) { //如果隔夜运行,会出现今早成交量0-昨收盘成交量,出现负数,所以当发现为负时要修改 volume = pDepthMarketData.Volume; } foreach (var _id in Ids) { List <Bid> bids = new List <Bid>(); if (pDepthMarketData.Bids != null) { foreach (var d in pDepthMarketData.Bids) { Bid bid = new Bid( _dateTime, _exchangeDateTime, id, _id, d.Price, d.Size); bids.Add(bid); } } List <Ask> asks = new List <Ask>(); if (pDepthMarketData.Asks != null) { foreach (var d in pDepthMarketData.Asks) { Ask ask = new Ask( _dateTime, _exchangeDateTime, id, _id, d.Price, d.Size); asks.Add(ask); } } var l2s = new Level2Snapshot(_dateTime, _exchangeDateTime, id, _id, bids.ToArray(), asks.ToArray()) { }; // 启用底层数据上传 EmitData(l2s); } }
public void OnInputMarketData_kdb(DepthMarketDataNClass pDepthMarketData) { KdbWriter.Write(ref pDepthMarketData); }
public void OnInputMarketData_pd0(DepthMarketDataNClass pDepthMarketData) { TickWriter.Write(ref pDepthMarketData); }
private void OnRtnDepthMarketData(object sender, ref DepthMarketDataNClass marketData) { Input.Post(marketData); }
private void FireBid(int InstrumentId, DateTime _dateTime, DateTime _exchangeDateTime, DepthMarketDataNClass pDepthMarketData, DepthMarketDataNClass DepthMarket) { do { if (pDepthMarketData.Bids == null || pDepthMarketData.Bids.Length == 0) { break; } if (DepthMarket.Bids != null && DepthMarket.Bids.Length > 0) { if (DepthMarket.Bids[0].Size == pDepthMarketData.Bids[0].Size && DepthMarket.Bids[0].Price == pDepthMarketData.Bids[0].Price) { // 由于与上次一样,不能动 break; } } Bid bid = new Bid( _dateTime, _exchangeDateTime, this.id, InstrumentId, pDepthMarketData.Bids[0].Price, pDepthMarketData.Bids[0].Size); EmitData(bid); } while (false); }
private void FireAsk(int InstrumentId, DateTime _dateTime, DateTime _exchangeDateTime, DepthMarketDataNClass pDepthMarketData, DepthMarketDataNClass DepthMarket) { do { if (pDepthMarketData.Asks == null || pDepthMarketData.Asks.Length == 0) { break; } if (DepthMarket.Asks != null && DepthMarket.Asks.Length > 0) { if (DepthMarket.Asks[0].Size == pDepthMarketData.Asks[0].Size && DepthMarket.Asks[0].Price == pDepthMarketData.Asks[0].Price) { // 由于与上次一样,不能动 break; } } Ask ask = new Ask( _dateTime, _exchangeDateTime, this.id, InstrumentId, pDepthMarketData.Asks[0].Price, pDepthMarketData.Asks[0].Size); EmitData(ask); } while (false); }
private void FireTrade(SortedSet <int> Ids, DateTime _dateTime, DateTime _exchangeDateTime, DepthMarketDataNClass pDepthMarketData, DepthMarketDataNClass DepthMarket) { //行情过来时是今天累计成交量,得转换成每个tick中成交量之差 double volume = pDepthMarketData.Volume - DepthMarket.Volume; // 以前第一条会导致集合竞价后的第一条没有成交量,这种方法就明确了上一笔是空数据 if (0 == DepthMarket.TradingDay && 0 == DepthMarket.ActionDay) { //没有接收到最开始的一条,所以这计算每个Bar的数据时肯定超大,强行设置为0 volume = 0; } else if (volume < 0) { //如果隔夜运行,会出现今早成交量0-昨收盘成交量,出现负数,所以当发现为负时要修改 volume = pDepthMarketData.Volume; } foreach (var _id in Ids) { // 使用新的类,保存更多信息 var trade = new TradeEx( _dateTime, _exchangeDateTime, id, _id, pDepthMarketData.LastPrice, (int)volume) { DepthMarketData = pDepthMarketData }; // 启用底层数据上传 EmitData(trade); } }
private DepthMarketDataNClass PbTick2DepthMarketDataNClass(PbTickCodec codec, PbTickView tickView) { DepthMarketDataNClass marketData = new DepthMarketDataNClass(); codec.GetUpdateTime(tickView, out marketData.UpdateTime, out marketData.UpdateMillisec); marketData.TradingDay = tickView.TradingDay; marketData.ActionDay = tickView.ActionDay; marketData.LastPrice = tickView.LastPrice; marketData.Volume = tickView.Volume; if (SubscribeExternData) { marketData.Turnover = tickView.Turnover; marketData.OpenInterest = tickView.OpenInterest; marketData.AveragePrice = tickView.AveragePrice; if (tickView.Bar != null) { marketData.OpenPrice = tickView.Bar.Open; marketData.HighestPrice = tickView.Bar.High; marketData.LowestPrice = tickView.Bar.Low; marketData.ClosePrice = tickView.Bar.Close; } if (tickView.Static != null) { marketData.LowerLimitPrice = tickView.Static.LowerLimitPrice; marketData.UpperLimitPrice = tickView.Static.UpperLimitPrice; marketData.SettlementPrice = tickView.Static.SettlementPrice; marketData.Symbol = tickView.Static.Symbol; if (!string.IsNullOrWhiteSpace(tickView.Static.Exchange)) { marketData.Exchange = Enum <ExchangeType> .Parse(tickView.Static.Exchange); } marketData.PreClosePrice = tickView.Static.PreClosePrice; marketData.PreSettlementPrice = tickView.Static.PreSettlementPrice; marketData.PreOpenInterest = tickView.Static.PreOpenInterest; } } int count = tickView.DepthList == null ? 0 : tickView.DepthList.Count; if (count > 0) { int AskPos = DepthListHelper.FindAsk1Position(tickView.DepthList, tickView.AskPrice1); int BidPos = AskPos - 1; int BidCount = BidPos + 1; int AskCount = count - AskPos; marketData.Bids = new DepthField[0]; marketData.Asks = new DepthField[0]; if (SubscribeBid) { if (BidCount > 0) { marketData.Bids = new DepthField[BidCount]; int j = 0; for (int i = BidPos; i >= 0; --i) { marketData.Bids[j] = new DepthField() { Price = tickView.DepthList[i].Price, Size = tickView.DepthList[i].Size, Count = tickView.DepthList[i].Count, }; ++j; } } } if (SubscribeAsk) { if (AskCount > 0) { marketData.Asks = new DepthField[AskCount]; int j = 0; for (int i = AskPos; i < count; ++i) { marketData.Asks[j] = new DepthField() { Price = tickView.DepthList[i].Price, Size = tickView.DepthList[i].Size, Count = tickView.DepthList[i].Count, }; ++j; } } } } return(marketData); }
public OnRtnDepthMarketDataNEventArgs(ref DepthMarketDataNClass marketData) { this.marketData = marketData; }
public MarketDataRecord(Instrument instrument) { this.Instrument = instrument; this.DepthMarket = new DepthMarketDataNClass(); }
public MarketDataRecord() { DepthMarket = new DepthMarketDataNClass(); Ids = new SortedSet <int>(); }
private void FireAsk(SortedSet <int> Ids, DateTime _dateTime, DateTime _exchangeDateTime, DepthMarketDataNClass pDepthMarketData, DepthMarketDataNClass DepthMarket) { do { if (pDepthMarketData.Asks == null || pDepthMarketData.Asks.Length == 0) { break; } if (DepthMarket.Asks != null && DepthMarket.Asks.Length > 0) { if (DepthMarket.Asks[0].Size == pDepthMarketData.Asks[0].Size && DepthMarket.Asks[0].Price == pDepthMarketData.Asks[0].Price) { // 由于与上次一样,不能动 break; } } foreach (var _id in Ids) { Ask ask = new Ask( _dateTime, _exchangeDateTime, id, _id, pDepthMarketData.Asks[0].Price, pDepthMarketData.Asks[0].Size); EmitData(ask); } } while (false); }
// 目前先不处理港股的tickSize变化的那种行情 PbTick CreateTick(ref DepthMarketDataNClass pDepthMarketData, PbTickCodec codec) { var tick = new PbTick(); tick.DepthList = new List <DepthItem>(); tick.Config = codec.Config; tick.TradingDay = pDepthMarketData.TradingDay; tick.ActionDay = pDepthMarketData.ActionDay; tick.Time_HHmm = pDepthMarketData.UpdateTime / 100; tick.Time_____ssf__ = pDepthMarketData.UpdateTime % 100 * 10 + pDepthMarketData.UpdateMillisec / 100; tick.Time________ff = pDepthMarketData.UpdateMillisec % 100; // 数据接收器时计算本地与交易所的行情时间差 // 1.这个地方是否保存? // 2.到底是XAPI中提供还是由接收器提供? //tick.LocalTime_Msec = (int)(DateTime.Now - codec.GetActionDayDateTime(tick)).TotalMilliseconds; codec.SetSymbol(tick, pDepthMarketData.Symbol); if (pDepthMarketData.Exchange != ExchangeType.Undefined) { codec.SetExchange(tick, Enum <ExchangeType> .ToString(pDepthMarketData.Exchange)); } codec.SetLowerLimitPrice(tick, pDepthMarketData.LowerLimitPrice); codec.SetUpperLimitPrice(tick, pDepthMarketData.UpperLimitPrice); codec.SetOpen(tick, pDepthMarketData.OpenPrice); codec.SetHigh(tick, pDepthMarketData.HighestPrice); codec.SetLow(tick, pDepthMarketData.LowestPrice); codec.SetClose(tick, pDepthMarketData.ClosePrice); codec.SetVolume(tick, (long)pDepthMarketData.Volume); codec.SetOpenInterest(tick, (long)pDepthMarketData.OpenInterest); codec.SetTurnover(tick, pDepthMarketData.Turnover);//一定要设置合约乘数才能最优保存 codec.SetAveragePrice(tick, pDepthMarketData.AveragePrice); codec.SetLastPrice(tick, pDepthMarketData.LastPrice); codec.SetSettlementPrice(tick, pDepthMarketData.SettlementPrice); codec.SetPreClosePrice(tick, pDepthMarketData.PreClosePrice); codec.SetPreSettlementPrice(tick, pDepthMarketData.PreSettlementPrice); codec.SetPreOpenInterest(tick, (long)pDepthMarketData.PreOpenInterest); for (int i = pDepthMarketData.Bids.Length - 1; i >= 0; --i) { var bid = pDepthMarketData.Bids[i]; if (bid.Size == 0) { break; } // 记录卖一价 if (i == 0) { codec.SetAskPrice1(tick, bid.Price); tick.AskPrice1 += 1; } tick.DepthList.Add(new DepthItem(codec.PriceToTick(bid.Price), bid.Size, bid.Count)); } for (int i = 0; i < pDepthMarketData.Asks.Length; ++i) { var ask = pDepthMarketData.Asks[i]; if (ask.Size == 0) { break; } // 记录卖一价 if (i == 0) { codec.SetAskPrice1(tick, ask.Price); } tick.DepthList.Add(new DepthItem(codec.PriceToTick(ask.Price), ask.Size, ask.Count)); } return(tick); }
private void FireAsk(SortedSet <int> Ids, DateTime _dateTime, DateTime _exchangeDateTime, DepthMarketDataNClass pDepthMarketData, DepthMarketDataNClass DepthMarket) { double price = 0.0; int size = 0; // 当出现涨跌停时,有可能是一开始就是涨跌停,也有可能慢慢变成涨跌停 if (pDepthMarketData.Asks == null || pDepthMarketData.Asks.Length == 0) { } else { if (DepthMarket.Asks != null && DepthMarket.Asks.Length > 0) { if (DepthMarket.Asks[0].Size == pDepthMarketData.Asks[0].Size && DepthMarket.Asks[0].Price == pDepthMarketData.Asks[0].Price) { // 由于与上次一样,不能动 return; } } price = pDepthMarketData.Asks[0].Price; size = pDepthMarketData.Asks[0].Size; } foreach (var _id in Ids) { Ask ask = new Ask( _dateTime, _exchangeDateTime, id, _id, price, size); EmitData(ask); } }