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