/// <summary> /// 开始平仓。 /// </summary> public void BeginClose() { lock (m_syncObj) { Debug.Assert(m_arbitrageOrder.Argument != null); Debug.Assert(m_arbitrageOrder.Argument.CloseArg != null); //Debug.Assert(m_arbitrageOrder.Argument.StopLossArg != null); if (m_arbitrageOrder.State != ArbitrageOrderState.Opened) { throw new Exception(string.Format("{0}为{1}状态,不能进入平仓状态", this, m_arbitrageOrder.State.ToDescription())); } string errorMessage = string.Empty; if (VerfiyArbitrageArgument(m_arbitrageOrder.Argument, out errorMessage) == false) { throw new Exception(string.Format("{0}平仓参数错误,{1}", this, errorMessage)); } //创建平仓任务组 ArbitrageTaskGroup closeTaskGroup = CreateCloseTaskGroup(m_arbitrageOrder.OpenTaskGroup, m_arbitrageOrder.Argument); m_arbitrageOrder.CloseTaskGroup = closeTaskGroup; m_arbitrageOrder.State = ArbitrageOrderState.Closeing; } m_operatorEvent.Set(); SafeFireArbitrageOrderChanged(); string text = "进入平仓流程"; AutoTraderNotice notice = CreateTraderNotice(text); SafeFireAutoTraderNotice(notice); WriteTraderNoticeLog(notice); }
/// <summary> /// 展示开仓信息。 /// </summary> /// <param name="arbitrageOrder"></param> private void ShowOpenInfo(USeArbitrageOrder arbitrageOrder) { Debug.Assert(arbitrageOrder.OpenArgument != null); Debug.Assert(arbitrageOrder.OpenTaskGroup != null); this.panelTop.BackColor = Color.FromArgb(255, 255, 192); this.panelPriceSpread.BackColor = Color.FromArgb(255, 255, 192); ArbitrageTaskGroup taskGroup = arbitrageOrder.OpenTaskGroup; this.lblAlias.Text = arbitrageOrder.Alias; if (taskGroup.BuyInstrument != null) { this.lblBuyInstrument.Text = taskGroup.BuyInstrument.InstrumentCode; } else { this.lblBuyInstrument.Text = "---"; } if (taskGroup.SellInstrument != null) { this.lblSellInstrument.Text = taskGroup.SellInstrument.InstrumentCode; } else { this.lblSellInstrument.Text = "---"; } this.lblBuyTradeInfo.Text = string.Format("{0}/{1}", taskGroup.BuySubTaskTradeQty, taskGroup.BuySubTaskPlanOrderQty); this.lblBuyInstrmentOpenAvgPrice.Text = taskGroup.BuySubTaskAvgTradePrice.ToString(); this.lblSellTradeInfo.Text = string.Format("{0}/{1}", taskGroup.SellSubTaskTradeQty, taskGroup.SellSubTaskPlanOrderQty); this.lblSellInstrmentOpenAvgPrice.Text = taskGroup.SellSubTaskAvgTradePrice.ToString(); }
private void SetTaskDataSource(ArbitrageTaskGroup taskGroup) { BindingList <ArbitrageSubTaskViewModel> list = new BindingList <ArbitrageSubTaskViewModel>(); if (taskGroup != null && taskGroup.TaskList != null) { foreach (ArbitrageTask task in taskGroup.TaskList) { ArbitrageSubTaskViewModel firstTaskVm = new ArbitrageSubTaskViewModel() { TaskId = task.TaskId, OrderSide = task.FirstSubTask.OrderSide, Instrument = task.FirstSubTask.Instrument, PlanOrderQty = task.FirstSubTask.PlanOrderQty, OrderQty = task.FirstSubTask.OrderQty, TradeQty = task.FirstSubTask.TradeQty }; list.Add(firstTaskVm); ArbitrageSubTaskViewModel secondTaskVm = new ArbitrageSubTaskViewModel() { TaskId = task.TaskId, OrderSide = task.SecondSubTask.OrderSide, Instrument = task.SecondSubTask.Instrument, PlanOrderQty = task.SecondSubTask.PlanOrderQty, OrderQty = task.SecondSubTask.OrderQty, TradeQty = task.SecondSubTask.TradeQty }; list.Add(secondTaskVm); } } this.gridTask.DataSource = list; }
/// <summary> /// 计算平仓损益。 /// </summary> /// <param name="arbitrageOrder"></param> /// <returns></returns> private ProfitResult CalculatCloseProfit(USeArbitrageOrder arbitrageOrder) { USeOrderDriver orderDriver = USeManager.Instance.OrderDriver; USeQuoteDriver quoteDriver = USeManager.Instance.QuoteDriver; Debug.Assert(orderDriver != null); Debug.Assert(quoteDriver != null); ArbitrageTaskGroup closeTaskGroup = arbitrageOrder.CloseTaskGroup; List <USeOrderBook> orderBookList = arbitrageOrder.GetAllOrderBooks(); USeMarketData buyMarketData = USeManager.Instance.QuoteDriver.Query(closeTaskGroup.BuyInstrument); USeMarketData sellMarketData = USeManager.Instance.QuoteDriver.Query(closeTaskGroup.SellInstrument); USeInstrumentDetail buyInstrumentDetail = USeManager.Instance.OrderDriver.QueryInstrumentDetail(closeTaskGroup.BuyInstrument); USeInstrumentDetail sellInstrumentDetail = USeManager.Instance.OrderDriver.QueryInstrumentDetail(closeTaskGroup.SellInstrument); decimal buyProfit = CalculateProfitByOrderBook(orderBookList, buyInstrumentDetail, buyMarketData); decimal sellProfit = CalculateProfitByOrderBook(orderBookList, sellInstrumentDetail, sellMarketData); decimal totalProfit = buyProfit + sellProfit; ProfitResult result = new ProfitResult() { BuyProfit = buyProfit, SellProfit = sellProfit }; return(result); }
/// <summary> /// 创建任务列表。 /// </summary> /// <returns></returns> private DataTable CreateTaskTable(string tableName, ArbitrageTaskGroup taskGroup) { DataTable table = new DataTable(); table.TableName = tableName; table.Columns.Add("Direction", typeof(string)); table.Columns.Add("Instrument", typeof(USeInstrument)); if (taskGroup != null && taskGroup.TaskCount > 0) { for (int i = 0; i < taskGroup.TaskCount; i++) { table.Columns.Add(string.Format("任务{0}", (i + 1)), typeof(OrderTaskResult)); } } DataRow buyRow = table.NewRow(); buyRow["Direction"] = "买入"; buyRow["Instrument"] = taskGroup.BuyInstrument; DataRow sellRow = table.NewRow(); sellRow["Direction"] = "卖出"; sellRow["Instrument"] = taskGroup.SellInstrument; foreach (DataColumn column in table.Columns) { if (column.ColumnName.StartsWith("任务") == false) { continue; } buyRow[column] = new OrderTaskResult(); sellRow[column] = new OrderTaskResult(); } if (taskGroup.PreferentialSide == USeOrderSide.Buy) { table.Rows.Add(buyRow); table.Rows.Add(sellRow); } else if (taskGroup.PreferentialSide == USeOrderSide.Sell) { table.Rows.Add(sellRow); table.Rows.Add(buyRow); } else { Debug.Assert(false); } return(table); }
private static ArbitrageTaskGroup CreateTaskGroup() { //买入合约开仓任务组 ArbitrageTaskGroup group = new ArbitrageTaskGroup(); //group.Instrument = new USeInstrument("IF1710", "股指1710", USeMarket.CFFE); //group.OrderSide = USeOrderSide.Sell; List <ArbitrageTask> taskList = new List <ArbitrageTask>(); taskList.Add(CreateTask()); group.TaskList = taskList; return(group); }
/// <summary> /// 展示平仓信息。 /// </summary> /// <param name="arbitrageOrder"></param> private void ShowCloseInfo(USeArbitrageOrder arbitrageOrder) { Debug.Assert(arbitrageOrder.CloseArgument != null); Debug.Assert(arbitrageOrder.CloseTaskGroup != null); this.panelTop.BackColor = System.Drawing.Color.AliceBlue; this.panelPriceSpread.BackColor = System.Drawing.Color.AliceBlue; ArbitrageTaskGroup closeTaskGroup = arbitrageOrder.CloseTaskGroup; this.lblAlias.Text = arbitrageOrder.Alias; this.lblBuyInstrument.Text = closeTaskGroup.BuyInstrument.InstrumentCode; this.lblSellInstrument.Text = closeTaskGroup.SellInstrument.InstrumentCode; this.lblBuyTradeInfo.Text = string.Format("{0}/{1}", closeTaskGroup.BuySubTaskTradeQty, closeTaskGroup.BuySubTaskPlanOrderQty); this.lblBuyInstrmentOpenAvgPrice.Text = closeTaskGroup.BuySubTaskAvgTradePrice.ToString(); this.lblSellTradeInfo.Text = string.Format("{0}/{1}", closeTaskGroup.SellSubTaskTradeQty, closeTaskGroup.SellSubTaskPlanOrderQty); this.lblSellInstrmentOpenAvgPrice.Text = closeTaskGroup.SellSubTaskAvgTradePrice.ToString(); }
private void SetOrderBookDataSource(ArbitrageTaskGroup taskGroup) { BindingList <ArbitrageTaskOrderBookViewModel> list = new BindingList <ArbitrageTaskOrderBookViewModel>(); if (taskGroup != null && taskGroup.TaskList != null) { foreach (ArbitrageTask task in taskGroup.TaskList) { foreach (USeOrderBook orderBook in task.FirstSubTask.OrderBooks) { list.Add(CreateOrderBookVm(orderBook, task.TaskId)); } foreach (USeOrderBook orderBook in task.SecondSubTask.OrderBooks) { list.Add(CreateOrderBookVm(orderBook, task.TaskId)); } } } this.gridOrderBook.DataSource = list; }
/// <summary> /// 克隆方法。 /// </summary> /// <returns></returns> public ArbitrageTaskGroup Clone() { ArbitrageTaskGroup entity = new ArbitrageTaskGroup(); entity.OpenCloseType = this.OpenCloseType; entity.BuyInstrument = this.BuyInstrument == null ? null : this.BuyInstrument.Clone(); entity.SellInstrument = this.SellInstrument == null ? null : this.SellInstrument.Clone(); entity.BuyInstrumentOrderPriceType = this.BuyInstrumentOrderPriceType; entity.SellInstrumentOrderPriceType = this.SellInstrumentOrderPriceType; entity.OperationSide = this.OperationSide; entity.PreferentialSide = this.PreferentialSide; List <ArbitrageTask> taskList = new List <ArbitrageTask>(); foreach (ArbitrageTask taskItem in m_taskList) { taskList.Add(taskItem.Clone()); } entity.m_taskList = taskList; return(entity); }
private void FillTaskTable(DataTable table, ArbitrageTaskGroup taskGroup) { if (taskGroup == null) { //Debug.Assert(false); return; } Debug.Assert(taskGroup.TaskCount == table.Columns.Count - 2); Debug.Assert(table.Rows.Count == 2); DataRow firstRow = table.Rows[0]; DataRow secondRow = table.Rows[1]; foreach (ArbitrageTask task in taskGroup.TaskList) { string cloumnName = string.Format("任务{0}", task.TaskId); { OrderTaskResult firstResult = new OrderTaskResult(); firstResult.PlanOrderQty = task.FirstSubTask.PlanOrderQty; firstResult.OrderQty = task.FirstSubTask.OrderQty; firstResult.TradeQty = task.FirstSubTask.TradeQty; firstResult.AvgTradePrice = task.FirstSubTask.TradeAvgPrice; firstRow[cloumnName] = firstResult; } { OrderTaskResult secondResult = new OrderTaskResult(); secondResult.PlanOrderQty = task.SecondSubTask.PlanOrderQty; secondResult.OrderQty = task.SecondSubTask.OrderQty; secondResult.TradeQty = task.SecondSubTask.TradeQty; secondResult.AvgTradePrice = task.SecondSubTask.TradeAvgPrice; secondRow[cloumnName] = secondResult; } } }
/// <summary> /// 设定流程进入开仓流程。 /// </summary> public void BeginOpen() { lock (m_syncObj) { if (m_arbitrageOrder.OpenArgument == null) { throw new Exception(string.Format("{0}开仓参数未设定", this)); } if (m_arbitrageOrder.State != ArbitrageOrderState.None) { throw new Exception(string.Format("{0}为{1}状态,不能进入开仓状态", this, m_arbitrageOrder.State.ToDescription())); } string errorMessage = string.Empty; if (VerfiyOpenArgument(m_arbitrageOrder.OpenArgument, out errorMessage) == false) { throw new Exception(string.Format("{0}开仓参数错误,{1}", this, errorMessage)); } //创建开仓任务组 ArbitrageTaskGroup openTaskGroup = CreateOpenTaskGroup(m_arbitrageOrder.Argument); m_arbitrageOrder.OpenTaskGroup = openTaskGroup; m_arbitrageOrder.State = ArbitrageOrderState.Opening; } m_operatorEvent.Set(); SafeFireArbitrageOrderChanged(); string text = "进入开仓流程"; AutoTraderNotice notice = CreateTraderNotice(text); SafeFireAutoTraderNotice(notice); WriteTraderNoticeLog(notice); }
/// <summary> /// 创建开仓任务组。 /// </summary> /// <param name="openArg">开仓参数。</param> /// <returns></returns> private static ArbitrageTaskGroup CreateOpenTaskGroup(ArbitrageArgument argument) { ArbitrageOpenArgument openArg = argument.OpenArg; USeInstrument firstInstrument = null; USeInstrument secondInstrument = null; USeOrderSide firstOrderSide = USeOrderSide.Buy; USeOrderSide secondOrderSide = USeOrderSide.Sell; ArbitrageOrderPriceType firstOrderPriceType = ArbitrageOrderPriceType.Unknown; ArbitrageOrderPriceType secondOrderPriceType = ArbitrageOrderPriceType.Unknown; if (openArg.PreferentialSide == USeOrderSide.Buy) { //优先买入 firstInstrument = openArg.BuyInstrument; firstOrderSide = USeOrderSide.Buy; firstOrderPriceType = openArg.BuyInstrumentOrderPriceType; secondInstrument = openArg.SellInstrument; secondOrderSide = USeOrderSide.Sell; secondOrderPriceType = openArg.SellInstrumentOrderPriceType; } else if (openArg.PreferentialSide == USeOrderSide.Sell) { //优先卖出 firstInstrument = openArg.SellInstrument; firstOrderSide = USeOrderSide.Sell; firstOrderPriceType = openArg.SellInstrumentOrderPriceType; secondInstrument = openArg.BuyInstrument; secondOrderSide = USeOrderSide.Buy; secondOrderPriceType = openArg.BuyInstrumentOrderPriceType; } else { Debug.Assert(false); } Debug.Assert(openArg.OrderQtyUint > 0); int taskCount = openArg.TotalOrderQty / openArg.OrderQtyUint; if ((openArg.TotalOrderQty % openArg.OrderQtyUint) > 0) { taskCount += 1; } #region 构造任务组 ArbitrageTaskGroup taskGroup = new ArbitrageTaskGroup(); taskGroup.OpenCloseType = OpenCloseType.Open; taskGroup.BuyInstrument = openArg.BuyInstrument; taskGroup.SellInstrument = openArg.SellInstrument; taskGroup.BuyInstrumentOrderPriceType = openArg.BuyInstrumentOrderPriceType; taskGroup.SellInstrumentOrderPriceType = openArg.SellInstrumentOrderPriceType; taskGroup.OperationSide = argument.OperationSide; taskGroup.PreferentialSide = openArg.PreferentialSide; List <ArbitrageTask> taskList = new List <ArbitrageTask>(); int remainPlanQty = openArg.TotalOrderQty; for (int i = 1; i <= taskCount; i++) { int planOrderQty = Math.Min(openArg.OrderQtyUint, remainPlanQty); Debug.Assert(planOrderQty > 0 && planOrderQty <= openArg.OrderQtyUint); remainPlanQty -= planOrderQty; ArbitrageTask task = new ArbitrageTask(); task.TaskId = i; task.TaskState = ArbitrageTaskState.None; ArbitrageSubTask firstSubTask = new ArbitrageSubTask() { Instrument = firstInstrument, OrderPriceType = firstOrderPriceType, OrderSide = firstOrderSide, PlanOrderQty = planOrderQty, OffsetType = USeOffsetType.Open, }; ArbitrageSubTask secondSubTask = new ArbitrageSubTask() { Instrument = secondInstrument, OrderPriceType = secondOrderPriceType, OrderSide = secondOrderSide, PlanOrderQty = planOrderQty, OffsetType = USeOffsetType.Open }; task.FirstSubTask = firstSubTask; task.SecondSubTask = secondSubTask; taskList.Add(task); } Debug.Assert(remainPlanQty == 0); taskGroup.TaskList = taskList; #endregion return(taskGroup); }
/// <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); }
public void SetData(ArbitrageTaskGroup taskGroup) { m_taskGroup = taskGroup; }
///// <summary> ///// 绘制任务。 ///// </summary> ///// <param name="g"></param> //private void DrawTaskList_2(Graphics g) //{ // ArbitrageTaskGroup taskGroup = m_taskGroup; // float xBegin = 35.0f; // float yBegin = 10.0f; // List<ArbitrageTask> taskList = taskGroup.TaskList; // if (taskList != null && taskList.Count > 0) // { // for (int i = 0; i < taskList.Count; i++) // { // ArbitrageTask task = taskList[i]; // float x = xBegin + (i * m_itemInterval); // float y = yBegin; // ArbitrageSubTask firstSubTask = task.FirstSubTask; // ArbitrageSubTask secondSubTask = task.SecondSubTask; // //优先任务 // Brush firstTaskBrush = m_taskNoExceuctBrush; // if (firstSubTask.TradeQty == firstSubTask.PlanOrderQty) // { // firstTaskBrush = m_taskFinishBrush; // } // else if (firstSubTask.OrderQty > 0) // { // firstTaskBrush = m_taskInExecuteBrush; // } // else // { // firstTaskBrush = m_taskNoExceuctBrush; // } // g.FillEllipse(firstTaskBrush, x, y, m_taskDotWidth, m_taskDotHeight); // g.DrawString(string.Format("{0}/{1}", firstSubTask.TradeQty, firstSubTask.PlanOrderQty), // m_font, firstTaskBrush, new RectangleF(x + m_taskDotWidth / 2 - 15, y + 13, 30, 10), m_centerStringFormat); // //反手任务 // Brush secondTaskBrush = m_taskNoExceuctBrush; // if (secondSubTask.TradeQty == secondSubTask.PlanOrderQty) // { // secondTaskBrush = m_taskFinishBrush; // } // else if (secondSubTask.OrderQty > 0) // { // secondTaskBrush = m_taskInExecuteBrush; // } // else // { // secondTaskBrush = m_taskNoExceuctBrush; // } // //反手任务 // g.FillEllipse(secondTaskBrush, x, y + 30, m_taskDotWidth, m_taskDotHeight); // g.DrawString(string.Format("{0}/{1}", secondSubTask.TradeQty, secondSubTask.PlanOrderQty), // m_font, secondTaskBrush, new RectangleF(x + m_taskDotWidth / 2 - 15, y + 30 + 13, 30, 10), m_centerStringFormat); // } // } //} private void DrawTaskList(Graphics g) { float xBegin = 45.0f; // 起始x坐标 float yBegin = 10.0f; // 起始y坐标 float y_f_NegativeQtyOffset = 0; // 优先任务反手量偏移位置 float y_f_taskOffset = 13f; // 优先任务主图标偏移位置 float y_f_QtyOffset = 26f; // 优先任务正手量偏移位置 float y_s_taskOffset = 45f; // 反手任务主图标偏移位置 float y_s_QtyOffset = 58f; // 反手任务正手量偏移位置 ArbitrageTaskGroup taskGroup = m_taskGroup; List <ArbitrageTask> taskList = taskGroup.TaskList; if (taskList == null || taskList.Count <= 0) { return; } for (int i = 0; i < taskList.Count; i++) { ArbitrageTask task = taskList[i]; float x = xBegin + (i * m_itemInterval); float y = yBegin; ArbitrageSubTask firstSubTask = task.FirstSubTask; ArbitrageSubTask secondSubTask = task.SecondSubTask; Brush firstTaskBrush = GetSubTaskBrush(firstSubTask); Brush secondTaskBrush = GetSubTaskBrush(secondSubTask); Pen tmpPen = new Pen(Color.Red); //优先合约反向委托量 if (firstSubTask.NegativeOrderQty > 0) //if (i == 2) { float rectWidth = 30f; float rectHeight = 10f; RectangleF rect = new RectangleF(x - (rectWidth / 2), y + y_f_NegativeQtyOffset, rectWidth, rectHeight); string text = string.Format("{0}/{1}", firstSubTask.NegativeTradeQty, firstSubTask.NegativeOrderQty); g.DrawString(text, m_negativeFont, m_negativeTaskBrush, rect, m_centerStringFormat); } //优先任务点 g.FillEllipse(firstTaskBrush, x - m_taskDotDiameter / 2, y + y_f_taskOffset, m_taskDotDiameter, m_taskDotDiameter); //g.DrawRectangle(tmpPen, x, y + f_y_taskOffset, m_taskDotWidth, m_taskDotHeight); { float rectWidth = 30f; float rectHeight = 10f; RectangleF rect = new RectangleF(x - rectWidth / 2, y + y_f_QtyOffset, rectWidth, rectHeight); string text = string.Format("{0}/{1}", firstSubTask.TradeQty, firstSubTask.PlanOrderQty); g.DrawString(text, m_font, firstTaskBrush, rect, m_centerStringFormat); } //反手任务点 g.FillEllipse(secondTaskBrush, x - m_taskDotDiameter / 2, y + y_s_taskOffset, m_taskDotDiameter, m_taskDotDiameter); //g.DrawRectangle(tmpPen, x, y + s_y_taskOffset, m_taskDotWidth, m_taskDotHeight); { float rectWidth = 30f; float rectHeight = 10f; RectangleF rect = new RectangleF(x - rectWidth / 2, y + y_s_QtyOffset, rectWidth, rectHeight); string text = string.Format("{0}/{1}", secondSubTask.TradeQty, secondSubTask.PlanOrderQty); g.DrawString(text, m_font, secondTaskBrush, rect, m_centerStringFormat); } } }
/// <summary> /// 创建平仓任务组。 /// </summary> /// <param name="openTaskGroup">开仓任务组。</param> /// <param name="closeArg">平仓参数。</param> /// <returns></returns> private ArbitrageTaskGroup CreateCloseTaskGroup(ArbitrageTaskGroup openTaskGroup, ArbitrageArgument argument) { ArbitrageCloseArgument closeArg = argument.CloseArg; Debug.Assert(openTaskGroup.BuyInstrument == closeArg.SellInstrument); Debug.Assert(openTaskGroup.SellInstrument == closeArg.BuyInstrument); int buyPosition = openTaskGroup.SellSubTaskTradeQty; // 平仓买入量 = 开仓卖出量 int sellPosition = openTaskGroup.BuySubTaskTradeQty; // 平仓卖出量 = 开仓买入量 USeInstrument firstInstrument = null; USeInstrument secondInstrument = null; USeOrderSide firstOrderSide = USeOrderSide.Buy; USeOrderSide secondOrderSide = USeOrderSide.Sell; ArbitrageOrderPriceType firstOrderPriceType = ArbitrageOrderPriceType.Unknown; ArbitrageOrderPriceType secondOrderPriceType = ArbitrageOrderPriceType.Unknown; int firstPosition = 0; int secondPosition = 0; if (closeArg.PreferentialSide == USeOrderSide.Buy) { //优先买入 firstInstrument = closeArg.BuyInstrument; firstOrderSide = USeOrderSide.Buy; firstOrderPriceType = closeArg.BuyInstrumentOrderPriceType; secondInstrument = closeArg.SellInstrument; secondOrderSide = USeOrderSide.Sell; secondOrderPriceType = closeArg.SellInstrumentOrderPriceType; firstPosition = buyPosition; secondPosition = sellPosition; } else if (closeArg.PreferentialSide == USeOrderSide.Sell) { //优先卖出 firstInstrument = closeArg.SellInstrument; firstOrderSide = USeOrderSide.Sell; firstOrderPriceType = closeArg.SellInstrumentOrderPriceType; secondInstrument = closeArg.BuyInstrument; secondOrderSide = USeOrderSide.Buy; secondOrderPriceType = closeArg.BuyInstrumentOrderPriceType; firstPosition = sellPosition; secondPosition = buyPosition; } else { Debug.Assert(false); } Debug.Assert(closeArg.OrderQtyUint > 0); int maxPositon = Math.Max(buyPosition, sellPosition); int taskCount = maxPositon / closeArg.OrderQtyUint; if ((maxPositon % closeArg.OrderQtyUint) > 0) { taskCount += 1; } #region 构造任务组 ArbitrageTaskGroup taskGroup = new ArbitrageTaskGroup(); taskGroup.OpenCloseType = OpenCloseType.Close; taskGroup.BuyInstrument = closeArg.BuyInstrument; taskGroup.SellInstrument = closeArg.SellInstrument; taskGroup.BuyInstrumentOrderPriceType = closeArg.BuyInstrumentOrderPriceType; taskGroup.SellInstrumentOrderPriceType = closeArg.SellInstrumentOrderPriceType; taskGroup.OperationSide = argument.OperationSide.GetOppositeSide(); taskGroup.PreferentialSide = closeArg.PreferentialSide; List <ArbitrageTask> taskList = new List <ArbitrageTask>(); int remainFirstPlanQty = firstPosition; int remainSecondPlanQty = secondPosition; for (int i = 1; i <= taskCount; i++) { int firstPlanOrderQty = Math.Min(closeArg.OrderQtyUint, remainFirstPlanQty); remainFirstPlanQty -= firstPlanOrderQty; int secondPlanOrderQty = Math.Min(closeArg.OrderQtyUint, remainSecondPlanQty); remainSecondPlanQty -= secondPlanOrderQty; ArbitrageTask task = new ArbitrageTask(); task.TaskId = i; task.TaskState = ArbitrageTaskState.None; ArbitrageSubTask firstSubTask = new ArbitrageSubTask() { Instrument = firstInstrument, OrderPriceType = firstOrderPriceType, OrderSide = firstOrderSide, PlanOrderQty = firstPlanOrderQty, OffsetType = USeOffsetType.Close, }; ArbitrageSubTask secondSubTask = new ArbitrageSubTask() { Instrument = secondInstrument, OrderPriceType = secondOrderPriceType, OrderSide = secondOrderSide, PlanOrderQty = secondPlanOrderQty, OffsetType = USeOffsetType.Close }; task.FirstSubTask = firstSubTask; task.SecondSubTask = secondSubTask; taskList.Add(task); } Debug.Assert(remainFirstPlanQty == 0); Debug.Assert(remainSecondPlanQty == 0); taskGroup.TaskList = taskList; #endregion return(taskGroup); }
private ArbitrageTaskGroup m_closeTaskGroup = null; // 平仓任务组 #endregion #region 构造方法 public USeArbitrageOrder() { this.TraderIdentify = Guid.Empty; m_openTaskGroup = new ArbitrageTaskGroup(); m_closeTaskGroup = new ArbitrageTaskGroup(); }
public void SetDataSource(ArbitrageTaskGroup taskGroup) { SetTaskDataSource(taskGroup); SetOrderBookDataSource(taskGroup); }