private void OnConnect_callback(IntPtr pApi, ref CZQThostFtdcRspUserLoginField pRspUserLogin, ConnectionStatus result) { _bMdConnected = (ConnectionStatus.E_logined == result); if (null != OnConnect) { OnConnect(this, new OnConnectArgs(pApi, ref pRspUserLogin, result)); } }
private void UpdateLocalTime(SetTimeMode _SetLocalTimeMode, CZQThostFtdcRspUserLoginField 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) { tdlog.Warn("{0}不能解析成时间", strNewTime); } }
protected override void ProcessBusinessResponse(CTPStockResponseType responseType, IntPtr pData, CTPResponseInfo rspInfo, int requestID) { Trace.WriteLine(string.Format("{0} [{1}]:{2},{3},{4}", this.wallTimeStopwatch.ElapsedMilliseconds, this.UserKey, "ProcessBusinessResponse", responseType, requestID)); switch (responseType) { #region 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 case CTPStockResponseType.FrontConnectedResponse: { this.isConnect = true; this.UserLogin(); //调用事件 OnEventHandler(CTPStockResponseType.FrontConnectedResponse, new CTPEventArgs()); break; } #endregion #region 通信中断 case CTPStockResponseType.FrontDisconnectedResponse: /// 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 ///@param nReason 错误原因 /// 0x1001 网络读失败 /// 0x1002 网络写失败 /// 0x2001 接收心跳超时 /// 0x2002 发送心跳失败 /// 0x2003 收到错误报文 { this.isConnect = false; //调用事件 OnEventHandler(CTPStockResponseType.FrontDisconnectedResponse, new CTPEventArgs()); } break; #endregion #region 心跳超时警告 case CTPStockResponseType.HeartBeatWarningResponse: { /// <summary> ///心跳超时警告。当长时间未收到报文时,该方法被调用。 ///@param nTimeLapse 距离上次接收报文的时间 /// </summary> /// <param name="nTimeLapse"></param> Trace.WriteLine("CTPTrader:OnHeartBeatWarning!! " + pData.ToString()); break; } #endregion #region 客户端认证响应 case CTPStockResponseType.AuthenticateResponse: { CTPEventArgs <CZQThostFtdcRspAuthenticateField> args = CreateEventArgs <CZQThostFtdcRspAuthenticateField>(requestID, rspInfo); this.OnEventHandler(CTPStockResponseType.AuthenticateResponse, args); break; } #endregion #region 用户登录 case CTPStockResponseType.UserLoginResponse: { CTPEventArgs <CZQThostFtdcRspUserLoginField> args = CreateEventArgs <CZQThostFtdcRspUserLoginField>(requestID, rspInfo); CZQThostFtdcRspUserLoginField userLogin = args.Value; if (rspInfo.ErrorID == 0) { this.BrokerID = userLogin.BrokerID; this.FrontID = userLogin.FrontID; this.SessionID = userLogin.SessionID; this.isLogin = true; this.loginTime = userLogin.LoginTime; //最大报单引用 int orderRef = 0; if (int.TryParse(userLogin.MaxOrderRef, out orderRef) == false) { orderRef = 0; } this.currentOrderRef = orderRef; //this.currentOrderRef++; DateTime.TryParseExact(userLogin.TradingDay, "yyyyMMdd", null, System.Globalization.DateTimeStyles.AllowWhiteSpaces, out this.tradingDate); TimeSpan.TryParse(userLogin.DCETime, out this.loginTimeDCE); TimeSpan.TryParse(userLogin.CZCETime, out this.loginTimeCZCE); TimeSpan.TryParse(userLogin.SHFETime, out this.loginTimeSHFE); //TimeSpan.TryParse(userLogin.DCETime, out this.currentTimeDCE); this.wallTimeStopwatch.Start(); this.timer.Change(0, 1000); } this.OnEventHandler(CTPStockResponseType.UserLoginResponse, args); } break; #endregion #region 登出请求响应 case CTPStockResponseType.UserLogoutResponse: { this.isLogin = false; //调用事件 OnEventHandler(CTPStockResponseType.UserLogoutResponse, new CTPEventArgs()); break; } #endregion #region 用户口令更新请求响应 case CTPStockResponseType.UserPasswordUpdateResponse: /// <summary> /// 用户口令更新请求响应 /// </summary> { CTPEventArgs <CZQThostFtdcUserPasswordUpdateField> args = CreateEventArgs <CZQThostFtdcUserPasswordUpdateField>(requestID, rspInfo); this.OnEventHandler(CTPStockResponseType.UserPasswordUpdateResponse, args); break; } #endregion #region 报单录入请求响应 case CTPStockResponseType.OrderInsertResponse: { CTPEventArgs <CZQThostFtdcInputOrderField> args = CreateEventArgs <CZQThostFtdcInputOrderField>(requestID, rspInfo); //调用事件 OnEventHandler(CTPStockResponseType.OrderInsertResponse, args); break; } #endregion #region 改单响应 case CTPStockResponseType.OrderActionResponse: { CTPEventArgs <CZQThostFtdcInputOrderActionField> args = CreateEventArgs <CZQThostFtdcInputOrderActionField>(requestID, rspInfo); //调用事件 OnEventHandler(CTPStockResponseType.OrderActionResponse, args); break; } #endregion #region 查询最大报单数量响应 case CTPStockResponseType.QueryMaxOrderVolumeResponse: { CTPEventArgs <CZQThostFtdcQueryMaxOrderVolumeField> args = CreateEventArgs <CZQThostFtdcQueryMaxOrderVolumeField>(requestID, rspInfo); this.OnEventHandler(CTPStockResponseType.QueryMaxOrderVolumeResponse, args); break; } #endregion #region 查询报单响应 case CTPStockResponseType.QueryOrderResponse: { CTPEventArgs <List <CZQThostFtdcOrderField> > args = CreateListEventArgs <CZQThostFtdcOrderField>(requestID, rspInfo); lock (this.OrderList) { this.OrderList.Clear(); this.OrderList.AddRange(args.Value); } //调用事件 OnEventHandler(CTPStockResponseType.QueryOrderResponse, args); break; } #endregion #region 查询成交单响应 case CTPStockResponseType.QueryTradeResponse: { CTPEventArgs <List <CZQThostFtdcTradeField> > args = CreateListEventArgs <CZQThostFtdcTradeField>(requestID, rspInfo); this.TradeList = args.Value; //调用事件 OnEventHandler(CTPStockResponseType.QueryTradeResponse, args); break; } #endregion #region 查询投资者持仓响应 case CTPStockResponseType.QueryInvestorPositionResponse: { CTPEventArgs <List <CZQThostFtdcInvestorPositionField> > args = CreateListEventArgs <CZQThostFtdcInvestorPositionField>(requestID, rspInfo); this.PositionList = args.Value; //调用事件 OnEventHandler(CTPStockResponseType.QueryInvestorPositionResponse, args); break; } #endregion #region 查询资金账户响应 case CTPStockResponseType.QueryTradingAccountResponse: { /// 查询资金账户响应 CTPEventArgs <CZQThostFtdcTradingAccountField> args = CreateEventArgs <CZQThostFtdcTradingAccountField>(requestID, rspInfo); this.tradingAccount = args.Value; this.OnEventHandler(CTPStockResponseType.QueryTradingAccountResponse, args); break; } #endregion #region 查询投资者响应 case CTPStockResponseType.QueryInvestorResponse: { CTPEventArgs <CZQThostFtdcInvestorField> args = CreateEventArgs <CZQThostFtdcInvestorField>(requestID, rspInfo); this.investor = args.Value; this.OnEventHandler(CTPStockResponseType.QueryInvestorResponse, args); break; } #endregion #region 请求查询交易编码响应 case CTPStockResponseType.QueryTradingCodeResponse: { CTPEventArgs <CZQThostFtdcTradingCodeField> args = CreateEventArgs <CZQThostFtdcTradingCodeField>(requestID, rspInfo); this.OnEventHandler(CTPStockResponseType.QueryTradingCodeResponse, args); break; } #endregion #region 查询手续费响应 case CTPStockResponseType.QueryInstrumentCommissionRateResponse: { CTPEventArgs <CZQThostFtdcInstrumentCommissionRateField> args = CreateEventArgs <CZQThostFtdcInstrumentCommissionRateField>(requestID, rspInfo); this.SetInstrumentRate(args.Value); //调用事件 OnEventHandler(CTPStockResponseType.QueryInstrumentCommissionRateResponse, args); break; } #endregion #region 查询交易所响应 case CTPStockResponseType.QueryExchangeResponse: { CTPEventArgs <CZQThostFtdcExchangeField> args = CreateEventArgs <CZQThostFtdcExchangeField>(requestID, rspInfo); //保存市场信息 //CTPExchange ctpExchange = new CTPExchange(); //ctpExchange.SetNativeValue(args.Value); //this.Exchanges.Add(args.Value.ExchangeID, ctpExchange); //调用事件 OnEventHandler(CTPStockResponseType.QueryExchangeResponse, args); break; } #endregion #region 查询合约响应 case CTPStockResponseType.QueryInstrumentResponse: { CTPEventArgs <List <CZQThostFtdcInstrumentField> > values = CreateListEventArgs <CZQThostFtdcInstrumentField>(requestID, rspInfo); foreach (var instrument in values.Value) { if (instrument.ProductClass == CTPStockProductClassType.EFP || instrument.ProductClass == CTPStockProductClassType.Futures || instrument.ProductClass == CTPStockProductClassType.Options) { continue; } CTPStockInstrument ctpInstrument = new CTPStockInstrument(); ctpInstrument.SetNativeValue(instrument); //加入到市场列表 //if (this.Exchanges.ContainsKey(ctpInstrument.ExchangeID)) //{ // this.Exchanges[instrument.ExchangeID].Instruments.Add(ctpInstrument); //} //if (this.SymbolProducts.ContainsKey(ctpInstrument.ProductID.ToUpper()) == false) //{ // this.SymbolProducts.Add(ctpInstrument.ProductID.ToUpper(), new CTPSymbolProduct(instrument)); //} //加入到合约表 if (this.InstrumentDictionary.ContainsKey(ctpInstrument.ID) == false) { this.InstrumentDictionary.Add(ctpInstrument.ID, ctpInstrument); } } //创建新的事件参数 List <CTPStockInstrument> list = new List <CTPStockInstrument>(this.InstrumentDictionary.Values); CTPEventArgs <List <CTPStockInstrument> > args = new CTPEventArgs <List <CTPStockInstrument> >(list); //调用事件 //OnEventHandler(CTPStockResponseType.QueryInstrumentResponse, args); OnEventHandler(CTPStockResponseType.QueryInstrumentResponse, values); break; } #endregion #region 查询行情响应 case CTPStockResponseType.QueryDepthMarketDataResponse: { CTPEventArgs <CZQThostFtdcDepthMarketDataField> args = CreateEventArgs <CZQThostFtdcDepthMarketDataField>(requestID, rspInfo); //调用事件 OnEventHandler(CTPStockResponseType.QueryDepthMarketDataResponse, args); break; } #endregion #region 查询投资者持仓明细响应 case CTPStockResponseType.QueryInvestorPositionDetailResponse: { CTPEventArgs <List <CZQThostFtdcInvestorPositionDetailField> > args = CreateListEventArgs <CZQThostFtdcInvestorPositionDetailField>(requestID, rspInfo); this.PositionDetailList = args.Value; //调用事件 OnEventHandler(CTPStockResponseType.QueryInvestorPositionDetailResponse, args); break; } #endregion #region 错误回报 case CTPStockResponseType.ErrorResponse: { this.OnEventHandler(CTPStockResponseType.ErrorResponse, new CTPEventArgs(rspInfo)); break; } #endregion #region 报单回报 case CTPStockResponseType.ReturnOrderResponse: { CTPEventArgs <CZQThostFtdcOrderField> args = CreateEventArgs <CZQThostFtdcOrderField>(pData, rspInfo); lock (this.orderList) { CTPStockOrderConvert.AppendOrReplaceOrder(this.orderList, args.Value); } if (this.filterRestart == true && this.isInitialized == false) { } else { //调用事件 OnEventHandler(CTPStockResponseType.ReturnOrderResponse, args); } break; } #endregion #region 成交回报 case CTPStockResponseType.ReturnTradeResponse: { CTPEventArgs <CZQThostFtdcTradeField> args = CreateEventArgs <CZQThostFtdcTradeField>(pData, rspInfo); //插入到列表中 CTPStockOrderConvert.AppendOrReplaceOrder(this.tradeList, args.Value); if (this.filterRestart == true && this.isInitialized == false) { } else { //调用事件 OnEventHandler(CTPStockResponseType.ReturnTradeResponse, args); } break; } #endregion #region 错单回报 case CTPStockResponseType.ErrorReturnOrderInsertResponse: { if (this.filterRestart == true && this.isInitialized == false) { } else { CTPEventArgs <CZQThostFtdcInputOrderField> args = CreateEventArgs <CZQThostFtdcInputOrderField>(pData, rspInfo); //调用事件 OnEventHandler(CTPStockResponseType.ErrorReturnOrderInsertResponse, args); } break; } #endregion #region 报单操作错误回报 case CTPStockResponseType.ErrorReturnOrderActionResponse: { if (this.filterRestart == true && this.isInitialized == false) { } else { CTPEventArgs <CZQThostFtdcOrderActionField> args = CreateEventArgs <CZQThostFtdcOrderActionField>(pData, rspInfo); //调用事件 OnEventHandler(CTPStockResponseType.ErrorReturnOrderActionResponse, args); } break; } #endregion #region 合约交易状态通知 case CTPStockResponseType.ReturnInstrumentStatusResponse: { CTPEventArgs <CZQThostFtdcInstrumentStatusField> args = CreateEventArgs <CZQThostFtdcInstrumentStatusField>(pData, rspInfo); CZQThostFtdcInstrumentStatusField instrumentStatus = args.Value; Trace.WriteLine(string.Format("{0}:{1}", instrumentStatus.ExchangeID, instrumentStatus.InstrumentStatus)); //交易所状态 if (this.exchangeStatus.ContainsKey(instrumentStatus.ExchangeID) == false) { this.exchangeStatus.Add(instrumentStatus.ExchangeID, instrumentStatus.InstrumentStatus); } //更新交易所状态 this.exchangeStatus[instrumentStatus.ExchangeID] = instrumentStatus.InstrumentStatus; this.tradingStatus = instrumentStatus.InstrumentStatus; //调用事件 OnEventHandler(CTPStockResponseType.ReturnInstrumentStatusResponse, args); break; } #endregion default: break; } }
public OnConnectArgs(IntPtr pApi, ref CZQThostFtdcRspUserLoginField pRspUserLogin, ConnectionStatus result) { this.pApi = pApi; this.pRspUserLogin = pRspUserLogin; this.result = result; }
private void OnConnect(IntPtr pApi, ref CZQThostFtdcRspUserLoginField pRspUserLogin, ConnectionStatus result) { //用于行情记算时简化时间解码 //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.E_logined == result) { _bMdConnected = true; mdlog.Info("TradingDay:{0},LoginTime:{1},SHFETime:{2},DCETime:{3},CZCETime:{4},FFEXTime:{5}", pRspUserLogin.TradingDay, pRspUserLogin.LoginTime, pRspUserLogin.SHFETime, pRspUserLogin.DCETime, pRspUserLogin.CZCETime, pRspUserLogin.FFEXTime); // 如果断线重连是使用的重新新建对象的方式,则要重新订阅 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.E_logined == result) { _RspUserLogin = pRspUserLogin; tdlog.Info("TradingDay:{0},LoginTime:{1},SHFETime:{2},DCETime:{3},CZCETime:{4},FFEXTime:{5}", pRspUserLogin.TradingDay, pRspUserLogin.LoginTime, pRspUserLogin.SHFETime, pRspUserLogin.DCETime, pRspUserLogin.CZCETime, pRspUserLogin.FFEXTime); UpdateLocalTime(SetLocalTimeMode, pRspUserLogin); //} //else if (ConnectionStatus.E_confirmed == result) //{ _bTdConnected = true; //请求查询资金 TraderApi.TD_ReqQryTradingAccount(m_pTdApi); //请求查询全部持仓 _dbInMemInvestorPosition.Clear(); TraderApi.TD_ReqQryInvestorPosition(m_pTdApi, null); //请求查询合约 _dictInstruments.Clear(); TraderApi.TD_ReqQryInstrument(m_pTdApi, null); _dictCommissionRate.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(); } }