Exemple #1
0
        /// <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);
        }
Exemple #6
0
        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;
        }
Exemple #9
0
        /// <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;
                }
            }
        }
Exemple #11
0
        /// <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);
        }
Exemple #18
0
        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);
 }