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); } }
/// <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); } }
/// <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); }