Пример #1
0
 private void RebalanceOrder(ProposedOrder propOrder, bool useLock = false)
 {
     foreach (var legs in propOrder.OrderLegs.GroupBy(o => o.LegLevel).OrderByDescending(o => o.Key).Skip(1))
     {
         var sellQuantity       = legs.Sum(l => l.ProposedSellQuantity);
         var nextLevelOrderLegs = propOrder.GetOrderLegs(legs.Key + 1);
         if (nextLevelOrderLegs == null)
         {
             break;
         }
         var buyQuantity = nextLevelOrderLegs.Sum(o => o.ProposedBuyQuantity);
         if (buyQuantity == sellQuantity)
         {
             continue;
         }
         if (sellQuantity <= 0 || buyQuantity <= 0)
         {
             break;
         }
         if (sellQuantity < buyQuantity)
         {
             long newBuyQuantity = sellQuantity;
             foreach (var orderLeg in nextLevelOrderLegs.OrderBy(o => (double)o.ProposedBuyQuantity / (double)o.ProposedSellQuantity))
             {
                 var adj = RebalanceOrderLegForBuy(propOrder, orderLeg, newBuyQuantity, useLock);
                 buyQuantity    += adj;
                 newBuyQuantity -= orderLeg.ProposedBuyQuantity;
                 if (buyQuantity <= sellQuantity)
                 {
                     break;
                 }
             }
         }
         else
         {
             long newSellQuantity = buyQuantity;
             foreach (var orderLeg in legs.OrderBy(o => (double)o.ProposedBuyQuantity / (double)o.ProposedSellQuantity))
             {
                 var adj = RebalanceOrderLegForSell(propOrder, orderLeg, newSellQuantity, useLock);
                 sellQuantity    += adj;
                 newSellQuantity -= orderLeg.ProposedSellQuantity;
                 if (sellQuantity <= buyQuantity)
                 {
                     break;
                 }
             }
         }
         if (!propOrder.OrderQuantitiesInSync && sellQuantity > 0 && buyQuantity > 0)
         {
             RebalanceOrder(propOrder);
             break;
         }
         else if (sellQuantity <= 0 || buyQuantity <= 0)
         {
             break;
         }
     }
 }
Пример #2
0
 private void RemoveWorstOrderLeg(ThreadSafeAsk ask, ProposedOrder propOrder, bool useLock = false)
 {
     while (propOrder.IsValidOrder && propOrder.BuyRatio < ask.GetBuyRatio(propOrder.SellCommodityID, propOrder.BuyCommodityID) && propOrder.ProposedQuanityBuy > 0)
     {
         var worstPerfomingOrderLeg = propOrder.RemoveWorstPerforming(useLock);
         if (worstPerfomingOrderLeg == null)
         {
             break;
         }
         RebalanceOrder(propOrder, useLock);
         propOrder.CleanUpOrder();
     }
 }
Пример #3
0
        private long RebalanceOrderLegForSell(ProposedOrder propOrder, ProposedOrderLeg orderLeg, long buyQuantity, bool useLock = false)
        {
            long sellQuantityAdj = 0;

            if (!orderLeg.Ask.AllowPartialFill || orderLeg.ProposedSellQuantity < buyQuantity)
            {
                sellQuantityAdj = -1 * orderLeg.ProposedSellQuantity;
            }
            else
            {
                sellQuantityAdj = -1 * (orderLeg.ProposedSellQuantity - buyQuantity);
            }
            sellQuantityAdj = orderLeg.SetSellQuantity(sellQuantityAdj, useLock: useLock);
            return(sellQuantityAdj);
        }
Пример #4
0
        private IEnumerable <OrderLeg> BuildOrderLegs(ThreadSafeAsk ask, ProposedOrder order, Dictionary <long, Tuple <ThreadSafeAsk, long> > asksInOrder, ref long orderQuanity, bool doLock = false, bool isMarketQuote = false)
        {
            bool            hasBrokenLeg             = false;
            List <OrderLeg> legs                     = new List <OrderLeg>();
            IEnumerable <ProposedOrderLeg> orderLegs = null;

            if ((ask.IsBuy ? order.ProposedQuanityBuy : order.ProposedQuantitySell) + orderQuanity <= ask.LockExecuteQuantity)
            {
                orderLegs = ProcessOrderLegs(order.OrderLegs, legs, asksInOrder, out hasBrokenLeg);
            }
            else if (orderQuanity < ask.LockExecuteQuantity)
            {
                ClearProposedOrderLegs(order.OrderLegs, useLock: doLock);
                var newOrder = BuildProposedOrder(ask, ask.LockExecuteQuantity - orderQuanity, order.OrderLegs, useLock: doLock);
                if (newOrder.IsValidOrder && (isMarketQuote || newOrder.BuyRatio >= ask.GetBuyRatio(newOrder.SellCommodityID, newOrder.BuyCommodityID)))
                {
                    orderLegs = ProcessOrderLegs(newOrder.OrderLegs, legs, asksInOrder, out hasBrokenLeg);
                }
                else
                {
                    ClearProposedOrderLegs(newOrder.OrderLegs, useLock: doLock);
                    return(new OrderLeg[] { });
                }
                order = newOrder;
            }
            if (hasBrokenLeg)
            {
                ClearProposedOrderLegs(order.OrderLegs, asksInOrder, useLock: doLock);
                var newOrder = BuildProposedOrder(ask, ask.LockExecuteQuantity - orderQuanity, orderLegs, useLock: doLock);
                legs.Clear();
                if (newOrder.IsValidOrder && (isMarketQuote || newOrder.BuyRatio >= ask.GetBuyRatio(newOrder.SellCommodityID, newOrder.BuyCommodityID)))
                {
                    ProcessOrderLegs(order.OrderLegs, legs, asksInOrder, out hasBrokenLeg);
                    if (hasBrokenLeg)
                    {
                        ClearProposedOrderLegs(newOrder.OrderLegs, asksInOrder, useLock: doLock);
                        return(new OrderLeg[] { });
                    }
                }
                else
                {
                    ClearProposedOrderLegs(newOrder.OrderLegs, asksInOrder, useLock: doLock);
                    return(new OrderLeg[] { });
                }
            }
            orderQuanity += ask.IsBuy ? legs.Where(l => l.CommodityBuyID == order.BuyCommodityID).Sum(l => l.BuyQuantity) : legs.Where(l => l.CommoditySellID == order.SellCommodityID).Sum(l => l.SellQuantity);
            return(legs);
        }
Пример #5
0
        private IEnumerable <Order> BuildOrder(ThreadSafeAsk ask, IEnumerable <ProposedOrder> orders, out long orderQuanity, bool isMarketQuote = false, bool doLock = false)
        {
            orderQuanity = 0;
            Dictionary <Tuple <int, int>, Order>            finalOrders = new Dictionary <Tuple <int, int>, Order>();
            Dictionary <long, Tuple <ThreadSafeAsk, long> > asksInOrder = new Dictionary <long, Tuple <ThreadSafeAsk, long> >();
            var orderBuyRatios = orders.GroupBy(o => new Tuple <int, int>(o.SellCommodityID, o.BuyCommodityID)).Select(g => new { SellBuyCommodities = g.Key, AskBuyRatio = ask.GetBuyRatio(g.Key.Item1, g.Key.Item2),
                                                                                                                                  AverageBuyRatio    = g.Average(o => o.BuyRatio) }).ToDictionary(g => g.SellBuyCommodities);

            foreach (var propOrder in orders.Where(
                         o => o.IsValidOrder && (isMarketQuote || o.BuyRatio >= orderBuyRatios[new Tuple <int, int>(o.SellCommodityID, o.BuyCommodityID)].AskBuyRatio)).OrderByDescending(o => isMarketQuote ? (o.BuyRatio - orderBuyRatios[new Tuple <int, int>(o.SellCommodityID, o.BuyCommodityID)].AverageBuyRatio) / orderBuyRatios[new Tuple <int, int>(o.SellCommodityID, o.BuyCommodityID)].AverageBuyRatio : (o.BuyRatio - orderBuyRatios[new Tuple <int, int>(o.SellCommodityID, o.BuyCommodityID)].AskBuyRatio) / orderBuyRatios[new Tuple <int, int>(o.SellCommodityID, o.BuyCommodityID)].AskBuyRatio))
            {
                ClearProposedOrderLegs(propOrder.OrderLegs);
                ProposedOrder newOrder = BuildProposedOrder(ask, ask.LockExecuteQuantity - orderQuanity, propOrder.OrderLegs, useLock: doLock);
                if (newOrder.IsValidOrder && (isMarketQuote || newOrder.BuyRatio >= ask.GetBuyRatio(newOrder.SellCommodityID, newOrder.BuyCommodityID)))
                {
                    foreach (var leg in BuildOrderLegs(ask, newOrder, asksInOrder, ref orderQuanity, doLock, isMarketQuote))
                    {
                        Order order = null;
                        if (!finalOrders.ContainsKey(new Tuple <int, int>(newOrder.SellCommodityID, newOrder.BuyCommodityID)))
                        {
                            order = new Order();
                            order.CommodityBuyID        = newOrder.BuyCommodityID;
                            order.CommoditySellID       = newOrder.SellCommodityID;
                            order.CommissionCommodityID = newOrder.Ask.GetApplyCommissionToBuy(newOrder.SellCommodityID, newOrder.BuyCommodityID) ? newOrder.BuyCommodityID : newOrder.SellCommodityID;
                            finalOrders[new Tuple <int, int>(newOrder.SellCommodityID, newOrder.BuyCommodityID)] = order;
                        }
                        else
                        {
                            order = finalOrders[new Tuple <int, int>(newOrder.SellCommodityID, newOrder.BuyCommodityID)];
                        }
                        order.OrderLegs.Add(leg);
                    }
                }
                if (orderQuanity >= ask.LockExecuteQuantity)
                {
                    break;
                }
            }
            orders = null;
            foreach (var order in finalOrders)
            {
                ApplyCommission(order.Value, ask.GetApplyCommissionToBuy(order.Key.Item1, order.Key.Item2));
            }
            return(finalOrders.Values);
        }
Пример #6
0
        private ProposedOrder BuildProposedOrder(ThreadSafeAsk ask, long askQuantity, IEnumerable <ProposedOrderLeg> orderLegs, bool useLock = false, bool isMarketOrder = false)
        {
            ProposedOrder propOrder = new ProposedOrder(ask);

            if (ask.IsBuy)
            {
                BuildProposedOrderForBuy(ask, askQuantity, orderLegs, propOrder, useLock);
            }
            else
            {
                BuildProposedOrderForSell(ask, askQuantity, orderLegs, propOrder, useLock);
            }
            propOrder.CleanUpOrder();
            if (!isMarketOrder && ask.AllowPartialFill && propOrder.IsValidOrder)
            {
                RemoveWorstOrderLeg(ask, propOrder, useLock);
            }

            orderLegs = null;
            return(propOrder);
        }
Пример #7
0
        private void RebalanceOrderLegsForSell(ThreadSafeAsk ask, IEnumerable <ProposedOrderLeg> orderLegs, int legLevel, long sellQuantity, ProposedOrder propOrder, bool useLock = false)
        {
            var previousOrderLegs = propOrder.GetOrderLegs(legLevel);

            while (previousOrderLegs != null)
            {
                ClearProposedOrderLegs(previousOrderLegs, useLock: useLock);
                var newLegs = FillProposedOrderLegsForRebalanceForSell(ask, sellQuantity, orderLegs.Where(o => o.LegLevel == legLevel), useLock);
                sellQuantity = newLegs.Sum(p => p.ProposedSellQuantity);
                if (sellQuantity > 0)
                {
                    propOrder.SetOrderLegs(newLegs);
                }


                legLevel--;
                previousOrderLegs = propOrder.GetOrderLegs(legLevel);
            }
        }
Пример #8
0
        private void BuildProposedOrderForBuy(ThreadSafeAsk ask, long askQuantity, IEnumerable <ProposedOrderLeg> orderLegs, ProposedOrder propOrder, bool useLock = false)
        {
            bool isFirst = true;

            foreach (var legs in orderLegs.GroupBy(o => o.LegLevel).OrderByDescending(o => o.Key))
            {
                long sellCap = long.MaxValue;
                if (ask.Legs.Count > 0 && legs.Key == 1)
                {
                    int commoditySellID = orderLegs.Where(l => l.LegLevel == 1).First().CommoditySellID;
                    var askLeg          = ask.Legs.Where(l => l.CommodityID == commoditySellID).First();
                    if (askLeg.AvailableQuantityWithoutLockExecute != null)
                    {
                        sellCap = askLeg.AvailableQuantityWithoutLockExecute.Value;
                    }
                }
                var propOrderLegs = FillProposedOrderLegsForBuy(ask, askQuantity, legs, useLock: useLock, sellCap: sellCap);
                if (propOrderLegs.Count == 0)
                {
                    break;
                }
                propOrder.SetOrderLegs(propOrderLegs);
                long sellQuantity = propOrderLegs.Sum(p => p.ProposedBuyQuantity);
                if (askQuantity > sellQuantity && sellQuantity > 0 && !isFirst)
                {
                    RebalanceOrderLegsForBuy(ask, orderLegs, legs.Key + 1, sellQuantity, propOrder, useLock);
                    var previousOrderLegs = propOrder.GetOrderLegs(legs.Key + 1);

                    if (previousOrderLegs != null)
                    {
                        ClearProposedOrderLegs(propOrderLegs, useLock: useLock);
                        askQuantity   = previousOrderLegs.Sum(p => p.ProposedSellQuantity);
                        propOrderLegs = FillProposedOrderLegsForBuy(ask, askQuantity, legs, useLock: useLock);
                        if (propOrderLegs.Count == 0 || askQuantity <= 0)
                        {
                            break;
                        }
                        propOrder.SetOrderLegs(propOrderLegs);
                    }
                }
                askQuantity = propOrderLegs.Sum(p => p.ProposedSellQuantity);
                if (askQuantity <= 0 || sellQuantity <= 0)
                {
                    break;
                }
                isFirst = false;
            }
        }