Beispiel #1
0
        private void TradeExt_OnRtnTrade(object sender, TradeArgs e)
        {
            OrderField of;

            if (!DicOrderField.TryGetValue(e.Value.OrderID, out of))
            {
                return;
            }
            if (!of.IsLocal)
            {
                return;
            }
        }
Beispiel #2
0
        private void CTPOnErrRtnOrderAction(ref CThostFtdcOrderActionField pOrderAction, ref CThostFtdcRspInfoField pRspInfo)
        {
            if (pRspInfo.ErrorID == 0)
            {
                return;
            }

            string     id = string.Format("{0}|{1}|{2}", pOrderAction.SessionID, pOrderAction.FrontID, pOrderAction.OrderRef);
            OrderField of;

            if (IsLogin && DicOrderField.TryGetValue(id, out of))
            {
                _OnRtnErrCancel?.Invoke(this, new ErrOrderArgs {
                    ErrorID = pRspInfo.ErrorID, ErrorMsg = pRspInfo.ErrorMsg, Value = of
                });
            }
        }
Beispiel #3
0
        public override int ReqOrderAction(string pOrderId)
        {
            OrderField of;

            if (!DicOrderField.TryGetValue(pOrderId, out of))
            {
                _OnRtnError?.Invoke(this, new ErrorEventArgs
                {
                    ErrorID  = -1,
                    ErrorMsg = string.Format("OrderActionError:[OrderID:{0}][ErrorMsg:no orderid.]", pOrderId),
                });
                return(-1);
            }

            return((int)_t.ReqOrderAction(_broker, _investor, InstrumentID: of.InstrumentID,
                                          OrderRef: pOrderId.Split('|')[2],
                                          FrontID: int.Parse(pOrderId.Split('|')[1]),
                                          SessionID: int.Parse(pOrderId.Split('|')[0]),
                                          ActionFlag: TThostFtdcActionFlagType.THOST_FTDC_AF_Delete));
        }
Beispiel #4
0
        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,
            }))             //首次响应
Beispiel #5
0
        /// <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]
                        });
                    }
                }
            }
        }
Beispiel #6
0
        private void CTPOnRtnTrade(ref CThostFtdcTradeField pTrade)
        {
            if (!IsLogin)
            {
                _rtnOrderTime = DateTime.Now;
            }

            string     id;
            OrderField of = null;

            if (!(_dicSysidSfrId.TryGetValue(pTrade.OrderSysID, out id) && DicOrderField.TryGetValue(id, out of)))
            {
                CThostFtdcTradeField fReTrade = pTrade;
                var list = _sysidTrade.GetOrAdd(pTrade.OrderSysID, new List <CThostFtdcTradeField>());
                list.Add(fReTrade);
                return;
            }

            TradeField f = new TradeField
            {
                Hedge = pTrade.HedgeFlag == TThostFtdcHedgeFlagType.THOST_FTDC_HF_Speculation ? HedgeType.Speculation
                    : pTrade.HedgeFlag == TThostFtdcHedgeFlagType.THOST_FTDC_HF_Arbitrage ? HedgeType.Arbitrage : HedgeType.Hedge,
                Direction = pTrade.Direction == TThostFtdcDirectionType.THOST_FTDC_D_Buy ? DirectionType.Buy : DirectionType.Sell,

                //ExchangeID = pTrade.ExchangeID,
                InstrumentID = pTrade.InstrumentID,
                Offset       = pTrade.OffsetFlag == TThostFtdcOffsetFlagType.THOST_FTDC_OF_Open ? OffsetType.Open
                    : pTrade.OffsetFlag == TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseToday ? OffsetType.CloseToday : OffsetType.Close,
                Price      = pTrade.Price,
                TradeID    = pTrade.TradeID + (char)pTrade.Direction,
                TradeTime  = pTrade.TradeTime,
                TradingDay = pTrade.TradingDay,
                Volume     = pTrade.Volume,
                SysID      = pTrade.OrderSysID,
            };
            Exchange exc;

            if (Enum.TryParse(pTrade.ExchangeID, out exc))
            {
                f.ExchangeID = exc;
            }
            if (DicTradeField.TryAdd(f.TradeID, f)) // string.Format("{0}_{1}", f.TradeID, f.Direction), f))
            {
                f.OrderID      = id;                //更新成交对应的委托ID
                of.TradeTime   = pTrade.TradeTime;
                of.AvgPrice    = (of.AvgPrice * (of.Volume - of.VolumeLeft) + pTrade.Price * pTrade.Volume) / (of.Volume - of.VolumeLeft + pTrade.Volume);
                of.TradeVolume = pTrade.Volume;
                of.VolumeLeft -= of.TradeVolume;
                if (of.VolumeLeft == 0)
                {
                    of.Status    = OrderStatus.Filled;
                    of.StatusMsg = "全部成交";
                }
                else
                {
                    of.Status    = OrderStatus.Partial;
                    of.StatusMsg = "部分成交";
                }

                if (IsLogin)
                {
                    #region 更新持仓
                    PositionField pf;
                    //处理持仓
                    if (f.Offset == OffsetType.Open)
                    {
                        pf = DicPositionField.GetOrAdd(f.InstrumentID + "_" + f.Direction, new PositionField());
                        pf.InstrumentID = f.InstrumentID;
                        pf.Direction    = f.Direction;
                        pf.Hedge        = f.Hedge;
                        pf.Price        = (pf.Price * pf.Position + f.Price * f.Volume) / (pf.Position + f.Volume);
                        pf.TdPosition  += f.Volume;
                        pf.Position    += f.Volume;
                    }
                    else
                    {
                        pf = this.DicPositionField.GetOrAdd(f.InstrumentID + "_" + (f.Direction == DirectionType.Buy ? "Sell" : "Buy"), new PositionField());
                        if (f.Offset == OffsetType.CloseToday)
                        {
                            pf.TdPosition -= f.Volume;
                        }
                        else
                        {
                            int tdClose = Math.Min(pf.TdPosition, f.Volume);
                            if (pf.TdPosition > 0)
                            {
                                pf.TdPosition -= tdClose;
                            }
                            pf.YdPosition -= Math.Max(0, f.Volume - tdClose);
                        }
                        pf.Position -= f.Volume;
                    }
                    #endregion

                    //委托响应
                    _OnRtnOrder?.Invoke(this, new OrderArgs {
                        Value = of
                    });
                    //成交响应
                    _OnRtnTrade?.Invoke(this, new TradeArgs {
                        Value = f
                    });
                }
            }
        }
Beispiel #7
0
        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();
                    }
                }
            }
        }