public static PriceSpreadCheckResult CreateNoOrderResult() { PriceSpreadCheckResult result = new PriceSpreadCheckResult(); result.OrderReason = TaskOrderReason.None; result.PriceSpreadThreshold = 0; return(result); }
/// <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> /// <returns></returns> private PriceSpreadCheckResult CheckPriceSpread(OpenCloseType openCloseType, ArbitrageArgument argument) { USeMarketData nearMarketData = m_quoteDriver.Query(argument.NearInstrument); USeMarketData farMarketData = m_quoteDriver.Query(argument.FarInstrument); decimal nearPrice = 0m; decimal farPrice = 0m; if (openCloseType == OpenCloseType.Open) { nearPrice = GetMarketPrice(nearMarketData, argument.OpenArg.NearOrderPriceType); farPrice = GetMarketPrice(farMarketData, argument.OpenArg.FarOrderPriceType); } else if (openCloseType == OpenCloseType.Close) { nearPrice = GetMarketPrice(nearMarketData, argument.CloseArg.NearOrderPriceType); farPrice = GetMarketPrice(farMarketData, argument.CloseArg.FarOrderPriceType); } else { Debug.Assert(false); return(PriceSpreadCheckResult.CreateNoOrderResult()); } if (nearPrice <= 0 || farPrice <= 0) { return(PriceSpreadCheckResult.CreateNoOrderResult()); } decimal priceSpread = nearPrice - farPrice; if (openCloseType == OpenCloseType.Open) { Debug.Assert(argument.OpenArg != null && argument.OpenArg.OpenCondition != null); if (IsInPriceSpread(argument.OpenArg.OpenCondition, priceSpread)) { PriceSpreadCheckResult result = new PriceSpreadCheckResult(); result.OrderReason = TaskOrderReason.Open; result.PriceSpreadThreshold = argument.OpenArg.OpenCondition.PriceSpreadThreshold; return(result); } } else if (openCloseType == OpenCloseType.Close) { Debug.Assert(argument.CloseArg != null && argument.CloseArg.CloseCondition != null); if (argument.CloseArg != null && argument.CloseArg.CloseCondition != null) { if (IsInPriceSpread(argument.CloseArg.CloseCondition, priceSpread)) { PriceSpreadCheckResult result = new PriceSpreadCheckResult(); result.OrderReason = TaskOrderReason.Close; result.PriceSpreadThreshold = argument.CloseArg.CloseCondition.PriceSpreadThreshold; return(result); } } if (argument.StopLossArg != null && argument.StopLossArg.StopLossCondition != null) { if (IsInPriceSpread(argument.StopLossArg.StopLossCondition, priceSpread)) { PriceSpreadCheckResult result = new PriceSpreadCheckResult(); result.OrderReason = TaskOrderReason.StopLoss; result.PriceSpreadThreshold = argument.StopLossArg.StopLossCondition.PriceSpreadThreshold; return(result); } } } return(PriceSpreadCheckResult.CreateNoOrderResult()); }