private void CTPOnRtnOrder(ref CThostFtdcOrderField pOrder) { if (!IsLogin) { _rtnOrderTime = DateTime.Now; //登录前接收所有旧的 order } if (string.IsNullOrEmpty(pOrder.InstrumentID)) { return; } string id = string.Format("{0}|{1}|{2}", pOrder.SessionID, pOrder.FrontID, pOrder.OrderRef); //_dicLocalidSfrId.TryAdd(pOrder.OrderLocalID, id);//防止因此项未赋值,导致成交响应里无法更新 if (DicOrderField.TryAdd(id, new OrderField { Custom = (int)(long.TryParse(pOrder.OrderRef, out long tmp) ? tmp % 1000000 : 0), //修复: 值为null会导致界面显示错误 InsertTime = string.IsNullOrEmpty(pOrder.InsertTime) ? DateTime.Now.ToString("HH:mm:ss") : pOrder.InsertTime, InstrumentID = pOrder.InstrumentID, //SysID = string.Empty, //为null会导致界面显示错误 //TradeTime = string.Empty, IsLocal = pOrder.SessionID == _session, LimitPrice = pOrder.LimitPrice, OrderID = id, Volume = pOrder.VolumeTotalOriginal, VolumeLeft = pOrder.VolumeTotalOriginal, // pOrder->VolumeTotal; //f->VolumeLeft = pOrder->VolumeTotal; //由ontrade处理 Status = OrderStatus.Normal, StatusMsg = pOrder.StatusMsg, Direction = pOrder.Direction == TThostFtdcDirectionType.THOST_FTDC_D_Buy ? DirectionType.Buy : DirectionType.Sell, Hedge = (TThostFtdcHedgeFlagType)pOrder.CombHedgeFlag[0] == TThostFtdcHedgeFlagType.THOST_FTDC_HF_Speculation ? HedgeType.Speculation : (TThostFtdcHedgeFlagType)pOrder.CombHedgeFlag[0] == TThostFtdcHedgeFlagType.THOST_FTDC_HF_Arbitrage ? HedgeType.Arbitrage : HedgeType.Hedge, Offset = (TThostFtdcOffsetFlagType)pOrder.CombOffsetFlag[0] == TThostFtdcOffsetFlagType.THOST_FTDC_OF_Open ? OffsetType.Open : (TThostFtdcOffsetFlagType)pOrder.CombOffsetFlag[0] == TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseToday ? OffsetType.CloseToday : OffsetType.Close, })) //首次响应
/// <summary> /// 处理错单: CTP平台返回 /// </summary> /// <param name="pInputOrder"></param> /// <param name="pRspInfo"></param> /// <param name="nRequestID"></param> /// <param name="bIsLast"></param> private void CTPOnRspOrderInsert(ref CThostFtdcInputOrderField pInputOrder, ref CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast) { //ref重复::重发 //if (pRspInfo.ErrorID == 22) //{ // if (!IsLogin) return; // CThostFtdcInputOrderField f = pInputOrder; // //Thread.Sleep(50); // f.OrderRef = string.Format("{0:000000}{1}", ++_req, f.OrderRef.Length >= 6 ? f.OrderRef.Substring(f.OrderRef.Length - 6) : (new string('0', 6 - f.OrderRef.Length) + f.OrderRef)); // _t.ReqOrderInsert() // this._import.ReqCommand(EnumReq.ReqOrderInsert, f); //} //else { string id = string.Format("{0}|{1}|{2}", _session, _front, pInputOrder.OrderRef); int tmp; if (DicOrderField.TryAdd(id, new OrderField { Custom = int.TryParse(pInputOrder.OrderRef, out tmp) ? tmp % 1000000 : 0, // pOrder.OrderRef.Length <= 6 ? string.Empty : pOrder.OrderRef.Substring(pOrder.OrderRef.Length - 6), //InsertTime = DicOrderField.Max(n => n.Value.InsertTime) ?? DateTime.Now.ToString("HH:mm:ss"), InstrumentID = pInputOrder.InstrumentID, InsertTime = DateTime.Now.ToString("HH:mm:ss"), //为null会导致界面显示错误 //SysID = string.Empty, //为null会导致界面显示错误 TradeTime = string.Empty, IsLocal = true, LimitPrice = pInputOrder.LimitPrice, OrderID = id, Volume = pInputOrder.VolumeTotalOriginal, VolumeLeft = pInputOrder.VolumeTotalOriginal, // pOrder->VolumeTotal; //f->VolumeLeft = pOrder->VolumeTotal; //由ontrade处理 //Status = OrderStatus.Normal, //Status = OrderStatus.Canceled, Status = OrderStatus.Error, StatusMsg = pRspInfo.ErrorID + "|" + pRspInfo.ErrorMsg, Direction = pInputOrder.Direction == TThostFtdcDirectionType.THOST_FTDC_D_Buy ? DirectionType.Buy : DirectionType.Sell, Hedge = (TThostFtdcHedgeFlagType)pInputOrder.CombHedgeFlag[0] == TThostFtdcHedgeFlagType.THOST_FTDC_HF_Speculation ? HedgeType.Speculation : (TThostFtdcHedgeFlagType)pInputOrder.CombHedgeFlag[0] == TThostFtdcHedgeFlagType.THOST_FTDC_HF_Arbitrage ? HedgeType.Arbitrage : HedgeType.Hedge, Offset = (TThostFtdcOffsetFlagType)pInputOrder.CombOffsetFlag[0] == TThostFtdcOffsetFlagType.THOST_FTDC_OF_Open ? OffsetType.Open : (TThostFtdcOffsetFlagType)pInputOrder.CombOffsetFlag[0] == TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseToday ? OffsetType.CloseToday : OffsetType.Close, })) { string it = DicOrderField.Max(n => n.Value.InsertTime); if (string.IsNullOrEmpty(it)) { it = DateTime.Now.ToString("HH:mm:ss"); } else { it = TimeSpan.Parse(it).Add(TimeSpan.FromMilliseconds(1)).ToString(@"hh\:mm\:ss"); //加1秒 } DicOrderField[id].InsertTime = it; if (IsLogin) { _OnRtnErrOrder?.Invoke(this, new ErrOrderArgs { ErrorID = pRspInfo.ErrorID, ErrorMsg = pRspInfo.ErrorMsg, Value = DicOrderField[id] }); } } } }
private void CTPOnRtnOrder(ref CThostFtdcOrderField pOrder) { TimeSpan ts; if (!IsLogin) { _rtnOrderTime = DateTime.Now; //登录前接收所有旧的 order } if (string.IsNullOrEmpty(pOrder.InstrumentID)) { return; } string id = string.Format("{0}|{1}|{2}", pOrder.SessionID, pOrder.FrontID, pOrder.OrderRef); //_dicLocalidSfrId.TryAdd(pOrder.OrderLocalID, id);//防止因此项未赋值,导致成交响应里无法更新 long tmp; if (DicOrderField.TryAdd(id, new OrderField { Custom = (int)(long.TryParse(pOrder.OrderRef, out tmp) ? tmp % 1000000 : 0), //修复: 值为null会导致界面显示错误 InsertTime = string.IsNullOrEmpty(pOrder.InsertTime) ? DateTime.Now.ToString("HH:mm:ss") : pOrder.InsertTime, InstrumentID = pOrder.InstrumentID, //SysID = string.Empty, //为null会导致界面显示错误 //TradeTime = string.Empty, IsLocal = pOrder.SessionID == _session, LimitPrice = pOrder.LimitPrice, OrderID = id, Volume = pOrder.VolumeTotalOriginal, VolumeLeft = pOrder.VolumeTotalOriginal, // pOrder->VolumeTotal; //f->VolumeLeft = pOrder->VolumeTotal; //由ontrade处理 Status = OrderStatus.Normal, StatusMsg = pOrder.StatusMsg, Direction = pOrder.Direction == TThostFtdcDirectionType.THOST_FTDC_D_Buy ? DirectionType.Buy : DirectionType.Sell, Hedge = (TThostFtdcHedgeFlagType)pOrder.CombHedgeFlag[0] == TThostFtdcHedgeFlagType.THOST_FTDC_HF_Speculation ? HedgeType.Speculation : (TThostFtdcHedgeFlagType)pOrder.CombHedgeFlag[0] == TThostFtdcHedgeFlagType.THOST_FTDC_HF_Arbitrage ? HedgeType.Arbitrage : HedgeType.Hedge, Offset = (TThostFtdcOffsetFlagType)pOrder.CombOffsetFlag[0] == TThostFtdcOffsetFlagType.THOST_FTDC_OF_Open ? OffsetType.Open : (TThostFtdcOffsetFlagType)pOrder.CombOffsetFlag[0] == TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseToday ? OffsetType.CloseToday : OffsetType.Close, })) //首次响应 { //if (pOrder.OrderLocalID.Length > 0) //成交响应时用 if (IsLogin) { _OnRtnOrder?.Invoke(this, new OrderArgs { Value = DicOrderField[id] }); } } else { OrderField f = DicOrderField[id]; //修复: 值为null会导致界面显示错误 f.InsertTime = string.IsNullOrEmpty(pOrder.InsertTime) ? DateTime.Now.ToString("HH:mm:ss") : pOrder.InsertTime; if (_excTime == DateTime.MinValue && TimeSpan.TryParse(f.InsertTime, out ts)) //首次的onrtnorder时间有问题,故放在此处更新_exctime { _excTime = DateTime.Today.Add(ts); _sw.Restart(); } if (TThostFtdcOrderStatusType.THOST_FTDC_OST_Canceled == pOrder.OrderStatus) { f.Status = OrderStatus.Canceled; f.StatusMsg = pOrder.StatusMsg; if (!string.IsNullOrEmpty(pOrder.CancelTime)) { f.TradeTime = pOrder.CancelTime; } else if (IsLogin)//成撤时间:此处为撤单时间 { f.TradeTime = DateTime.Now.ToString("HH:mm:ss"); } if (IsLogin) { //委托被拒绝的撤单按错误处理 if (pOrder.StatusMsg.IndexOf(@"被拒绝") >= 0) { _OnRtnErrOrder?.Invoke(this, new ErrOrderArgs { ErrorID = -1, ErrorMsg = pOrder.StatusMsg, Value = f }); } else { _OnRtnCancel?.Invoke(this, new OrderArgs { Value = f, }); } } //撤单次数等规则由业务层处理 //_dicCancelTimes.AddOrUpdate(f.InstrumentID, 1, (k, v) => v + 1); //if (_dicCancelTimes[f.InstrumentID] >= 450 && _dicCancelTimes[f.InstrumentID] % 10 == 0) //{ // if (IsLogin && _caller._OnRtnErrCancel != null) // _caller._OnRtnErrOrder(_caller, new ErrOrderArgs // { // ErrorID = -1, // ErrorMsg = string.Format("撤单次数将要达到上限500次[{0}]", _dicCancelTimes[f.InstrumentID]), // Value = f, // }); //} } } //委托到交易所 if (!string.IsNullOrEmpty(pOrder.OrderSysID)) { DicOrderField[id].SysID = pOrder.OrderSysID; if (_dicSysidSfrId.TryAdd(pOrder.OrderSysID, id)) { List <CThostFtdcTradeField> list; //成交先至,则在此处再调成交 if (_sysidTrade.TryGetValue(pOrder.OrderSysID, out list)) { foreach (CThostFtdcTradeField t1 in list) { var t = t1; //再调用rtntrade: 成交响应在rtntrade中完成 CTPOnRtnTrade(ref t); } list.Clear(); } } } }