public virtual void Subscribe(string inst, string period) { lock (locker) { MdApi.MD_Subscribe(inst, period); } }
public virtual void Subscribe(string inst, string szExchange) { lock (locker) { MdApi.MD_Subscribe(IntPtrKey, inst, szExchange); inst.Split(new char[2] { ';', ',' }).ToList().ForEach(x => { if (!string.IsNullOrWhiteSpace(x)) { _SubscribedInstruments.Add(x); } }); } }
public void SendMarketDataRequest(FIXMarketDataRequest request) { if (!_bMdConnected) { EmitError(-1, -1, "行情服务器没有连接"); mdlog.Error("行情服务器没有连接"); return; } bool bSubscribe = false; bool bTrade = false; bool bQuote = false; bool bMarketDepth = false; if (request.NoMDEntryTypes > 0) { switch (request.GetMDEntryTypesGroup(0).MDEntryType) { case FIXMDEntryType.Bid: case FIXMDEntryType.Offer: if (request.MarketDepth != 1) { bMarketDepth = true; break; } bQuote = true; break; case FIXMDEntryType.Trade: bTrade = true; break; } } bSubscribe = (request.SubscriptionRequestType == DataManager.MARKET_DATA_SUBSCRIBE); if (bSubscribe) { 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); string altExchange = inst.GetSecurityExchange(this.Name); string apiSymbol = GetApiSymbol(altSymbol); string apiExchange = altExchange; #if CTPZQ altSymbol = GetYahooSymbol(apiSymbol, apiExchange); #endif CThostFtdcInstrumentField _Instrument; if (_dictInstruments.TryGetValue(altSymbol, out _Instrument)) { apiSymbol = _Instrument.InstrumentID; apiExchange = _Instrument.ExchangeID; } #if CTPZQ altSymbol = GetYahooSymbol(apiSymbol, apiExchange); #endif DataRecord record; if (!_dictAltSymbol2Instrument.TryGetValue(altSymbol, out record)) { record = new DataRecord(); record.Instrument = inst; record.Symbol = apiSymbol; record.Exchange = apiExchange; _dictAltSymbol2Instrument[altSymbol] = record; mdlog.Info("订阅合约/订阅询价 {0} {1} {2}", altSymbol, record.Symbol, record.Exchange); if (_bTdConnected) { TraderApi.TD_ReqQryInvestorPosition(m_pTdApi, null); timerPonstion.Enabled = false; timerPonstion.Enabled = true; } } //记录行情,同时对用户合约与交易所合约进行映射 CThostFtdcDepthMarketDataField DepthMarket; if (!_dictDepthMarketData.TryGetValue(altSymbol, out DepthMarket)) { _dictDepthMarketData[altSymbol] = DepthMarket; } // 多次订阅也无所谓 MdApi.MD_Subscribe(m_pMdApi, record.Symbol, record.Exchange); MdApi.MD_SubscribeQuote(m_pMdApi, record.Symbol, record.Exchange); if (bTrade) { record.TradeRequested = true; } if (bQuote) { record.QuoteRequested = true; } if (bMarketDepth) { record.MarketDepthRequested = true; } if (bMarketDepth) { inst.OrderBook.Clear(); } } } else { 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); string altExchange = inst.GetSecurityExchange(this.Name); DataRecord record; if (!_dictAltSymbol2Instrument.TryGetValue(altSymbol, out record)) { break; } if (bTrade) { record.TradeRequested = false; } if (bQuote) { record.QuoteRequested = false; } if (bMarketDepth) { record.MarketDepthRequested = false; } if (!record.TradeRequested && !record.QuoteRequested && !record.MarketDepthRequested) { _dictDepthMarketData.Remove(altSymbol); _dictAltSymbol2Instrument.Remove(altSymbol); mdlog.Info("取消合约/取消询价 {0} {1} {2}", altSymbol, record.Symbol, record.Exchange); MdApi.MD_Unsubscribe(m_pMdApi, record.Symbol, record.Exchange); MdApi.MD_UnsubscribeQuote(m_pMdApi, record.Symbol, record.Exchange); } else { // 只要有一种类型说要订阅,就给订上 MdApi.MD_Subscribe(m_pMdApi, record.Symbol, record.Exchange); MdApi.MD_SubscribeQuote(m_pMdApi, record.Symbol, record.Exchange); } } } }
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()); } } }
private void OnConnect(IntPtr pApi, ref CThostFtdcRspUserLoginField pRspUserLogin, ConnectionStatus result) { //用于行情记算时简化时间解码 // 在夜盘,这个TradingDay就不靠谱了,所以不用了 //try //{ // int _yyyyMMdd = int.Parse(pRspUserLogin.TradingDay); // _yyyy = _yyyyMMdd / 10000; // _MM = (_yyyyMMdd % 10000) / 100; // _dd = _yyyyMMdd % 100; //} //catch (Exception) { _yyyy = DateTime.Now.Year; _MM = DateTime.Now.Month; _dd = DateTime.Now.Day; } if (m_pMdApi == pApi)//行情 { _bMdConnected = false; if (ConnectionStatus.Logined == result) { _bMdConnected = true; mdlog.Info("TradingDay:{0},LoginTime:{1},SHFETime:{2},DCETime:{3},CZCETime:{4},FFEXTime:{5},FrontID:{6},SessionID:{7}", pRspUserLogin.TradingDay, pRspUserLogin.LoginTime, pRspUserLogin.SHFETime, pRspUserLogin.DCETime, pRspUserLogin.CZCETime, pRspUserLogin.FFEXTime, pRspUserLogin.FrontID, pRspUserLogin.SessionID); // 如果断线重连是使用的重新新建对象的方式,则要重新订阅 if (_dictAltSymbol2Instrument.Count > 0) { mdlog.Info("行情列表数{0},全部重新订阅", _dictAltSymbol2Instrument.Count); foreach (DataRecord record in _dictAltSymbol2Instrument.Values) { MdApi.MD_Subscribe(m_pMdApi, record.Symbol, record.Exchange); } } } //这也有个时间,但取出的时间无效 mdlog.Info("{0},{1}", result, pRspUserLogin.LoginTime); } else if (m_pTdApi == pApi)//交易 { _bTdConnected = false; if (ConnectionStatus.Logined == result) { _RspUserLogin = pRspUserLogin; tdlog.Info("TradingDay:{0},LoginTime:{1},SHFETime:{2},DCETime:{3},CZCETime:{4},FFEXTime:{5},FrontID:{6},SessionID:{7}", pRspUserLogin.TradingDay, pRspUserLogin.LoginTime, pRspUserLogin.SHFETime, pRspUserLogin.DCETime, pRspUserLogin.CZCETime, pRspUserLogin.FFEXTime, pRspUserLogin.FrontID, pRspUserLogin.SessionID); UpdateLocalTime(SetLocalTimeMode, pRspUserLogin); #if CTP } else if (ConnectionStatus.Confirmed == result) { #endif _bTdConnected = true; //请求查询资金 TraderApi.TD_ReqQryTradingAccount(m_pTdApi); //请求查询全部持仓 _dictPositions.Clear(); TraderApi.TD_ReqQryInvestorPosition(m_pTdApi, null); //请求查询合约 _dictInstruments.Clear(); TraderApi.TD_ReqQryInstrument(m_pTdApi, null); _dictCommissionRate.Clear(); _dictMarginRate.Clear(); timerAccount.Enabled = true; timerPonstion.Enabled = true; } tdlog.Info("{0},{1}", result, pRspUserLogin.LoginTime); } if ( (_bMdConnected && _bTdConnected) ||//都连上 (!_bWantMdConnect && _bTdConnected) ||//只用分析交易连上 (!_bWantTdConnect && _bMdConnected) //只用分析行情连上 ) { timerConnect.Enabled = true; timerDisconnect.Enabled = false;//都连接上了,用不着定时断 ChangeStatus(ProviderStatus.LoggedIn); isConnected = true; EmitConnectedEvent(); } }
public void SendMarketDataRequest(FIXMarketDataRequest request) { if (!_bMdConnected) { EmitError(-1, -1, "行情服务器没有连接"); mdlog.Error("行情服务器没有连接"); return; } bool bSubscribe = false; bool bTrade = false; bool bQuote = false; bool bMarketDepth = false; if (request.NoMDEntryTypes > 0) { switch (request.GetMDEntryTypesGroup(0).MDEntryType) { case '0': case '1': if (request.MarketDepth != 1) { bMarketDepth = true; break; } bQuote = true; break; case '2': bTrade = true; break; } } bSubscribe = (request.SubscriptionRequestType == DataManager.MARKET_DATA_SUBSCRIBE); if (bSubscribe) { 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); string altExchange = inst.GetSecurityExchange(this.Name); DataRecord record; if (!_dictAltSymbol2Instrument.TryGetValue(altSymbol, out record)) { record = new DataRecord(); record.Instrument = inst; _dictAltSymbol2Instrument[altSymbol] = record; mdlog.Info("订阅合约 {0} {1}", altSymbol, altExchange); MdApi.MD_Subscribe(m_pMdApi, altSymbol); if (_bTdConnected) { TraderApi.TD_ReqQryInvestorPosition(m_pTdApi, null); timerPonstion.Enabled = false; timerPonstion.Enabled = true; } } //记录行情,同时对用户合约与交易所合约进行映射 CThostFtdcDepthMarketDataField DepthMarket; if (!_dictDepthMarketData.TryGetValue(altSymbol, out DepthMarket)) { _dictDepthMarketData.Add(altSymbol, DepthMarket); } if (bTrade) { record.TradeRequested = true; } if (bQuote) { record.QuoteRequested = true; } if (bMarketDepth) { record.MarketDepthRequested = true; } if (bMarketDepth) { inst.OrderBook.Clear(); } } } else { 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); string altExchange = inst.GetSecurityExchange(this.Name); DataRecord record; if (!_dictAltSymbol2Instrument.TryGetValue(altSymbol, out record)) { break; } if (bTrade) { record.TradeRequested = false; } if (bQuote) { record.QuoteRequested = false; } if (bMarketDepth) { record.MarketDepthRequested = false; } if (!record.TradeRequested && !record.QuoteRequested && !record.MarketDepthRequested) { _dictDepthMarketData.Remove(altSymbol); _dictAltSymbol2Instrument.Remove(altSymbol); mdlog.Info("取消订阅 {0} {1}", altSymbol, altExchange); MdApi.MD_Unsubscribe(m_pMdApi, altSymbol); } } } }
//#region 更新时间 //private void UpdateLocalTime(SetTimeMode _SetLocalTimeMode, CThostFtdcRspUserLoginField pRspUserLogin) //{ // string strNewTime; // switch (_SetLocalTimeMode) // { // case SetTimeMode.None: // return; // case SetTimeMode.LoginTime: // strNewTime = pRspUserLogin.LoginTime; // break; // case SetTimeMode.SHFETime: // strNewTime = pRspUserLogin.SHFETime; // break; // case SetTimeMode.DCETime: // strNewTime = pRspUserLogin.DCETime; // break; // case SetTimeMode.CZCETime: // strNewTime = pRspUserLogin.CZCETime; // break; // case SetTimeMode.FFEXTime: // strNewTime = pRspUserLogin.FFEXTime; // break; // default: // return; // } // try // { // int HH = int.Parse(strNewTime.Substring(0, 2)); // int mm = int.Parse(strNewTime.Substring(3, 2)); // int ss = int.Parse(strNewTime.Substring(6, 2)); // DateTime _dateTime = new DateTime(_yyyy, _MM, _dd, HH, mm, ss); // DateTime _newDateTime = _dateTime.AddMilliseconds(AddMilliseconds); // tdlog.Info("SetLocalTime:Return:{0},{1}", // WinAPI.SetLocalTime(_newDateTime), // _newDateTime.ToString("yyyy-MM-dd HH:mm:ss.fff")); // } // catch (Exception ex) // { // tdlog.Warn("{0}不能解析成时间", strNewTime); // } //} //#endregion #region 连接状态回调 private void OnConnect(IntPtr pApi, ref DFITCUserLoginInfoRtnField pRspUserLogin, ConnectionStatus result) { //用于行情记算时简化时间解码 //try //{ // int _yyyyMMdd = int.Parse(pRspUserLogin.TradingDay); // _yyyy = _yyyyMMdd / 10000; // _MM = (_yyyyMMdd % 10000) / 100; // _dd = _yyyyMMdd % 100; //} //catch (Exception ex) //{ // _yyyy = DateTime.Now.Year; // _MM = DateTime.Now.Month; // _dd = DateTime.Now.Day; //} if (m_pMdApi == pApi)//行情 { _bMdConnected = false; if (ConnectionStatus.E_logined == result) { _bMdConnected = true; mdlog.Info("accountID:{0},loginResult:{1},SHFETime:{2},DCETime:{3},CZCETime:{4},FFEXTime:{5},lRequestID:{6},sessionID:{7}", pRspUserLogin.accountID, pRspUserLogin.loginResult, pRspUserLogin.SHFETime, pRspUserLogin.DCEtime, pRspUserLogin.CZCETime, pRspUserLogin.CFFEXTime, pRspUserLogin.lRequestID, pRspUserLogin.sessionID); // 如果断线重连是使用的重新新建对象的方式,则要重新订阅 if (_dictAltSymbol2Instrument.Count > 0) { mdlog.Info("行情列表数{0},全部重新订阅", _dictAltSymbol2Instrument.Count); foreach (string symbol in _dictAltSymbol2Instrument.Keys) { MdApi.MD_Subscribe(m_pMdApi, symbol); } } } //这也有个时间,但取出的时间无效 mdlog.Info("{0}", result); } else if (m_pTdApi == pApi)//交易 { _bTdConnected = false; if (ConnectionStatus.E_logined == result) { _RspUserLogin = pRspUserLogin; tdlog.Info("accountID:{0},loginResult:{1},SHFETime:{2},DCETime:{3},CZCETime:{4},FFEXTime:{5},lRequestID:{6},sessionID:{7}", pRspUserLogin.accountID, pRspUserLogin.loginResult, pRspUserLogin.SHFETime, pRspUserLogin.DCEtime, pRspUserLogin.CZCETime, pRspUserLogin.CFFEXTime, pRspUserLogin.lRequestID, pRspUserLogin.sessionID); //UpdateLocalTime(SetLocalTimeMode, pRspUserLogin); //} //else if (ConnectionStatus.E_confirmed == result) //{ _bTdConnected = true; ////请求查询资金 //TraderApi.TD_ReqQryTradingAccount(m_pTdApi); ////请求查询全部持仓 //TraderApi.TD_ReqQryInvestorPosition(m_pTdApi, null); ////请求查询合约 _dictInstruments.Clear(); //_dictCommissionRate.Clear(); //_dictMarginRate.Clear(); TraderApi.TD_ReqQryExchangeInstrument(m_pTdApi, DFITCExchangeIDType.CFFEX, DFITCInstrumentTypeType.COMM_TYPE); TraderApi.TD_ReqQryExchangeInstrument(m_pTdApi, DFITCExchangeIDType.CZCE, DFITCInstrumentTypeType.COMM_TYPE); TraderApi.TD_ReqQryExchangeInstrument(m_pTdApi, DFITCExchangeIDType.DCE, DFITCInstrumentTypeType.COMM_TYPE); TraderApi.TD_ReqQryExchangeInstrument(m_pTdApi, DFITCExchangeIDType.SHFE, DFITCInstrumentTypeType.COMM_TYPE); TraderApi.TD_ReqQryArbitrageInstrument(m_pTdApi, DFITCExchangeIDType.DCE); TraderApi.TD_ReqQryArbitrageInstrument(m_pTdApi, DFITCExchangeIDType.CZCE); TraderApi.TD_ReqQryExchangeInstrument(m_pTdApi, DFITCExchangeIDType.DCE, DFITCInstrumentTypeType.OPT_TYPE); TraderApi.TD_ReqQryExchangeInstrument(m_pTdApi, DFITCExchangeIDType.CFFEX, DFITCInstrumentTypeType.OPT_TYPE); TraderApi.TD_ReqQryExchangeInstrument(m_pTdApi, DFITCExchangeIDType.CZCE, DFITCInstrumentTypeType.OPT_TYPE); //timerAccount.Enabled = true; //timerPonstion.Enabled = true; } tdlog.Info("{0}", result); } if ( (_bMdConnected && _bTdConnected) ||//都连上 (!_bWantMdConnect && _bTdConnected) ||//只用分析交易连上 (!_bWantTdConnect && _bMdConnected) //只用分析行情连上 ) { timerConnect.Enabled = true; timerDisconnect.Enabled = false;//都连接上了,用不着定时断 ChangeStatus(ProviderStatus.LoggedIn); isConnected = true; EmitConnectedEvent(); } }