예제 #1
0
        private bool AddOrder(OrderTracker tracker, double price)
        {
            bool  matched = false;
            Order order   = tracker.Order;

            if (order.IsBuy)
            {
                matched = MatchBidOrder(tracker, price, Asks);
            }
            else
            {
                matched = MatchAskOrder(tracker, price, Bids);
            }

            if (tracker.Open != 0 && !tracker.IsImmediate)
            {
                if (order.IsBuy)
                {
                    Bids.Add(price, tracker);
                }
                else
                {
                    Asks.Add(price, tracker);
                }
            }

            return(matched);
        }
예제 #2
0
        protected virtual bool Matches(OrderTracker inbound, double inboundPrice, int inboundOpen, OrderTracker current, double currentPrice, bool isInboundBuy)
        {
            if (isInboundBuy)
            {
                if (inboundPrice < currentPrice)
                {
                    return(false);
                }
            }
            else
            {
                if (inboundPrice > currentPrice)
                {
                    return(false);
                }
            }

            if (current.IsInseparable)
            {
                if (current.Open > inboundOpen)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #3
0
        protected virtual bool ValidateReplace(OrderTracker order, int deltaSize, double price)
        {
            bool sizeDecreased = deltaSize < 0;

            if (sizeDecreased && (order.Open < Math.Abs(deltaSize)))
            {
                OnReplaceRejected(order.Order, "Insufficient open quantity", Transaction);
                return(false);
            }
            return(true);
        }
예제 #4
0
        protected void CrossOrders(OrderTracker inbound, OrderTracker current)
        {
            int    fillQuantity = Math.Min(inbound.Open, current.Open);
            double crossPrice   = current.Order.Price;

            if (MarketOrderPrice == crossPrice)
            {
                crossPrice = inbound.Order.Price;
            }

            inbound.Fill(fillQuantity);
            current.Fill(fillQuantity);

            bool inboundFilled = inbound.IsFilled;
            bool matchedFilled = current.IsFilled;

            OnFilled(inbound.Order, current.Order, fillQuantity, crossPrice, inboundFilled, matchedFilled, Transaction);
        }
예제 #5
0
        public virtual bool Add(Order order, OrderConditions conditions = OrderConditions.None)
        {
            ++Transaction;

            bool matched = false;

            if (!ValidateOrder(order, conditions))
            {
                // rejected
            }
            else
            {
                double       price   = SortPrice(order);
                OrderTracker tracker = new OrderTracker(order, conditions);

                matched = AddOrder(tracker, price);
                if (matched)
                {
                    // add tracker.Filled to OnAccepted
                    OnAccepted(order, Transaction, tracker.Filled);
                }
                else
                {
                    OnAccepted(order, Transaction, 0);
                }

                if (tracker.IsImmediate && !tracker.IsFilled)
                {
                    // cancel order, transaction
                    OnCanceled(order, 0, Transaction);
                }

                // update this, transaction
                OnBookUpdated(Transaction);
            }

            return(matched);
        }
예제 #6
0
        public virtual void Replace(Order order, int deltaSize, double newPrice)
        {
            ++Transaction;

            bool   matched      = false;
            bool   found        = false;
            bool   priceChanged = newPrice != 0 && newPrice != order.Price;
            double price        = (newPrice == PriceUnchanged) ? order.Price : newPrice;

            if (order.IsBuy)
            {
                int index = FindBid(order);

                if (index != -1)
                {
                    found = true;

                    if (ValidateReplace(Bids.Values[index], deltaSize, price))
                    {
                        OrderTracker tracker = Bids.Values[index];

                        OnReplaced(order, tracker.Open, deltaSize, price, Transaction);
                        OnBookUpdated(Transaction);

                        int newOpen = tracker.Open + deltaSize;
                        tracker.ChangeQuantity(newOpen);

                        if (newOpen == 0)
                        {
                            OnCanceled(order, 0, Transaction);
                            Bids.RemoveAt(index);
                        }
                        else
                        {
                            matched = AddOrder(tracker, price);
                            Bids.RemoveAt(index);
                        }
                    }
                }
            }
            else
            {
                int index = FindAsk(order);

                if (index != -1)
                {
                    found = true;

                    if (ValidateReplace(Asks.Values[index], deltaSize, price))
                    {
                        OrderTracker tracker = Asks.Values[index];

                        OnReplaced(order, tracker.Open, deltaSize, price, Transaction);
                        OnBookUpdated(Transaction);

                        int newOpen = tracker.Open + deltaSize;
                        tracker.ChangeQuantity(newOpen);

                        if (newOpen == 0)
                        {
                            OnCanceled(order, 0, Transaction);
                            Asks.RemoveAt(index);
                        }
                        else
                        {
                            matched = AddOrder(tracker, price);
                            Asks.RemoveAt(index);
                        }
                    }
                }
            }

            if (!found)
            {
                OnReplaceRejected(order, "Order not found.", Transaction);
            }
        }
예제 #7
0
        /// <summary>
        /// Matches a new bid order to current asks.
        /// </summary>
        /// <param name="order"></param>
        /// <param name="price"></param>
        /// <param name="asks"></param>
        /// <returns></returns>
        protected virtual bool MatchBidOrder(OrderTracker order, double price, OrderList asks)
        {
            bool matched         = false;
            int  matchedQuantity = 0;
            int  orderQuantity   = order.Open;

            for (int i = 0; i < asks.Count; i++)
            {
                if (Matches(order, price, order.Open - matchedQuantity, asks.Values[i], asks.Keys[i], true))
                {
                    if (order.IsInseparable)
                    {
                        matchedQuantity += asks.Values[i].Open;

                        if (matchedQuantity >= orderQuantity)
                        {
                            matched = true;

                            // unwind deferred crosses
                            int adjustment = 0;
                            for (int j = 0; j < DeferredAskCrosses.Count; j++)
                            {
                                int index = DeferredAskCrosses[j] - adjustment;

                                CrossOrders(order, asks.Values[index]);

                                if (asks.Values[index].IsFilled)
                                {
                                    asks.RemoveAt(index);
                                    ++adjustment;

                                    DeferredAskCrosses.RemoveAt(j--);
                                }
                                else
                                {
                                    DeferredAskCrosses[j] = index;
                                }
                            }
                        }
                        else
                        {
                            DeferredAskCrosses.Add(i);
                        }
                    }
                    else
                    {
                        matched = true;
                    }

                    if (matched)
                    {
                        CrossOrders(order, asks.Values[i]);

                        if (asks.Values[i].IsFilled)
                        {
                            asks.RemoveAt(i--);
                        }

                        if (order.IsFilled)
                        {
                            break;
                        }
                    }
                }
                else if (asks.Keys[i] > price)
                {
                    break;
                }
            }

            return(matched);
        }