Пример #1
0
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return(false);
            }
            if (GetType() != obj.GetType())
            {
                return(false);
            }
            //(frontID+sessionID+orderRef)组合和(ExchangeID + OrderSysID)组合均能标识唯一的委托编号
            //两者使用环境不同,但在有值的前提下都可以作为识别关键字
            CtpOrderNum orderNum = obj as CtpOrderNum;

            if (this.FrontID != 0 &&
                this.SessionID != 0 &&
                string.IsNullOrEmpty(this.OrderRef) == false &&
                this.FrontID == orderNum.FrontID &&
                this.SessionID == orderNum.SessionID &&
                this.OrderRef == orderNum.OrderRef)
            {
                return(true);
            }
            else if (string.IsNullOrEmpty(this.ExchangeID) == false &&
                     string.IsNullOrEmpty(this.OrderSysID) == false &&
                     this.ExchangeID == orderNum.ExchangeID &&
                     this.OrderSysID == orderNum.OrderSysID)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #2
0
        /// <summary>
        /// 克隆CtpOrderNum对象。
        /// </summary>
        /// <returns></returns>
        public override USeOrderNum Clone()
        {
            CtpOrderNum orderNum = new CtpOrderNum(this.FrontID,
                                                   this.SessionID,
                                                   this.OrderRef,
                                                   this.ExchangeID,
                                                   this.OrderSysID);

            return(orderNum);
        }
        /// <summary>
        /// 撤单。
        /// </summary>
        /// <param name="orderNum">委托单号。</param>
        /// <param name="product">委托产品。</param>
        /// <param name="error">[out]撤单失败错误信息。</param>
        /// <returns>撤单是否成功。</returns>
        public override bool CancelOrder(USeOrderNum orderNum, USeInstrument product, out string error)
        {
            CtpOrderNum ctpOrderNum = orderNum as CtpOrderNum;

            if (ctpOrderNum == null)
            {
                throw new ArgumentException("Invalid orderNum type", "orderNum");
            }

            error = string.Empty;

            int requestID = m_requetSeqIDCreator.Next();

            try
            {
                InputOrderActionField requestField = new InputOrderActionField();
                requestField.ActionFlag   = ActionFlagType.Delete;
                requestField.BrokerID     = m_brokerID;
                requestField.InvestorID   = m_investorID;
                requestField.InstrumentID = product.InstrumentCode;
                requestField.FrontID      = ctpOrderNum.FrontID;
                requestField.SessionID    = ctpOrderNum.SessionID;
                requestField.OrderRef     = ctpOrderNum.OrderRef;
                requestField.ExchangeID   = ctpOrderNum.ExchangeID;
                requestField.OrderSysID   = ctpOrderNum.OrderSysID;

                m_ctpUser.ReqOrderAction(ref requestField, requestID);

                return(true);
            }
            catch (Exception ex)
            {
                m_logger.WriteError(string.Format("{0} cancelorder[OrderNum:{1}] failed,Error:{2}.",
                                                  ToString(), orderNum, ex.Message));
                error = ex.Message;
                return(false);
            }
        }
        /// <summary>
        /// 委托下单。
        /// </summary>
        /// <param name="instrument">委托产品。</param>
        /// <param name="qty">委托量。</param>
        /// <param name="price">委托价格。</param>
        /// <param name="offsetType">开平仓方向。</param>
        /// <param name="orderSide">买卖方向。</param>
        /// <param name="error">[out]委托失败原因。</param>
        /// <returns>委托单号。</returns>
        /// <remarks>返回为null代表失败,否则为委托单号。</remarks>
        public override USeOrderNum PlaceOrder(USeInstrument instrument, int qty, decimal price, USeOffsetType offsetType, USeOrderSide orderSide, out string error)
        {
            if (m_ctpUser == null || m_ctpUser.IsLogin == false)
            {
                error = "OrderServer unable";
                return(null);
            }

            string orderRef  = m_orderRefIDCreator.Next().ToString(); // 生成报单引用
            int    requestID = m_requetSeqIDCreator.Next();

            error = string.Empty;

            try
            {
                OffsetFlagType ctpOffsetFlag;
                switch (offsetType)
                {
                case USeOffsetType.Open: ctpOffsetFlag = OffsetFlagType.Open; break;

                case USeOffsetType.Close: ctpOffsetFlag = OffsetFlagType.Close; break;

                case USeOffsetType.CloseToday: ctpOffsetFlag = OffsetFlagType.CloseToday; break;

                case USeOffsetType.CloseHistory: ctpOffsetFlag = OffsetFlagType.CloseYesterday; break;

                default:
                    throw new ArgumentException(string.Format("Invalid offsetType {0}.", offsetType), "offsetType");
                }

                DirectionType ctpDirection;
                switch (orderSide)
                {
                case USeOrderSide.Buy: ctpDirection = DirectionType.Buy; break;

                case USeOrderSide.Sell: ctpDirection = DirectionType.Sell; break;

                default:
                    throw new ArgumentException(string.Format("Invalid orderside {0}.", orderSide), "orderSide");
                }

                InputOrderField requestField = new InputOrderField();
                requestField.BrokerID            = m_brokerID;
                requestField.InvestorID          = m_investorID;
                requestField.InstrumentID        = instrument.InstrumentCode;
                requestField.OrderRef            = orderRef;
                requestField.UserID              = m_investorID;
                requestField.OrderPriceType      = OrderPriceType.LimitPrice;
                requestField.Direction           = ctpDirection;
                requestField.CombOffsetFlag1     = ctpOffsetFlag;
                requestField.CombHedgeFlag1      = HedgeFlagType.Speculation;
                requestField.LimitPrice          = Convert.ToDouble(price);
                requestField.VolumeTotalOriginal = qty;
                requestField.TimeCondition       = TimeConditionType.GFD;
                requestField.VolumeCondition     = VolumeConditionType.AV;
                requestField.MinVolume           = 1;
                requestField.ContingentCondition = ContingentConditionType.Immediately;
                requestField.ForceCloseReason    = ForceCloseReasonType.NotForceClose;
                requestField.IsAutoSuspend       = IntBoolType.No;
                requestField.BusinessUnit        = null;
                requestField.RequestID           = requestID;
                requestField.UserForceClose      = IntBoolType.No;

                //构造一个委托回报,防止报单不合规等问题遭CTP拒绝,但未有委托回报推送
                OrderField orderField = new OrderField();
                orderField.BrokerID            = m_brokerID;
                orderField.FrontID             = m_frontID;
                orderField.SessionID           = m_sessionID;
                orderField.OrderRef            = orderRef;
                orderField.OrderSysID          = string.Empty;
                orderField.InvestorID          = m_investorID;
                orderField.InstrumentID        = instrument.InstrumentCode;
                orderField.ExchangeID          = CtpProtocol.USeMarketToFtdcExchange(instrument.Market);
                orderField.VolumeTotalOriginal = qty;
                orderField.LimitPrice          = Convert.ToDouble(price);
                orderField.VolumeTraded        = 0;
                orderField.OrderStatus         = OrderStatusType.Unknown;
                orderField.Direction           = orderSide == USeOrderSide.Buy ? DirectionType.Buy : DirectionType.Sell;

                switch (offsetType)
                {
                case USeOffsetType.Open: orderField.CombOffsetFlag1 = OffsetFlagType.Open; break;

                case USeOffsetType.Close: orderField.CombOffsetFlag1 = OffsetFlagType.Close; break;

                case USeOffsetType.CloseHistory: orderField.CombOffsetFlag1 = OffsetFlagType.CloseYesterday; break;

                case USeOffsetType.CloseToday: orderField.CombOffsetFlag1 = OffsetFlagType.CloseToday; break;
                }
                orderField.InsertDate = DateTime.Now.ToString("yyyyMMdd");
                orderField.InsertTime = DateTime.Now.ToString("HH:mm:ss");

                m_dataBuffer.UpdateOrderField(orderField);


                m_ctpUser.ReqOrderInsert(ref requestField, requestID);

                USeOrderNum orderNum = new CtpOrderNum(m_frontID, m_sessionID, orderRef);

                m_logger.WriteInformation(string.Format("{0}.PlaceOrder() ok,[RequestID:{1}][Instrument:{2}][FulcOffsetType{3}][Qty:{4}][Price:{5}].",
                                                        ToString(), requestID, instrument.InstrumentCode, offsetType, qty, price));

                return(orderNum);
            }
            catch (Exception ex)
            {
                m_logger.WriteError(string.Format("{0} placeorder[Instrument:{1}][FulcOffsetType:{2}][Qty:{3}][Price:{4}] failed,Error:{5}.",
                                                  ToString(), instrument.InstrumentCode, offsetType, qty, price, ex.Message));
                error = ex.Message;
                return(null);
            }
        }
Пример #5
0
        /// <summary>
        /// CTP TradeField To USeTradeBook。
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        private USeTradeBook CtpTradeFieldToUSeTradeBook(TradeField field)
        {
            USeTradeBook tradeBook = new USeTradeBook();

            try
            {
                tradeBook.Instrument = new USeInstrument(field.InstrumentID.Trim(),
                                                         field.InstrumentID.Trim(),
                                                         CtpProtocol.FtdcExchangeToUSeMarket(field.ExchangeID));
                tradeBook.TradeNum = field.TradeID.Trim();
                USeOrderNum  orderNum  = new CtpOrderNum(field.ExchangeID, field.OrderSysID);
                USeOrderBook orderBook = m_dataBuffer.GetOrderBook(orderNum);
                if (orderBook != null)
                {
                    orderNum = orderBook.OrderNum.Clone();  // 去搜索对应委托单,若存在则将委托单号设置为完整委托单号
                }
                tradeBook.OrderNum  = orderNum;
                tradeBook.OrderSide = field.Direction == DirectionType.Buy ? USeOrderSide.Buy : USeOrderSide.Sell;
                switch (field.OffsetFlag)
                {
                case OffsetFlagType.Close:
                case OffsetFlagType.ForceClose:
                    tradeBook.OffsetType = USeOffsetType.Close; break;

                case OffsetFlagType.CloseToday:
                    tradeBook.OffsetType = USeOffsetType.CloseToday; break;

                case OffsetFlagType.CloseYesterday:
                    tradeBook.OffsetType = USeOffsetType.CloseHistory; break;

                case OffsetFlagType.Open:
                    tradeBook.OffsetType = USeOffsetType.Open; break;

                default:
                    Debug.Assert(false, string.Format("CtpTradeFieldToUSeTradeBook(),Invalid offsetfalg.", field.OffsetFlag));
                    break;
                }
                tradeBook.Price   = Convert.ToDecimal(field.Price);
                tradeBook.Qty     = field.Volume;
                tradeBook.Account = field.InvestorID;
                DateTime tradeTime = DateTime.Now;
                if (string.IsNullOrEmpty(field.TradeDate) && string.IsNullOrEmpty(field.TradeTime))
                {
                    Debug.Assert(false);
                    tradeTime = DateTime.Now;
                }
                else if (string.IsNullOrEmpty(field.TradeDate))
                {
                    if (DateTime.TryParseExact(DateTime.Today.ToString("yyyyMMdd") + field.TradeTime, "yyyyMMddHH:mm:ss", null, System.Globalization.DateTimeStyles.None, out tradeTime) == false)
                    {
                        Debug.Assert(false);
                        tradeTime = DateTime.Now;
                    }
                }
                else
                {
                    if (DateTime.TryParseExact(field.TradeDate + field.TradeTime, "yyyyMMddHH:mm:ss", null, System.Globalization.DateTimeStyles.None, out tradeTime) == false)
                    {
                        Debug.Assert(false);
                        tradeTime = DateTime.Now;
                    }
                }

                tradeBook.TradeTime = tradeTime;

                int volumeMultiple = m_dataBuffer.GetVolumeMultiple(tradeBook.Instrument);

                tradeBook.Amount = tradeBook.Price * tradeBook.Qty * volumeMultiple;
                // 手续费尝试计算
                tradeBook.Fee = m_dataBuffer.CalculateFee(tradeBook.Instrument, tradeBook.OffsetType, tradeBook.Qty, tradeBook.Price);
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "CtpTradeFieldToUSeTradeBook() convet failed," + ex.Message);
            }
            return(tradeBook);
        }