private void OnRtnDepthMarketData(IntPtr pApi, ref CThostFtdcDepthMarketDataField pDepthMarketData) { DataRecord record; if (!_dictAltSymbol2Instrument.TryGetValue(pDepthMarketData.InstrumentID, out record)) { mdlog.Warn("合约{0}不在订阅列表中却收到了数据", pDepthMarketData.InstrumentID); return; } Instrument instrument = record.Instrument; CThostFtdcDepthMarketDataField DepthMarket; _dictDepthMarketData.TryGetValue(pDepthMarketData.InstrumentID, out DepthMarket); //将更新字典的功能提前,因为如果一开始就OnTrade中下单,涨跌停没有更新 _dictDepthMarketData[pDepthMarketData.InstrumentID] = pDepthMarketData; if (TimeMode.LocalTime == _TimeMode) { //为了生成正确的Bar,使用本地时间 _dateTime = Clock.Now; } else { //直接按HH:mm:ss来解析,测试过这种方法目前是效率比较高的方法 try { // 只有使用交易所行情时才需要处理跨天的问题 ChangeTradingDay(pDepthMarketData.TradingDay); 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); } catch (Exception) { _dateTime = Clock.Now; } } if (record.TradeRequested) { //通过测试,发现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; } else if (volume < 0) { //如果隔夜运行,会出现今早成交量0-昨收盘成交量,出现负数,所以当发现为负时要修改 volume = pDepthMarketData.Volume; } Trade trade = new Trade(_dateTime, pDepthMarketData.LastPrice == double.MaxValue ? 0 : pDepthMarketData.LastPrice, volume); EmitNewTradeEvent(instrument, trade); } } if (record.QuoteRequested) { //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 ); EmitNewQuoteEvent(instrument, quote); } } if (record.MarketDepthRequested) { EmitNewMarketDepth(instrument, _dateTime, 0, MDSide.Ask, pDepthMarketData.AskPrice1, pDepthMarketData.AskVolume1); EmitNewMarketDepth(instrument, _dateTime, 0, MDSide.Bid, pDepthMarketData.BidPrice1, pDepthMarketData.BidVolume1); //EmitNewMarketDepth(instrument, _dateTime, 1, MDSide.Ask, pDepthMarketData.AskPrice2, pDepthMarketData.AskVolume2); //EmitNewMarketDepth(instrument, _dateTime, 1, MDSide.Bid, pDepthMarketData.BidPrice2, pDepthMarketData.BidVolume2); //EmitNewMarketDepth(instrument, _dateTime, 2, MDSide.Ask, pDepthMarketData.AskPrice3, pDepthMarketData.AskVolume3); //EmitNewMarketDepth(instrument, _dateTime, 2, MDSide.Bid, pDepthMarketData.BidPrice3, pDepthMarketData.BidVolume3); //EmitNewMarketDepth(instrument, _dateTime, 3, MDSide.Ask, pDepthMarketData.AskPrice4, pDepthMarketData.AskVolume4); //EmitNewMarketDepth(instrument, _dateTime, 3, MDSide.Bid, pDepthMarketData.BidPrice4, pDepthMarketData.BidVolume4); //EmitNewMarketDepth(instrument, _dateTime, 4, MDSide.Ask, pDepthMarketData.AskPrice5, pDepthMarketData.AskVolume5); //EmitNewMarketDepth(instrument, _dateTime, 4, MDSide.Bid, pDepthMarketData.BidPrice5, pDepthMarketData.BidVolume5); } // 价差生成功能 do { if (null == CTPAPI.GetInstance().SpreadMarketData) break; ISpreadMarketData SpreadMarketData = CTPAPI.GetInstance().SpreadMarketData; var ticks = SpreadMarketData.CalculateSpread(pDepthMarketData); if (null == ticks) break; foreach (var tick in ticks) { Instrument inst = InstrumentManager.Instruments[tick.Symbol]; if (null == inst) continue; if (!double.IsNaN(tick.Price)) { Trade trade = new Trade(_dateTime, tick.Price, tick.Size); trade.ProviderId = tick.ProviderId; EmitNewTradeEvent(inst, trade); } if (!double.IsNaN(tick.Ask) && !double.IsNaN(tick.Bid)) { Quote quote = new Quote(_dateTime, tick.Bid, tick.BidSize, tick.Ask, tick.AskSize); quote.ProviderId = tick.ProviderId; EmitNewQuoteEvent(inst, quote); } } } while (false); // 直接回报CTP的行情信息 if (EmitOnRtnDepthMarketData) { CTPAPI.GetInstance().FireOnRtnDepthMarketData(pDepthMarketData); } }
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; } }
private void Dispatcher_HistoricalData(object sender, HistoricalDataEventArgs args) { HistoricalData data = args.Data; ImportTaskViewItem importTaskViewItem; if (!this.taskItems.TryGetValue(data.RequestId, out importTaskViewItem)) return; foreach (SmartQuant.DataObject dataObject in data.Objects) { if (dataObject is Quote) { Quote quote1 = (Quote) dataObject; Quote quote2; lock (this.lastQuotes) { if (!this.lastQuotes.TryGetValue(data.RequestId, out quote2)) { quote2 = new Quote(new Bid(), new Ask()); this.lastQuotes.Add(data.RequestId, quote2); } } if (quote1.Bid.Price != quote2.Bid.Price || quote1.Bid.Size != quote2.Bid.Size) this.framework.DataManager.Save(importTaskViewItem.Task.Instrument, (SmartQuant.DataObject) new Bid(quote1.Bid), SaveMode.Add); if (quote1.Ask.Price != quote2.Ask.Price || quote1.Ask.Size != quote2.Ask.Size) this.framework.DataManager.Save(importTaskViewItem.Task.Instrument, (SmartQuant.DataObject) new Ask(quote1.Ask), SaveMode.Add); quote2.Bid.Price = quote1.Bid.Price; quote2.Bid.Size = quote1.Bid.Size; quote2.Ask.Price = quote1.Ask.Price; quote2.Ask.Size = quote1.Ask.Size; } else this.framework.DataManager.Save(importTaskViewItem.Task.Instrument, dataObject, SaveMode.Add); } importTaskViewItem.Task.TotalNum = data.TotalNum; importTaskViewItem.Task.Count += data.Objects.Length; }
private void OnRtnDepthMarketData(IntPtr pApi, ref CThostFtdcDepthMarketDataField pDepthMarketData) { DataRecord record; if (!_dictAltSymbol2Instrument.TryGetValue(pDepthMarketData.InstrumentID, out record)) { mdlog.Warn("合约{0}不在订阅列表中却收到了数据", pDepthMarketData.InstrumentID); return; } Instrument instrument = record.Instrument; CThostFtdcDepthMarketDataField DepthMarket; _dictDepthMarketData.TryGetValue(pDepthMarketData.InstrumentID, out DepthMarket); //将更新字典的功能提前,因为如果一开始就OnTrade中下单,涨跌停没有更新 _dictDepthMarketData[pDepthMarketData.InstrumentID] = pDepthMarketData; 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); } if (record.TradeRequested) { //通过测试,发现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; } else if (volume < 0) { //如果隔夜运行,会出现今早成交量0-昨收盘成交量,出现负数,所以当发现为负时要修改 volume = pDepthMarketData.Volume; } 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 (record.QuoteRequested) { //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); } } } if (record.MarketDepthRequested) { EmitNewMarketDepth(instrument, _dateTime, 0, MDSide.Ask, pDepthMarketData.AskPrice1, pDepthMarketData.AskVolume1); EmitNewMarketDepth(instrument, _dateTime, 0, MDSide.Bid, pDepthMarketData.BidPrice1, pDepthMarketData.BidVolume1); //EmitNewMarketDepth(instrument, _dateTime, 1, MDSide.Ask, pDepthMarketData.AskPrice2, pDepthMarketData.AskVolume2); //EmitNewMarketDepth(instrument, _dateTime, 1, MDSide.Bid, pDepthMarketData.BidPrice2, pDepthMarketData.BidVolume2); //EmitNewMarketDepth(instrument, _dateTime, 2, MDSide.Ask, pDepthMarketData.AskPrice3, pDepthMarketData.AskVolume3); //EmitNewMarketDepth(instrument, _dateTime, 2, MDSide.Bid, pDepthMarketData.BidPrice3, pDepthMarketData.BidVolume3); //EmitNewMarketDepth(instrument, _dateTime, 3, MDSide.Ask, pDepthMarketData.AskPrice4, pDepthMarketData.AskVolume4); //EmitNewMarketDepth(instrument, _dateTime, 3, MDSide.Bid, pDepthMarketData.BidPrice4, pDepthMarketData.BidVolume4); //EmitNewMarketDepth(instrument, _dateTime, 4, MDSide.Ask, pDepthMarketData.AskPrice5, pDepthMarketData.AskVolume5); //EmitNewMarketDepth(instrument, _dateTime, 4, MDSide.Bid, pDepthMarketData.BidPrice5, pDepthMarketData.BidVolume5); } }
private void OnRtnDepthMarketData(IntPtr pApi, ref CZQThostFtdcDepthMarketDataField pDepthMarketData) { CZQThostFtdcDepthMarketDataField DepthMarket; if (_dictDepthMarketData.TryGetValue(pDepthMarketData.InstrumentID, out DepthMarket)) { //将更新字典的功能提前,因为如果一开始就OnTrade中下单,涨跌停没有更新 _dictDepthMarketData[pDepthMarketData.InstrumentID] = pDepthMarketData; 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; } else if (volume<0) { //如果隔夜运行,会出现今早成交量0-昨收盘成交量,出现负数,所以当发现为负时要修改 volume = pDepthMarketData.Volume; } Trade trade = new Trade(_dateTime, pDepthMarketData.LastPrice == double.MaxValue ? 0 : pDepthMarketData.LastPrice, volume); if (null != marketDataFilter) { //comment by fouvy, for openquant 2.9 //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) { //comment by fouvy change for openquant 2.9 //Quote q = marketDataFilter.FilterQuote(quote, instrument.Symbol); //if (null != q) //{ // EmitNewQuoteEvent(instrument, q); //} } else { EmitNewQuoteEvent(instrument, quote); } } } }
public override void onMessage(QuickFix42.MarketDataIncrementalRefresh refresh, QuickFix.SessionID sessionID) { if (refresh.isSetNoMDEntries()) { string reqID = refresh.getMDReqID().getValue(); Instrument instrument = (provider as GSFIX).GetInstrument(reqID); if (instrument == null) return; QuickFix42.MarketDataIncrementalRefresh.NoMDEntries group = new QuickFix42.MarketDataIncrementalRefresh.NoMDEntries(); int position; double price; int size; SmartQuant.Data.MarketDepth depth; SmartQuant.Data.Quote quote; for (uint i = 1; i <= refresh.getNoMDEntries().getValue(); i++) { refresh.getGroup(i, group); switch (group.getMDUpdateAction().getValue()) { // new case QuickFix.MDUpdateAction.NEW: { switch (group.getMDEntryType().getValue()) { case QuickFix.MDEntryType.BID: //Console.WriteLine("NEW BID"); price = group.getMDEntryPx().getValue(); size = (int)group.getMDEntrySize().getValue(); // market depth depth = new SmartQuant.Data.MarketDepth(Clock.Now, "", -1, MDOperation.Insert, MDSide.Bid, price, size); provider.EmitMarketDepth(depth, instrument); // quote, best bid if (price > instrument.Quote.Bid) { quote = new Quote(instrument.Quote); quote.DateTime = Clock.Now; quote.Bid = price; quote.BidSize = size; provider.EmitQuote(quote, instrument); } break; case QuickFix.MDEntryType.OFFER: //Console.WriteLine("NEW ASK"); price = group.getMDEntryPx().getValue(); size = (int)group.getMDEntrySize().getValue(); // market depth depth = new SmartQuant.Data.MarketDepth(Clock.Now, "", -1, MDOperation.Insert, MDSide.Ask, price, size); provider.EmitMarketDepth(depth, instrument); // quote, best ask if (price < instrument.Quote.Ask) { quote = new Quote(instrument.Quote); quote.DateTime = Clock.Now; quote.Ask = price; quote.AskSize = size; provider.EmitQuote(quote, instrument); } break; case QuickFix.MDEntryType.TRADE: provider.EmitTrade(new Trade(Clock.Now, group.getMDEntryPx().getValue(), (int)group.getMDEntrySize().getValue()), instrument); break; } } break; // change case QuickFix.MDUpdateAction.CHANGE: { switch (group.getMDEntryType().getValue()) { case QuickFix.MDEntryType.BID: //Console.WriteLine("CHANGE BID!"); position = group.getMDEntryPositionNo().getValue() - 1; size = (int)group.getMDEntrySize().getValue(); // market depth depth = new SmartQuant.Data.MarketDepth(Clock.Now, "", position, MDOperation.Update, MDSide.Bid, 0, size); provider.EmitMarketDepth(depth, instrument); // quote, best bid if (position == 0) { quote = new Quote(instrument.Quote); quote.DateTime = Clock.Now; quote.BidSize = (int)group.getMDEntrySize().getValue(); provider.EmitQuote(quote, instrument); } break; case QuickFix.MDEntryType.OFFER: //Console.WriteLine("CHANGE ASK!"); position = group.getMDEntryPositionNo().getValue() - 1; size = (int)group.getMDEntrySize().getValue(); // market depth depth = new SmartQuant.Data.MarketDepth(Clock.Now, "", position, MDOperation.Update, MDSide.Ask, 0, size); provider.EmitMarketDepth(depth, instrument); // quote, best bid if (position == 0) { quote = new Quote(instrument.Quote); quote.DateTime = Clock.Now; quote.AskSize = (int)group.getMDEntrySize().getValue(); provider.EmitQuote(quote, instrument); } break; } } break; // delete case QuickFix.MDUpdateAction.DELETE: { switch (group.getMDEntryType().getValue()) { case QuickFix.MDEntryType.BID: //Console.WriteLine("DELETE BID"); position = group.getMDEntryPositionNo().getValue() - 1; // market depth depth = new SmartQuant.Data.MarketDepth(Clock.Now, "", position, MDOperation.Delete, MDSide.Bid, 0, 0); provider.EmitMarketDepth(depth, instrument); // quote if (position == 0) { Quote newQuote = instrument.OrderBook.GetQuote(0); newQuote.DateTime = Clock.Now; provider.EmitQuote(newQuote, instrument); } break; case QuickFix.MDEntryType.OFFER: //Console.WriteLine("DELETE ASK"); position = group.getMDEntryPositionNo().getValue() - 1; // market depth depth = new SmartQuant.Data.MarketDepth(Clock.Now, "", position, MDOperation.Delete, MDSide.Ask, 0, 0); provider.EmitMarketDepth(depth, instrument); // quote if (position == 0) { Quote newQuote = instrument.OrderBook.GetQuote(0); newQuote.DateTime = Clock.Now; provider.EmitQuote(newQuote, instrument); } break; } } break; } } group.Dispose(); } }
public override void onMessage(QuickFix42.MarketDataSnapshotFullRefresh snapshot, QuickFix.SessionID sessionID) { if (snapshot.isSetNoMDEntries()) { string reqID = snapshot.getMDReqID().getValue(); Instrument instrument = (provider as GSFIX).GetInstrument(reqID); instrument.OrderBook.Clear(); QuickFix42.MarketDataSnapshotFullRefresh.NoMDEntries group = new QuickFix42.MarketDataSnapshotFullRefresh.NoMDEntries(); Quote quote = new Quote(); quote.DateTime = Clock.Now; for (uint i = 1; i <= snapshot.getNoMDEntries().getValue(); i++) { snapshot.getGroup(i, group); SmartQuant.Data.MarketDepth depth; int position = 0; if (group.isSetMDEntryPositionNo()) position = group.getMDEntryPositionNo().getValue() - 1; double price = group.getMDEntryPx().getValue(); int size = (int)group.getMDEntrySize().getValue(); // Console.WriteLine("Snapshot Level : " + position + " " + price + " " + size); switch (group.getMDEntryType().getValue()) { case QuickFix.MDEntryType.TRADE: provider.EmitTrade(new Trade(Clock.Now, price, size), instrument); break; case QuickFix.MDEntryType.BID: // market depth depth = new SmartQuant.Data.MarketDepth(Clock.Now, "", position, MDOperation.Insert, MDSide.Bid, price, size); provider.EmitMarketDepth(depth, instrument); // quote if (position == 0) { quote.Bid = price; quote.BidSize = size; } break; case QuickFix.MDEntryType.OFFER: // market depth depth = new SmartQuant.Data.MarketDepth(Clock.Now, "", position, MDOperation.Insert, MDSide.Ask, price, size); provider.EmitMarketDepth(depth, instrument); // quote if (position == 0) { quote.Ask = price; quote.AskSize = size; } break; } } group.Dispose(); provider.EmitQuote(quote, instrument); } }