Example #1
0
        // 这里假设已经挂的单子已经是按最优数量进行处理过,目标是直接挂单
        // 目前对前两层做智能开平,后面的全用开仓单
        // 因为后面的使用平仓单,还要处理复杂的大量开挂单的问题。
        // 实际上不能太深,因为深了占用资金
        public int 补单(OrderBook_OneSide_Order buy1, OrderBook_OneSide_Size buy2)
        {
            int cnt = 0;

            // 方向不对,不可能补单
            if (buy1.Side != buy2.Side)
            {
                return(cnt);
            }

            int l = 0;

            // 由于在别的地方做了撤单,在这buy2中的数量是大于buy1的
            foreach (var b2 in buy2.Grid)
            {
                ++l;
                int    level = b2.Key;
                double size  = b2.Value;

                // 要补单的数量
                double leave = size - buy1.SizeByLevel(level);
                if (leave <= 0)
                {
                    continue;
                }

                double price = PriceHelper.GetPriceByLevel(level);
                cnt += (int)leave;

                // 超过两层的全用开仓
                if (l > 2)
                {
                    SendLimitOrder(buy2.Side, leave, price,
                                   OpenCloseHelper.GetOpenCloseString(EnumOpenClose.OPEN));
                    continue;
                }

                // 应当对容易平仓的位置进行平仓
                // 这个地方要测试一个,我只有10持仓,先挂10手平,第二个价格再挂自动生成的单是平还是开?检查数据计算是否正确
                // 补单是一次性的,还是分两笔,还是分两笔吧
                //double canqty = DualPosition.CanCloseQty(buy2.Side);

                //// 检查平仓,如果补单限为一次,那就把此行注释
                //if (canqty > 0)
                //{
                //    double min = Math.Min(leave, canqty);
                //    leave -= min;
                //    SendLimitOrder(buy2.Side, min, price,
                //        OpenCloseHelper.GetOpenCloseString(EnumOpenClose.CLOSE_TODAY));
                //}

                if (leave > 0)
                {
                    //SendLimitOrder(buy2.Side, leave, price,
                    //    OpenCloseHelper.GetOpenCloseString(DualPosition.CanClose(buy2.Side, leave)));
                }
            }

            return(cnt);
        }
Example #2
0
        // 此部分是因为确信此位置上不会挂单,所以撤了
        public int 强行撤单部分(OrderBook_OneSide_Order buy1, OrderBook_OneSide_Size buy2)
        {
            int cnt = 0;



            return(cnt);
        }
Example #3
0
        // 检查对手,保证最不会自成交
        // 这次有可能把平仓单全撤了,剩下的全是开仓单,有些风险
        public int 单边防自成交(OrderBook_OneSide_Order sell, OrderBook_OneSide_Size buy)
        {
            int cnt = 0;

            // 同买卖是不可能自成交的
            if (sell.Side == buy.Side)
            {
                return(cnt);
            }

            // 还没有挂单,不会自成交
            if (sell.Count <= 0)
            {
                return(cnt);
            }

            // 对手单也是空的,不会自成交
            if (buy.Count <= 0)
            {
                return(cnt);
            }

            // 取对手单的最高价
            int level = buy.Grid.Keys[0];

            // 将挂单列表中的单子撤单
            foreach (var s in sell.Grid)
            {
                if (buy.Side == OrderSide.Buy)
                {
                    if (s.Key <= level)
                    {
                        cnt += sell.Cancel(s.Value);
                    }
                }
                else
                {
                    if (s.Key >= level)
                    {
                        cnt += sell.Cancel(s.Value);
                    }
                }
            }
            return(cnt);
        }
        // 其它层好办,关键在第一层,第一层要保证排队和开平
        // 没有竞争者就保证平仓

        // 在第一层时,把后面几层能平的仓先平了
        // 在第二层时,把

        // 如果第一层有开仓单,把后面所有的平仓全撤了
        // 如果第一层只有自己排队,把开仓单平了


        // 排队要排第一,然后平仓单向前挪,只撤超出部分
        // 前两层,数量超过得撤,先撤排后的,如果撤了后少于指定数就不撤
        // 后两层,只要是平仓单就撤,我没法区分平仓单啊
        public int 智能撤单逻辑(OrderBook_OneSide_Order buy1, OrderBook_OneSide_Size buy2)
        {
            List<Order> forCancel = new List<Order>();
            int cnt = 0;

            // 方向不对,不可能补单
            if (buy1.Side != buy2.Side)
                return cnt;

            lock(this)
            {
                // 撤单时按已有的挂单进行处理
                foreach (var b1 in buy1.GridList)
                {
                    int level = b1.Key;

                    double size2 = buy2.SizeByLevel(level);
                    if (size2 <= 0)
                    {
                        // 发现目标价上量为0,全撤
                        forCancel.AddRange(b1.Value);
                        //cancelList.UnionWith(b1.Value);
                        //cnt += buy1.Cancel(b1.Value);
                        continue;
                    }

                    double size1 = buy1.Size(b1.Value);
                    if (size1 <= size2)
                    {
                        // 量少于目标量,不动,等着补单
                        continue;
                    }

                    // 要撤单的量,实际上还剩的挂单量不由人为控制,所以这个地方可以多撤
                    double leave = size1 - size2;
                    // 现在这个价位上挂了很多单,是撤开仓,还是撤新挂的?
                    double count = 0;

                    // 这个地方会出错,只好重新复制一下
                    foreach (Order o in b1.Value.ToList())
                    {
                        count += o.LeavesQty;
                        if (count >= leave)
                            break;

                        forCancel.Add(o);
                        //cancelList.Add(o);
                        //o.Cancel();
                        //++cnt;
                    }
                }
            }

            foreach(var o in forCancel)
            {
                if (!o.IsDone)
                    o.Cancel();
                cancelList.Add(o);
                ++cnt;
            }

            return cnt;
        }
        // 这里假设已经挂的单子已经是按最优数量进行处理过,目标是直接挂单
        // 目前对前两层做智能开平,后面的全用开仓单
        // 因为后面的使用平仓单,还要处理复杂的大量开挂单的问题。
        // 实际上不能太深,因为深了占用资金
        public int 单边全面补单(OrderBook_OneSide_Order buy1, OrderBook_OneSide_Size buy2)
        {
            int cnt = 0;
            List<CopyOrder> list = new List<CopyOrder>();

            // 方向不对,不可能补单
            if (buy1.Side != buy2.Side)
                return cnt;

            TextCommon tp = buy1.Side == OrderSide.Buy ? TextParameterBid : TextParameterAsk;
            PositionRecord LongShort = buy1.Side == OrderSide.Buy ? base.DualPosition.Short : base.DualPosition.Long;

            lock(this)
            {
                int l = 0;
                // 由于在别的地方做了撤单,在这buy2中的数量是大于等于buy1的
                foreach (var b2 in buy2.GridList)
                {
                    ++l;
                    int level = b2.Key;
                    double size = b2.Value;

                    // 要补单的数量
                    double leave = size - buy1.SizeByLevel(level);
                    if (leave <= 0)
                        continue;

                    double price = PriceHelper.GetPriceByLevel(level);
                    cnt += (int)leave;

                    // 超过两层的全用开仓
                    if (l > AlwaysOpenIfDepthGreatThan)
                    {
                        tp.OpenClose = EnumOpenClose.OPEN;
                        tp.Text = string.Format("{0}层,开仓补单", l);
                    }
                    else
                    {
                        // 计算开平
                        double q = CloseTodayHelper.GetCloseAndQty(LongShort, out tp.OpenClose);
                        if (q < leave)
                        {
                            tp.OpenClose = EnumOpenClose.OPEN;
                            tp.Text = string.Format("开仓:可平量{0}<{1}", q, leave);
                        }
                        else
                        {
                            tp.Text = string.Format("平仓:可平量{0}>={1}", q, leave);
                        }
                    }


                    // 入场下单
                    // 在模拟下,这个地方有可能导致成交回报lock
                    //SendLimitOrder(buy2.Side, leave, price, tp.ToString());

                    list.Add(new CopyOrder() {
                        Side = buy2.Side,
                        Qty = leave,
                        Price = price,
                        Text = tp.ToString(),
                    });
                }
            }

            foreach(var o in list)
            {
                SendLimitOrder(o.Side, o.Qty, o.Price, o.Text);
            }

            return cnt;
        }
        // 检查对手,保证不会自成交
        // 这次有可能把平仓单全撤了,剩下的全是开仓单,有些风险
        public int 单边防自成交撤单(OrderBook_OneSide_Order sell, OrderBook_OneSide_Size buy)
        {
            int cnt = 0;
            List<Order> forCancel = new List<Order>();

            // 同买卖是不可能自成交的
            if (sell.Side == buy.Side)
                return cnt;

            // 还没有挂单,不会自成交
            if (sell.Count <= 0)
                return cnt;

            // 对手单也是空的,不会自成交
            if (buy.Count <= 0)
                return cnt;

            lock(this)
            {
                // 取对手单的最高价
                int level = buy.LevelByIndex(0);
                // 将挂单列表中的单子撤单
                // 将挂单列表中的单子撤单
                foreach (var s in sell.GridList)
                {
                    if (buy.Side == OrderSide.Buy)
                    {
                        if (s.Key <= level)
                        {
                            forCancel.AddRange(s.Value);
                            //cancelList.UnionWith(s.Value);
                            //cnt += sell.Cancel(s.Value);
                        }
                    }
                    else
                    {
                        if (s.Key >= level)
                        {
                            forCancel.AddRange(s.Value);
                            //cancelList.UnionWith(s.Value);
                            //cnt += sell.Cancel(s.Value);
                        }
                    }
                }
            }

            foreach (var o in forCancel)
            {
                if (!o.IsDone)
                    o.Cancel();
                cancelList.Add(o);
                ++cnt;
            }

            return cnt;
        }
        // 检查对手,保证最不会自成交
        // 这次有可能把平仓单全撤了,剩下的全是开仓单,有些风险
        public int 单边防自成交(OrderBook_OneSide_Order sell,OrderBook_OneSide_Size buy)
        {
            int cnt = 0;
            // 同买卖是不可能自成交的
            if(sell.Side == buy.Side)
                return cnt;

            // 还没有挂单,不会自成交
            if (sell.Count <= 0)
                return cnt;

            // 对手单也是空的,不会自成交
            if (buy.Count <= 0)
                return cnt;

            // 取对手单的最高价
            int level = buy.Grid.Keys[0];
            // 将挂单列表中的单子撤单
            foreach(var s in sell.Grid)
            {
                if (buy.Side == OrderSide.Buy)
                {
                    if (s.Key <= level)
                    {
                        cnt += sell.Cancel(s.Value);
                    }
                }
                else
                {
                    if (s.Key >= level)
                    {
                        cnt += sell.Cancel(s.Value);
                    }
                }
            }
            return cnt;
        }
        // 这里假设已经挂的单子已经是按最优数量进行处理过,目标是直接挂单
        // 目前对前两层做智能开平,后面的全用开仓单
        // 因为后面的使用平仓单,还要处理复杂的大量开挂单的问题。
        // 实际上不能太深,因为深了占用资金
        public int 补单(OrderBook_OneSide_Order buy1, OrderBook_OneSide_Size buy2)
        {
            int cnt = 0;
            // 方向不对,不可能补单
            if (buy1.Side != buy2.Side)
                return cnt;

            int l = 0;
            // 由于在别的地方做了撤单,在这buy2中的数量是大于buy1的
            foreach(var b2 in buy2.Grid)
            {
                ++l;
                int level = b2.Key;
                double size = b2.Value;

                // 要补单的数量
                double leave = size - buy1.SizeByLevel(level);
                if (leave <= 0)
                    continue;

                double price = PriceHelper.GetPriceByLevel(level);
                cnt += (int)leave;

                // 超过两层的全用开仓
                if (l > 2)
                {
                    SendLimitOrder(buy2.Side, leave, price,
                        OpenCloseHelper.GetOpenCloseString(EnumOpenClose.OPEN));
                    continue;
                }

                // 应当对容易平仓的位置进行平仓
                // 这个地方要测试一个,我只有10持仓,先挂10手平,第二个价格再挂自动生成的单是平还是开?检查数据计算是否正确
                // 补单是一次性的,还是分两笔,还是分两笔吧
                //double canqty = DualPosition.CanCloseQty(buy2.Side);

                //// 检查平仓,如果补单限为一次,那就把此行注释
                //if (canqty > 0)
                //{
                //    double min = Math.Min(leave, canqty);
                //    leave -= min;
                //    SendLimitOrder(buy2.Side, min, price,
                //        OpenCloseHelper.GetOpenCloseString(EnumOpenClose.CLOSE_TODAY));
                //}

                if (leave > 0)
                {
                    //SendLimitOrder(buy2.Side, leave, price,
                    //    OpenCloseHelper.GetOpenCloseString(DualPosition.CanClose(buy2.Side, leave)));
                }
            }

            return cnt;
        }
        // 此部分是因为确信此位置上不会挂单,所以撤了
        public int 强行撤单部分(OrderBook_OneSide_Order buy1, OrderBook_OneSide_Size buy2)
        {
            int cnt = 0;

            return cnt;
        }
Example #10
0
        // 其它层好办,关键在第一层,第一层要保证排队和开平
        // 没有竞争者就保证平仓

        // 在第一层时,把后面几层能平的仓先平了
        // 在第二层时,把

        // 如果第一层有开仓单,把后面所有的平仓全撤了
        // 如果第一层只有自己排队,把开仓单平了


        // 排队要排第一,然后平仓单向前挪,只撤超出部分
        // 前两层,数量超过得撤,先撤排后的,如果撤了后少于指定数就不撤
        // 后两层,只要是平仓单就撤,我没法区分平仓单啊
        public int 智能撤单逻辑(OrderBook_OneSide_Order buy1, OrderBook_OneSide_Size buy2)
        {
            List <Order> forCancel = new List <Order>();
            int          cnt       = 0;

            // 方向不对,不可能补单
            if (buy1.Side != buy2.Side)
            {
                return(cnt);
            }

            lock (this)
            {
                // 撤单时按已有的挂单进行处理
                foreach (var b1 in buy1.GridList)
                {
                    int level = b1.Key;

                    double size2 = buy2.SizeByLevel(level);
                    if (size2 <= 0)
                    {
                        // 发现目标价上量为0,全撤
                        forCancel.AddRange(b1.Value);
                        //cancelList.UnionWith(b1.Value);
                        //cnt += buy1.Cancel(b1.Value);
                        continue;
                    }

                    double size1 = buy1.Size(b1.Value);
                    if (size1 <= size2)
                    {
                        // 量少于目标量,不动,等着补单
                        continue;
                    }

                    // 要撤单的量,实际上还剩的挂单量不由人为控制,所以这个地方可以多撤
                    double leave = size1 - size2;
                    // 现在这个价位上挂了很多单,是撤开仓,还是撤新挂的?
                    double count = 0;

                    // 这个地方会出错,只好重新复制一下
                    foreach (Order o in b1.Value.ToList())
                    {
                        count += o.LeavesQty;
                        if (count >= leave)
                        {
                            break;
                        }

                        forCancel.Add(o);
                        //cancelList.Add(o);
                        //o.Cancel();
                        //++cnt;
                    }
                }
            }

            foreach (var o in forCancel)
            {
                if (!o.IsDone)
                {
                    o.Cancel();
                }
                cancelList.Add(o);
                ++cnt;
            }

            return(cnt);
        }
Example #11
0
        // 这里假设已经挂的单子已经是按最优数量进行处理过,目标是直接挂单
        // 目前对前两层做智能开平,后面的全用开仓单
        // 因为后面的使用平仓单,还要处理复杂的大量开挂单的问题。
        // 实际上不能太深,因为深了占用资金
        public int 单边全面补单(OrderBook_OneSide_Order buy1, OrderBook_OneSide_Size buy2)
        {
            int cnt = 0;
            List <CopyOrder> list = new List <CopyOrder>();

            // 方向不对,不可能补单
            if (buy1.Side != buy2.Side)
            {
                return(cnt);
            }

            TextCommon     tp        = buy1.Side == OrderSide.Buy ? TextParameterBid : TextParameterAsk;
            PositionRecord LongShort = buy1.Side == OrderSide.Buy ? base.DualPosition.Short : base.DualPosition.Long;

            lock (this)
            {
                int l = 0;
                // 由于在别的地方做了撤单,在这buy2中的数量是大于等于buy1的
                foreach (var b2 in buy2.GridList)
                {
                    ++l;
                    int    level = b2.Key;
                    double size  = b2.Value;

                    // 要补单的数量
                    double leave = size - buy1.SizeByLevel(level);
                    if (leave <= 0)
                    {
                        continue;
                    }

                    double price = PriceHelper.GetPriceByLevel(level);
                    cnt += (int)leave;

                    // 超过两层的全用开仓
                    if (l > AlwaysOpenIfDepthGreatThan)
                    {
                        tp.OpenClose = EnumOpenClose.OPEN;
                        tp.Text      = string.Format("{0}层,开仓补单", l);
                    }
                    else
                    {
                        // 计算开平
                        double q = CloseTodayHelper.GetCloseAndQty(LongShort, out tp.OpenClose);
                        if (q < leave)
                        {
                            tp.OpenClose = EnumOpenClose.OPEN;
                            tp.Text      = string.Format("开仓:可平量{0}<{1}", q, leave);
                        }
                        else
                        {
                            tp.Text = string.Format("平仓:可平量{0}>={1}", q, leave);
                        }
                    }


                    // 入场下单
                    // 在模拟下,这个地方有可能导致成交回报lock
                    //SendLimitOrder(buy2.Side, leave, price, tp.ToString());

                    list.Add(new CopyOrder()
                    {
                        Side  = buy2.Side,
                        Qty   = leave,
                        Price = price,
                        Text  = tp.ToString(),
                    });
                }
            }

            foreach (var o in list)
            {
                SendLimitOrder(o.Side, o.Qty, o.Price, o.Text);
            }

            return(cnt);
        }
Example #12
0
        // 检查对手,保证不会自成交
        // 这次有可能把平仓单全撤了,剩下的全是开仓单,有些风险
        public int 单边防自成交撤单(OrderBook_OneSide_Order sell, OrderBook_OneSide_Size buy)
        {
            int          cnt       = 0;
            List <Order> forCancel = new List <Order>();

            // 同买卖是不可能自成交的
            if (sell.Side == buy.Side)
            {
                return(cnt);
            }

            // 还没有挂单,不会自成交
            if (sell.Count <= 0)
            {
                return(cnt);
            }

            // 对手单也是空的,不会自成交
            if (buy.Count <= 0)
            {
                return(cnt);
            }

            lock (this)
            {
                // 取对手单的最高价
                int level = buy.LevelByIndex(0);
                // 将挂单列表中的单子撤单
                // 将挂单列表中的单子撤单
                foreach (var s in sell.GridList)
                {
                    if (buy.Side == OrderSide.Buy)
                    {
                        if (s.Key <= level)
                        {
                            forCancel.AddRange(s.Value);
                            //cancelList.UnionWith(s.Value);
                            //cnt += sell.Cancel(s.Value);
                        }
                    }
                    else
                    {
                        if (s.Key >= level)
                        {
                            forCancel.AddRange(s.Value);
                            //cancelList.UnionWith(s.Value);
                            //cnt += sell.Cancel(s.Value);
                        }
                    }
                }
            }

            foreach (var o in forCancel)
            {
                if (!o.IsDone)
                {
                    o.Cancel();
                }
                cancelList.Add(o);
                ++cnt;
            }

            return(cnt);
        }