Пример #1
0
        private IEnumerable <Order> GetQuote(ThreadSafeAsk ask, out long orderQuantity, int maxLegDepth = 5, bool doLock = false, bool isMarketQuote = false)
        {
            IEnumerable <Order> orders = null;

            orderQuantity = 0;
            ask.SetLockExecuteQuantity();
            if (ask.LockExecuteQuantity > 0)
            {
                ConcurrentBag <IEnumerable <ProposedOrderLeg> > orderLegs = new ConcurrentBag <IEnumerable <ProposedOrderLeg> >();
                foreach (var sellID in ask.CommoditySellID)
                {
                    BuildOrderLegs(sellID, ask.CommodityBuyID, orderLegs, maxLegDepth: maxLegDepth, doLock: doLock);
                }

                if (orderLegs.Count > 0)
                {
                    orders = BuildOrder(ask, orderLegs.Select(orderLeg =>
                                                              BuildProposedOrder(ask, ask.LockExecuteQuantity, orderLeg, isMarketOrder: isMarketQuote)).ToArray(),
                                        out orderQuantity, isMarketQuote, doLock);
                    if (orders.Count() == 0)
                    {
                        orders = null;
                    }
                }
                IEnumerable <ProposedOrderLeg> leg;
                while (orderLegs.TryTake(out leg))
                {
                    leg = null;
                }
                orderLegs = null;
                GC.Collect();
            }
            return(orders);
        }
Пример #2
0
 public Task Start()
 {
     return(Task.Factory.StartNew(() =>
     {
         if (Token == null)
         {
             Token = new CancellationTokenSource();
         }
         AskRepositoryTask = AskRepository.Start(Token);
         OpenAsksByBuyerCommdoity.Clear();
         OpenAsks.Clear();
         var commodities = CommodityRepository.GetCommodities();
         Parallel.ForEach(commodities, c => OpenAsksByBuyerCommdoity.AddOrUpdate(c.CommodityID, new ConcurrentDictionary <int, ConcurrentDictionary <long, ThreadSafeAsk> >(), (k, o) => o));
         Parallel.ForEach(OpenAsksByBuyerCommdoity, buyCommodityDictionary =>
         {
             foreach (var commodity in commodities)
             {
                 buyCommodityDictionary.Value.AddOrUpdate(commodity.CommodityID, new ConcurrentDictionary <long, ThreadSafeAsk>(), (k, o) => o);
             }
         });
         Parallel.ForEach(AskRepository.GetAsks(), ask =>
         {
             ThreadSafeAsk tAsk = CreateAsk(new ThreadSafeAsk(ask));
             foreach (var commodityBuyID in tAsk.CommodityBuyID)
             {
                 foreach (var commoditySellID in tAsk.CommoditySellID)
                 {
                     OpenAsksByBuyerCommdoity[commodityBuyID][commoditySellID].AddOrUpdate(tAsk.AskID, tAsk, (k, o) => o);
                 }
             }
             OpenAsks.AddOrUpdate(tAsk.AskID, tAsk, (k, o) => o);
         });
     }));
 }
Пример #3
0
 public ProposedOrderLeg(ThreadSafeAsk ask, int legLevel, bool doLock = false, ThreadSafeAskLeg leg = null)
 {
     Ask      = ask;
     LegLevel = legLevel;
     DoLock   = doLock;
     Leg      = leg;
 }
Пример #4
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();
     }
 }
Пример #5
0
        private void BuildProposedOrderForSell(ThreadSafeAsk ask, long askQuantity, IEnumerable <ProposedOrderLeg> orderLegs, ProposedOrder propOrder, bool useLock = false)
        {
            bool isFirst     = true;
            int  maxLegLevel = orderLegs.Max(l => l.LegLevel);

            foreach (var legs in orderLegs.GroupBy(o => o.LegLevel).OrderBy(o => o.Key))
            {
                long buyCap = long.MaxValue;
                if (ask.Legs.Count > 0 && legs.Key == maxLegLevel)
                {
                    int commodityBuyID = orderLegs.Where(l => l.LegLevel == maxLegLevel).First().CommodityBuyID;
                    var askLeg         = ask.Legs.Where(l => l.CommodityID == commodityBuyID).First();
                    if (askLeg.AvailableQuantityWithoutLockExecute != null)
                    {
                        buyCap = askLeg.AvailableQuantityWithoutLockExecute.Value;
                    }
                }
                var propOrderLegs = FillProposedOrderLegsForSell(ask, askQuantity, legs, useLock: useLock, buyCap: buyCap);
                if (propOrderLegs.Count == 0)
                {
                    break;
                }
                propOrder.SetOrderLegs(propOrderLegs);
                long sellQuantity = propOrderLegs.Sum(p => p.ProposedSellQuantity);
                if (askQuantity > sellQuantity && sellQuantity > 0 && !isFirst)
                {
                    RebalanceOrderLegsForSell(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.ProposedBuyQuantity);
                        propOrderLegs = FillProposedOrderLegsForSell(ask, askQuantity, legs, useLock: useLock);
                        if (propOrderLegs.Count == 0 || askQuantity <= 0)
                        {
                            break;
                        }
                        propOrder.SetOrderLegs(propOrderLegs);
                    }
                }
                askQuantity = propOrderLegs.Sum(p => p.ProposedBuyQuantity);
                if (askQuantity <= 0 || sellQuantity <= 0)
                {
                    break;
                }
                isFirst = false;
            }
        }
Пример #6
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);
        }
Пример #7
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);
        }
Пример #8
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);
            }
        }
Пример #9
0
        private ICollection <ProposedOrderLeg> FillProposedOrderLegsForSell(ThreadSafeAsk ask, long askQuantity, IEnumerable <ProposedOrderLeg> orderLegs, bool useLock = false, long buyCap = long.MaxValue)
        {
            List <ProposedOrderLeg> propOrderLegs = new List <ProposedOrderLeg>();

            foreach (var leg in orderLegs.OrderBy(l => l.RealBuyRatio).ThenBy(l => l.Ask.AskDate))
            {
                leg.SetSellQuantity(askQuantity, useLock, buyCap);
                if (leg.ProposedBuyQuantity > 0 || leg.ProposedSellQuantity > 0)
                {
                    propOrderLegs.Add(leg);
                }
                askQuantity -= leg.ProposedSellQuantity;
                buyCap      -= leg.ProposedBuyQuantity;
                if (askQuantity <= 0)
                {
                    break;
                }
            }
            return(propOrderLegs);
        }
Пример #10
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);
        }
Пример #11
0
 public ThreadSafeAskLeg(AskLeg leg, ThreadSafeAsk ask, object sync)
 {
     this.Leg  = leg;
     this.sync = sync;
     this.Ask  = ask;
 }
Пример #12
0
 public ProposedOrder(ThreadSafeAsk ask)
 {
     this.Ask       = ask;
     this.orderLegs = new SortedDictionary <int, ICollection <ProposedOrderLeg> >();
 }
Пример #13
0
        private ICollection <ProposedOrderLeg> FillProposedOrderLegsForRebalanceForSell(ThreadSafeAsk ask, long buyQuantity, IEnumerable <ProposedOrderLeg> orderLegs, bool useLock = false)
        {
            List <ProposedOrderLeg> propOrderLegs = new List <ProposedOrderLeg>();

            foreach (var leg in orderLegs.OrderBy(l => l.RealBuyRatio).ThenBy(l => l.Ask.AskDate))
            {
                leg.SetBuyQuantity(buyQuantity, useLock);
                if (leg.ProposedBuyQuantity > 0 && leg.ProposedSellQuantity > 0)
                {
                    propOrderLegs.Add(leg);
                }
                buyQuantity -= leg.ProposedBuyQuantity;

                if (buyQuantity <= 0)
                {
                    break;
                }
            }
            return(propOrderLegs);
        }
Пример #14
0
 private ThreadSafeAsk CreateAsk(ThreadSafeAsk ask)
 {
     ask.PropertyChanged += ThreadSafeAsk_PropertyChanged;
     return(ask);
 }
Пример #15
0
 private void DisposeAsk(ThreadSafeAsk ask)
 {
     ask.PropertyChanged -= ThreadSafeAsk_PropertyChanged;
 }
Пример #16
0
        private void ThreadSafeAsk_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            ThreadSafeAsk ask = (ThreadSafeAsk)sender;

            AsksToProcess.AddOrUpdate(ask.AskID, ask, (k, a) => a);
        }
Пример #17
0
        private IEnumerable <Order> ExecuteAsk(ThreadSafeAsk ask, int maxLegDepth = 5)
        {
            long          orderQuantity;
            var           orders = GetQuote(ask, out orderQuantity, maxLegDepth, true);
            ThreadSafeAsk tAsk;

            if (ask.AskID == 0 || !OpenAsks.TryGetValue(ask.AskID, out tAsk))
            {
                this.AskRepository.AddAsk(ask.Ask);
                tAsk = CreateAsk(ask);
                this.OpenAsks[ask.AskID] = tAsk;
                foreach (var buyID in tAsk.CommodityBuyID)
                {
                    foreach (var sellID in tAsk.CommoditySellID)
                    {
                        this.OpenAsksByBuyerCommdoity[buyID][sellID][ask.AskID] = tAsk;
                    }
                }
            }
            List <Ask>    orderLegAsks = new List <Ask>();
            List <AskLeg> legs         = new List <AskLeg>();

            if (orders != null)
            {
                if (!tAsk.FillOrder(orderQuantity))
                {
                    orders = null;
                }
                tAsk.RealizeLockExecuteQuantiy();
                if (tAsk.AskQuantity <= 0)
                {
                    if (this.OpenAsks.TryRemove(tAsk.AskID, out tAsk))
                    {
                        foreach (var buyID in tAsk.CommodityBuyID)
                        {
                            foreach (var sellID in tAsk.CommoditySellID)
                            {
                                this.OpenAsksByBuyerCommdoity[buyID][sellID].TryRemove(tAsk.AskID, out tAsk);
                            }
                        }
                    }
                }

                if (orders != null)
                {
                    foreach (var order in orders)
                    {
                        order.AskID   = tAsk.AskID;
                        order.OrderID = Guid.NewGuid();
                        foreach (var orderLeg in order.OrderLegs)
                        {
                            orderLeg.OrderID    = order.OrderID;
                            orderLeg.OrderLegID = Guid.NewGuid();
                            ThreadSafeAsk orderAsk;
                            if (OpenAsks.TryGetValue(orderLeg.AskID, out orderAsk))
                            {
                                orderAsk.RealizeLock(orderAsk.IsBuy ? orderLeg.SellQuantity : orderLeg.BuyQuantity);
                                if (orderAsk.Legs.Count > 0)
                                {
                                    var leg = orderAsk.Legs.Where(l => orderAsk.IsBuy ? l.CommodityID == orderLeg.CommodityBuyID : l.CommodityID == orderLeg.CommoditySellID).Single();
                                    leg.RealizeLock(orderAsk.IsBuy ? orderLeg.BuyQuantity : orderLeg.SellQuantity);
                                    legs.Add(leg.Leg);
                                }
                                if (orderAsk.AskQuantity <= 0)
                                {
                                    if (this.OpenAsks.TryRemove(orderAsk.AskID, out orderAsk))
                                    {
                                        foreach (var buyID in tAsk.CommodityBuyID)
                                        {
                                            foreach (var sellID in tAsk.CommoditySellID)
                                            {
                                                this.OpenAsksByBuyerCommdoity[buyID][sellID].TryRemove(tAsk.AskID, out orderAsk);
                                            }
                                        }
                                    }
                                    if (orderAsk != null)
                                    {
                                        DisposeAsk(orderAsk);
                                    }
                                }
                                if (orderAsk != null)
                                {
                                    orderLegAsks.Add(orderAsk.Ask);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                tAsk.RealizeLockExecuteQuantiy();
            }
            AskRepository.ExecuteAsk(ask.Ask, orders, orderLegAsks, legs);
            return(orders);
        }