private decimal InternalCalculateFee(USeInstrument instrument, USeOffsetType offsetType, int qty, decimal price) { USeFee fee = InternalGetFee(instrument); if (fee == null) { return(0m); } int volumeMultiple = InternalGetVolumeMultiple(instrument); switch (offsetType) { case USeOffsetType.Open: return(fee.OpenRatioByMoney * qty * price * volumeMultiple + fee.OpenRatioByVolume * qty); case USeOffsetType.CloseHistory: case USeOffsetType.Close: return(fee.CloseRatioByMoney * qty * price * volumeMultiple + fee.CloseRatioByVolume * qty); case USeOffsetType.CloseToday: return(fee.CloseTodayRatioByMoney * qty * price * volumeMultiple + fee.CloseTodayRatioByVolume * qty); default: Debug.Assert(false); return(0m); } }
/// <summary> /// 开平仓方向描述。 /// </summary> /// <param name="offsetType">开平仓方向。</param> /// <returns>描述字符串。</returns> public static string ToDescription(this USeOffsetType offsetType) { switch (offsetType) { case USeOffsetType.Open: return("开仓"); case USeOffsetType.CloseHistory: return("平昨仓"); case USeOffsetType.CloseToday: return("平今仓"); case USeOffsetType.Close: return("平仓"); default: return("未知"); } }
private USeOffsetType GetChoiceOffsetType() { USeOffsetType order_offset_type = USeOffsetType.Open; if (this.radioButton_Open.Checked) { order_offset_type = USeOffsetType.Open; } else if (this.radioButton_CloseToday.Checked) { order_offset_type = USeOffsetType.CloseToday; } else if (this.radioButton_CloseYD.Checked) { order_offset_type = USeOffsetType.CloseHistory; } else { Debug.Assert(false); } return(order_offset_type); }
/// <summary> /// 创建空的委托回报。 /// </summary> /// <param name="orderNum">委托单号。</param> /// <param name="instrument">合约。</param> /// <param name="orderQty">委托量。</param> /// <param name="orderPrice">委托价格。</param> /// <param name="offsetType">开平方向。</param> /// <param name="orderSide">买卖方向。</param> /// <returns></returns> private USeOrderBook CreateOrignalUSeOrderBook(USeOrderNum orderNum, USeInstrument instrument, int orderQty, decimal orderPrice, USeOffsetType offsetType, USeOrderSide orderSide) { USeOrderBook orderBook = new USeOrderBook(); orderBook.OrderNum = orderNum; orderBook.Account = string.Empty; orderBook.Instrument = instrument; orderBook.OrderQty = orderQty; orderBook.OrderPrice = orderPrice; orderBook.TradeQty = 0; orderBook.TradeAmount = 0m; orderBook.TradePrice = 0m; orderBook.TradeFee = 0m; orderBook.OrderStatus = USeOrderStatus.Unknown; orderBook.CancelQty = 0; orderBook.OrderSide = orderSide; orderBook.OffsetType = offsetType; orderBook.Memo = string.Empty; orderBook.OrderTime = DateTime.Now; return(orderBook); }
/// <summary> /// 创建委托命令集合。 /// </summary> /// <param name="taskId">任务ID。</param> /// <param name="instrument">合约。</param> /// <param name="orderSide">买卖方向。</param> /// <param name="offsetType">开平方向。</param> /// <param name="orderQty">委托量。</param> /// <param name="orderPrice">委托价格。</param> /// <param name="orderReason">委托原因。</param> /// <returns></returns> private List <OrderCommand> CreateOrderCommands(int taskId, USeInstrument instrument, USeOrderSide orderSide, USeOffsetType offsetType, int orderQty, decimal orderPrice, string orderReason) { List <OrderCommand> commandList = new List <OrderCommand>(); //构造指令 if (offsetType == USeOffsetType.Open) { OrderCommand command = new OrderCommand() { TaskId = taskId, Instrument = instrument, OrderSide = orderSide, OffsetType = USeOffsetType.Open, OrderQty = orderQty, OrderPrice = orderPrice, OrderReason = orderReason }; commandList.Add(command); } else { Debug.Assert(offsetType == USeOffsetType.Close); if (instrument.Market == USeMarket.SHFE) { #region 交所平仓 USeDirection direction = orderSide == USeOrderSide.Buy ? USeDirection.Short : USeDirection.Long; //上海交易所平仓需区分平今还是平昨 USePosition position = m_orderDriver.QueryPositions(instrument, direction); //[yangming] string tmpTestText = string.Format(@"[hanyuClose]Ins:{0} OrderSide:{1} OffsetFlag:{2} OrderQty:{3},NewAvaliablePosition:{4} ,NewFrozonPosition:{5},NewPosition{6}," + "OldAvaliablePosition:{7},OldFrozonPosition:{8},OldPosition:{9}", instrument.InstrumentCode, orderSide, offsetType, orderQty, position.NewAvaliablePosition, position.NewFrozonPosition, position.NewPosition, position.OldAvaliablePosition, position.OldFrozonPosition, position.OldPosition); USeManager.Instance.EventLogger.WriteAudit(tmpTestText); // if (position == null || position.AvaliablePosition < orderQty) { //查询不到仓位,或者仓位不足,直接构造平今指令 OrderCommand command = new OrderCommand() { TaskId = taskId, Instrument = instrument, OrderSide = orderSide, OffsetType = USeOffsetType.CloseToday, OrderQty = orderQty, OrderPrice = orderPrice, OrderReason = orderReason }; commandList.Add(command); } else { //平今 int remainQty = orderQty; if (position.NewAvaliablePosition > 0) { int closeQty = Math.Min(position.NewAvaliablePosition, remainQty); OrderCommand command = new OrderCommand() { TaskId = taskId, Instrument = instrument, OrderSide = orderSide, OffsetType = USeOffsetType.CloseToday, OrderQty = closeQty, OrderPrice = orderPrice, OrderReason = orderReason }; remainQty -= closeQty; commandList.Add(command); } //平昨 if (remainQty > 0) { Debug.Assert(remainQty <= position.OldAvaliablePosition); int closeQty = remainQty; OrderCommand command = new OrderCommand() { TaskId = taskId, Instrument = instrument, OrderSide = orderSide, OffsetType = USeOffsetType.CloseHistory, OrderQty = closeQty, OrderPrice = orderPrice, OrderReason = orderReason }; remainQty -= closeQty; commandList.Add(command); } Debug.Assert(remainQty == 0); } #endregion } else { OrderCommand command = new OrderCommand() { TaskId = taskId, Instrument = instrument, OrderSide = orderSide, OffsetType = USeOffsetType.Close, OrderQty = orderQty, OrderPrice = orderPrice, OrderReason = orderReason }; } } return(commandList); }
/// <summary> /// 套利单任务 -- 优先合约下单。 /// </summary> /// <param name="taskGroup">开仓/平仓 任务组。</param> /// <param name="differentialUnit">最大仓差。</param> /// <returns></returns> private bool ProcessFirstSubTask(ArbitrageTaskGroup taskGroup, int differentialUnit) { #region 校验 PriceSpreadCheckResult priceSpeadResult = CheckPriceSpread(taskGroup.OpenCloseType, m_arbitrageOrder.Argument); if (priceSpeadResult.OrderReason == TaskOrderReason.None) { WriteTraderDebugInfo("优先合约检查,不满足价差条件"); return(false); } int firstUnExeTaskIndex = taskGroup.GetFirstTaskUnExecutIndex(); if (firstUnExeTaskIndex < 0) { // 优先合约全部完成下单 return(false); } bool secondTaskIsPlaceOrder = taskGroup.CheckSecondTaskIsPlaceOrder(firstUnExeTaskIndex); if (secondTaskIsPlaceOrder == false) { WriteTraderDebugInfo("反手合约还未下单,不许下单"); return(false); } //反手仓位未成交任务数 int secondUnTradeTaskCount = taskGroup.GetUnTradeSecondTaskCount(firstUnExeTaskIndex); if (secondUnTradeTaskCount >= differentialUnit) { WriteTraderDebugInfo("优先合约反手合约任务仓差大于等于允许最大仓差,不许下单"); return(false); } ArbitrageTask task = taskGroup.TaskList[firstUnExeTaskIndex]; Debug.Assert(task != null && task.TaskState == ArbitrageTaskState.None); ArbitrageSubTask firstSubTask = task.FirstSubTask; if (firstSubTask.TryOrderCount >= m_tryOrderCondition.MaxTryOrderCount) { m_backgroundRunFlag = false; string text = string.Format("流程暂停,{2}下单任务[{0}]超出最大尝试下单次数{1}次", task.TaskId, m_tryOrderCondition.MaxTryOrderCount, firstSubTask.Instrument.InstrumentCode); AutoTraderNotice notice = CreateTraderNotice(AutoTraderNoticeType.Order, text); SafeFireAutoTraderNotice(notice); AlarmNotice alarm = new AlarmNotice(AlarmType.AutoTraderWarning, text); SafeFireAutoTraderAlarm(alarm); WriteTraderNoticeLog(notice); return(false); } if (firstSubTask.CanPlaceNextOrder(m_tryOrderCondition.NextOrderInterval) == false) { WriteTraderDebugInfo("优先合约检查,距离上次下单时间过近,暂时不下单"); return(false); } #endregion #region 单 Debug.Assert(priceSpeadResult.OrderReason == TaskOrderReason.Open || priceSpeadResult.OrderReason == TaskOrderReason.Close || priceSpeadResult.OrderReason == TaskOrderReason.StopLoss); task.OrderReason = priceSpeadResult.OrderReason; task.PriceSpread = priceSpeadResult.PriceSpreadThreshold; //获取优先合约下单价格 decimal orderPrice = GetFirstInstrumentOrderPrice(firstSubTask.Instrument, firstSubTask.OrderPriceType, firstSubTask.OrderSide); Debug.Assert(orderPrice > 0); int orderQty = firstSubTask.UnOrderQty; Debug.Assert(orderQty > 0); USeInstrument instrument = firstSubTask.Instrument; USeOffsetType offsetType = firstSubTask.OffsetType; USeOrderSide orderSide = firstSubTask.OrderSide; List <OrderCommand> commandList = null; lock (ms_orderSyncObj) { commandList = CreateOrderCommands(task.TaskId, instrument, orderSide, offsetType, orderQty, orderPrice, "优先合约"); Debug.Assert(commandList != null && commandList.Count > 0); foreach (OrderCommand command in commandList) { bool orderResult = PlaceOrderForOrderCommand(command); if (orderResult) { firstSubTask.AddPositiveOrderBook(command.CreateOrignalOrderBook()); task.UpdateTaskState(); //task.TaskState = ArbitrageTaskState.FirstPlaceOrder; } } } firstSubTask.AddTryOrderCount(); // 下单累加1次 #endregion #region 通知 foreach (OrderCommand command in commandList) { AutoTraderNotice notice = CreateTraderNotice(AutoTraderNoticeType.Order, command.ToDescription()); SafeFireAutoTraderNotice(notice); WriteTraderNoticeLog(notice); } #endregion return(true); }
/// <summary> /// 套利单任务--反手合约下单(优先合约已成交) /// </summary> /// <param name="taskGroup">开仓/平仓 任务组。</param> private bool ProcessSecondSubTask(ArbitrageTaskGroup taskGroup) { for (int i = 0; i < taskGroup.TaskList.Count; i++) { #region 校验 ArbitrageTask task = taskGroup.TaskList[i]; if (task.TaskState != ArbitrageTaskState.FirstTradeFinish) { //优先合约未成交,无需做反手合约检查 continue; } ArbitrageSubTask secondSubTask = task.SecondSubTask; if (secondSubTask.TryOrderCount >= m_tryOrderCondition.MaxTryOrderCount) { m_backgroundRunFlag = false; string text = string.Format("流程暂停,{2}下单任务[{0}]超出最大尝试下单次数{1}次", task.TaskId, m_tryOrderCondition.MaxTryOrderCount, secondSubTask.Instrument.InstrumentCode); AutoTraderNotice notice = CreateTraderNotice(AutoTraderNoticeType.Order, text); SafeFireAutoTraderNotice(notice); AlarmNotice alarm = new AlarmNotice(AlarmType.AutoTraderWarning, text); SafeFireAutoTraderAlarm(alarm); WriteTraderNoticeLog(notice); return(false); } if (secondSubTask.CanPlaceNextOrder(m_tryOrderCondition.NextOrderInterval) == false) { WriteTraderDebugInfo("反手合约检查,距离上次下单时间过近,暂时不下单"); continue; } #endregion #region 单 //获取反手合约下单价格 decimal orderPrice = GetSecondTaskOrderPrice(taskGroup.OperationSide, taskGroup.PreferentialSide, task.FirstSubTaskAvgTradePrice, task.PriceSpread); orderPrice = TrimOrderPrice(secondSubTask.Instrument, orderPrice, secondSubTask.OrderSide); int orderQty = secondSubTask.UnOrderQty; Debug.Assert(orderQty > 0); USeInstrument instrument = secondSubTask.Instrument; USeOffsetType offsetType = secondSubTask.OffsetType; USeOrderSide orderSide = secondSubTask.OrderSide; List <OrderCommand> commandList = null; lock (ms_orderSyncObj) { commandList = CreateOrderCommands(task.TaskId, instrument, orderSide, offsetType, orderQty, orderPrice, "反手合约"); Debug.Assert(commandList != null && commandList.Count > 0); foreach (OrderCommand command in commandList) { bool orderResult = PlaceOrderForOrderCommand(command); if (orderResult) { secondSubTask.AddPositiveOrderBook(command.CreateOrignalOrderBook()); task.UpdateTaskState(); //task.TaskState = ArbitrageTaskState.FirstPlaceOrder; } } } secondSubTask.AddTryOrderCount(); // 下单累加1次 #endregion #region 通知 foreach (OrderCommand command in commandList) { AutoTraderNotice notice = CreateTraderNotice(AutoTraderNoticeType.Order, command.ToDescription()); SafeFireAutoTraderNotice(notice); WriteTraderNoticeLog(notice); } #endregion } return(false); }
/// <summary> /// 委托下单。 /// </summary> /// <param name="product">委托产品。</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 abstract USeOrderNum PlaceOrder(USeInstrument product, int qty, decimal price, USeOffsetType offsetType, USeOrderSide orderSide, out string error);
/// <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) { error = ""; System.Diagnostics.Debug.Assert(instrument != null); int orderNumValue = m_orderNumCreateor.Next(); USeOrderBook orderBook = new USeOrderBook(); orderBook.OrderNum = new TestOrderNum(orderNumValue); orderBook.Account = m_investorID; orderBook.Instrument = instrument; orderBook.OrderQty = qty; orderBook.OrderPrice = price; orderBook.TradeQty = 0; orderBook.TradeAmount = 0; orderBook.TradePrice = 0; orderBook.TradeFee = 0; orderBook.OrderStatus = USeOrderStatus.Unknown; orderBook.CancelQty = 0; orderBook.OrderSide = orderSide; orderBook.OffsetType = offsetType; orderBook.Memo = ""; orderBook.OrderTime = DateTime.Now; string error_orderInfo = string.Empty; VerfiyPlaceOrderToReturn(orderBook, out error_orderInfo); if (error_orderInfo == "开仓") { m_dataBuffer.OrderBookList.Add(orderBook); m_pushOrderBookList.Enqueue(orderBook); error = "Place Order Ok"; return(orderBook.OrderNum); } else if (error_orderInfo == "CloseSuccessed") { //开仓 orderBook.Memo = "平仓委托成功"; m_dataBuffer.OrderBookList.Add(orderBook); m_pushOrderBookList.Enqueue(orderBook); error = "Place Order Ok"; return(orderBook.OrderNum); } else { //平仓委托失败 orderBook.Memo = error_orderInfo; orderBook.OrderStatus = USeOrderStatus.BlankOrder; m_pushOrderBookList.Enqueue(orderBook); error = "Place Order Failed"; return(orderBook.OrderNum); } }
/// <summary> /// 平仓追单。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void WorkerDoWorkForCloseChaseOrder(object sender, DoWorkEventArgs e) { { AutoTraderNotice notice = CreateTraderNotice("平仓追单对齐操作"); SafeFireAutoTraderNotice(notice); WriteTraderNoticeLog(notice); } //开仓追单 //1.撤销掉当前所有未成交委托单 //2.检查不对齐欠缺仓位,对欠缺仓位进行开仓追单 //3.开仓以市价委托,尽量保证成交 Debug.Assert(m_arbitrageOrder.State == ArbitrageOrderState.Closeing); if (m_arbitrageOrder.HasUnFinishOrderBook) { string text = "平仓追单有未完成委托单正在撤单"; AutoTraderNotice notice = CreateTraderNotice(AutoTraderNoticeType.Order, text); SafeFireAutoTraderNotice(notice); WriteTraderNoticeLog(notice); List <USeOrderBook> unFinishOrderBook = m_arbitrageOrder.GetAllUnfinishOrderBooks(); foreach (USeOrderBook orderBook in unFinishOrderBook) { string errorMessage = string.Empty; bool cancelResult = m_orderDriver.CancelOrder(orderBook.OrderNum, orderBook.Instrument, out errorMessage); if (cancelResult == false) { text = string.Format("平仓追单{0} 撤单失败", orderBook.OrderNum); notice = CreateTraderNotice(AutoTraderNoticeType.Order, text); SafeFireAutoTraderNotice(notice); WriteTraderNoticeLog(notice); return; // 退出流程,触发预警 } } text = "平仓追单操作完成,等待撤单成功"; notice = CreateTraderNotice(AutoTraderNoticeType.Order, text); SafeFireAutoTraderNotice(notice); WriteTraderNoticeLog(notice); while (true) { //等待撤单完成 m_operatorEvent.WaitOne(EVENT_WAIT_Time); if (m_backgroundRunFlag == false) { text = string.Format("平仓追单流程退出"); notice = CreateTraderNotice(AutoTraderNoticeType.Infomation, text); SafeFireAutoTraderNotice(notice); WriteTraderNoticeLog(notice); return; } if (m_arbitrageOrder.HasUnFinishOrderBook == false) { text = string.Format("平仓追单已完成撤单"); notice = CreateTraderNotice(AutoTraderNoticeType.Order, text); SafeFireAutoTraderNotice(notice); WriteTraderNoticeLog(notice); break; } } } List <OrderCommand> commandList = new List <OrderCommand>(); // 对欠缺仓位进行补单 foreach (ArbitrageTask task in m_arbitrageOrder.CloseTaskGroup.TaskList) { if (task.FirstSubTask.TradeQty == task.SecondSubTask.TradeQty) { continue; } Debug.Assert(task.FirstSubTask.TradeQty > task.SecondSubTask.TradeQty); //追单 USeInstrument instrument = task.SecondSubTask.Instrument; USeOrderSide orderSide = task.SecondSubTask.OrderSide; int orderQty = task.FirstSubTask.TradeQty - task.SecondSubTask.TradeQty; Debug.Assert(orderQty > 0); decimal orderPrice = GetFirstInstrumentOrderPrice(instrument, ArbitrageOrderPriceType.OpponentPrice, orderSide); Debug.Assert(orderPrice > 0); USeOffsetType offsetType = USeOffsetType.Close; List <OrderCommand> subCommandList = CreateOrderCommands(task.TaskId, instrument, orderSide, offsetType, orderQty, orderPrice, "平仓追单"); foreach (OrderCommand command in subCommandList) { bool orderResult = PlaceOrderForOrderCommand(command); if (orderResult) { task.SecondSubTask.AddPositiveOrderBook(command.CreateOrignalOrderBook()); task.UpdateTaskState(); //task.TaskState = ArbitrageTaskState.FirstPlaceOrder; } } commandList.AddRange(subCommandList); } #region 通知 foreach (OrderCommand command in commandList) { AutoTraderNotice notice = CreateTraderNotice(AutoTraderNoticeType.Order, command.ToDescription()); SafeFireAutoTraderNotice(notice); WriteTraderNoticeLog(notice); } #endregion { string text = "平仓追单已完成追单,等待成交"; AutoTraderNotice notice = CreateTraderNotice(AutoTraderNoticeType.Order, text); SafeFireAutoTraderNotice(notice); WriteTraderNoticeLog(notice); } }
/// <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); } }