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); } }
public void OutputSeries(out IDataSeries trades, out IDataSeries bids, out IDataSeries asks) { trades = new TickSeries(); bids = new TickSeries(); asks = new TickSeries(); PbTickCodec codec = new PbTickCodec(); int TradingDay = -1; int _lastTradeSize = 0; foreach (var s in Series) { if (TradingDay != s.TradingDay) { _lastTradeSize = 0; TradingDay = s.TradingDay; } var dateTime = codec.GetDateTime(s.ActionDay == 0 ? s.TradingDay : s.ActionDay).Add(codec.GetUpdateTime(s)); var tick = PbTick2DepthMarketDataNClass(codec, s); if (SubscribeExternData) { var trade = new TradeEx(dateTime, 0, _InstrumentId, tick.LastPrice, (int)tick.Volume); trade.Size -= _lastTradeSize; trade.DepthMarketData = tick; trades.Add(trade); } else { var trade = new Trade(dateTime, 0, _InstrumentId, tick.LastPrice, (int)tick.Volume); trade.Size -= _lastTradeSize; trades.Add(trade); } if (tick.Bids != null && tick.Bids.Length > 0) { var bid = new Bid(dateTime, 0, _InstrumentId, tick.Bids[0].Price, tick.Bids[0].Size); bids.Add(bid); } if (tick.Asks != null && tick.Asks.Length > 0) { var ask = new Ask(dateTime, 0, _InstrumentId, tick.Asks[0].Price, tick.Asks[0].Size); asks.Add(ask); } _lastTradeSize = (int)tick.Volume; } }
public bool Enqueue() { if (EventQueue.IsFull() || EndOfSeries) { return(false); } if (_current == null || !_current.HasNext && _files.Count > 0) { OpenReader(); _lastTradeSize = 0; } // 这种每次只取一个数据方式比较慢,下一阶段可以改成一次读完一个文件 if (_current != null && _current.HasNext) { var tick = _current.Next(); var dateTime = _current.Codec.GetDateTime(tick.ActionDay == 0?tick.TradingDay:tick.ActionDay).Add(_current.Codec.GetUpdateTime(tick)); var marketData = PbTick2DepthMarketDataField(_current.Codec, tick); // 在这个地方式可以试着生成自己的TradeEx,这样在策略中,模拟与实盘的效果就完全一样了 if (_info.SubscribeTrade) { var trade = new TradeEx(dateTime, 0, _info.InstrumentId, marketData.LastPrice, (int)marketData.Volume); trade.Size -= _lastTradeSize; trade.DepthMarketData = marketData; EventQueue.Enqueue(trade); _lastTradeSize = (int)marketData.Volume; } if (_info.SubscribeBidAsk) { if (marketData.BidVolume1 > 0) { var bid = new Bid(dateTime, 0, _info.InstrumentId, marketData.BidPrice1, marketData.BidVolume1); EventQueue.Write(bid); } if (marketData.AskVolume1 > 0) { var ask = new Ask(dateTime, 0, _info.InstrumentId, marketData.AskPrice1, marketData.AskVolume1); EventQueue.Write(ask); } } _completed += _current.Setp; if (_completed >= _progressCount) { _progressCount += _progressDelta; _progressPercent++; EventQueue.Enqueue(new OnSimulatorProgress(_progressCount, _progressPercent)); } return(true); } else { EndOfSeries = true; return(false); } }