private void OnRtnDepthMarketData(IntPtr pApi, ref CThostFtdcDepthMarketDataField pDepthMarketData) { CThostFtdcDepthMarketDataField DepthMarket; if (_dictDepthMarketData.TryGetValue(pDepthMarketData.InstrumentID, out DepthMarket)) { if (TimeMode.LocalTime == _TimeMode) { //为了生成正确的Bar,使用本地时间 _dateTime = Clock.Now; } else { //直接按HH:mm:ss来解析,测试过这种方法目前是效率比较高的方法 int HH = int.Parse(pDepthMarketData.UpdateTime.Substring(0, 2)); int mm = int.Parse(pDepthMarketData.UpdateTime.Substring(3, 2)); int ss = int.Parse(pDepthMarketData.UpdateTime.Substring(6, 2)); _dateTime = new DateTime(_yyyy, _MM, _dd, HH, mm, ss, pDepthMarketData.UpdateMillisec); } Instrument instrument = _dictAltSymbol2Instrument[pDepthMarketData.InstrumentID]; //通过测试,发现IB的Trade与Quote在行情过来时数量是不同的,在这也做到不同 if (DepthMarket.LastPrice == pDepthMarketData.LastPrice && DepthMarket.Volume == pDepthMarketData.Volume) { } else { //行情过来时是今天累计成交量,得转换成每个tick中成交量之差 int volume = pDepthMarketData.Volume - DepthMarket.Volume; if (0 == DepthMarket.Volume) { //没有接收到最开始的一条,所以这计算每个Bar的数据时肯定超大,强行将设置为0 volume = 0; } Trade trade = new Trade(_dateTime, pDepthMarketData.LastPrice == double.MaxValue ? 0 : pDepthMarketData.LastPrice, volume); if (null != marketDataFilter) { /* Trade t = marketDataFilter.FilterTrade(trade, instrument.Symbol); if (null != t) { EmitNewTradeEvent(instrument, t); } */ } else { EmitNewTradeEvent(instrument, trade); } } if ( DepthMarket.BidVolume1 == pDepthMarketData.BidVolume1 && DepthMarket.AskVolume1 == pDepthMarketData.AskVolume1 && DepthMarket.BidPrice1 == pDepthMarketData.BidPrice1 && DepthMarket.AskPrice1 == pDepthMarketData.AskPrice1 ) { } else { Quote quote = new Quote(_dateTime, pDepthMarketData.BidPrice1 == double.MaxValue ? 0 : pDepthMarketData.BidPrice1, pDepthMarketData.BidVolume1, pDepthMarketData.AskPrice1 == double.MaxValue ? 0 : pDepthMarketData.AskPrice1, pDepthMarketData.AskVolume1 ); if (null != marketDataFilter) { /* Quote q = marketDataFilter.FilterQuote(quote, instrument.Symbol); if (null != q) { EmitNewQuoteEvent(instrument, q); } */ } else { EmitNewQuoteEvent(instrument, quote); } } _dictDepthMarketData[pDepthMarketData.InstrumentID] = pDepthMarketData; } }
public void SendMarketDataRequest(FIXMarketDataRequest request) { lock (this) { switch (request.SubscriptionRequestType) { case DataManager.MARKET_DATA_SUBSCRIBE: if (!_bMdConnected) { EmitError(-1,-1,"行情服务器没有连接,无法订阅行情"); return; } for (int i = 0; i < request.NoRelatedSym; ++i) { FIXRelatedSymGroup group = request.GetRelatedSymGroup(i); //通过订阅的方式,由平台传入合约对象,在行情接收处将要使用到合约 CThostFtdcDepthMarketDataField DepthMarket; Instrument inst = InstrumentManager.Instruments[group.Symbol]; string altSymbol = inst.GetSymbol(this.Name); if (!_dictDepthMarketData.TryGetValue(altSymbol, out DepthMarket)) { DepthMarket = new CThostFtdcDepthMarketDataField(); _dictDepthMarketData.Add(altSymbol, DepthMarket); } _dictAltSymbol2Instrument[altSymbol] = inst; MdApi.MD_Subscribe(m_pMdApi, altSymbol); } if (!_bTdConnected) { EmitError(-1, -1, "交易服务器没有连接,无法保证持仓真实"); return; } TraderApi.TD_ReqQryInvestorPosition(m_pTdApi, null); timerPonstion.Enabled = false; timerPonstion.Enabled = true; break; case DataManager.MARKET_DATA_UNSUBSCRIBE: if (!_bMdConnected) { EmitError(-1, -1, "行情服务器没有连接,退订合约无效"); return; } for (int i = 0; i < request.NoRelatedSym; ++i) { FIXRelatedSymGroup group = request.GetRelatedSymGroup(i); Instrument inst = InstrumentManager.Instruments[group.Symbol]; string altSymbol = inst.GetSymbol(this.Name); _dictDepthMarketData.Remove(altSymbol); MdApi.MD_Unsubscribe(m_pMdApi, altSymbol); } break; default: throw new ArgumentException("Unknown subscription type: " + request.SubscriptionRequestType.ToString()); } } }