Beispiel #1
0
        // NOTE: In the context of the CME's data platform, a CHANGE OrderAction means a change to the aggregate size
        // of a pre-existing level.  It DOES NOT mean a change to the price of a resting order.
        // A change to the price of a resting order would be communicated via a DELETE OrderAction
        // at the old price, followed immediately by a NEW OrderAction at the new price.
        /// <summary>
        /// Modifies a price level which is already displayed in the limit order book.
        /// </summary>
        /// <param name="header"></param>
        /// <param name="update"></param>
        private void Change(Header header, MarketDataIncrementalRefresh.RepeatingGroup update)
        {
            int level = update.MDPriceLevel;

            if (update.MDEntryType == MDEntryType.Bid)
            {
                if (Bid[level].Price == null)
                {
                    New(header, update);
                    return;
                }

                Bid[level].Size           = update.MDEntrySize;
                Bid[level].UpdateTime     = header.SendingTime;
                Bid[level].NumberOfOrders = update.NumberOfOrders;
            }
            else if (update.MDEntryType == MDEntryType.Offer)
            {
                if (Ask[level].Price == null)
                {
                    New(header, update);
                    return;
                }

                Ask[level].Size           = update.MDEntrySize;
                Ask[level].UpdateTime     = header.SendingTime;
                Ask[level].NumberOfOrders = update.NumberOfOrders;
            }
        }
Beispiel #2
0
 private void BuildOrderBook(MarketDataIncrementalRefresh.RepeatingGroup update)
 {
     if (update.QuoteCondition != QuoteCondition.Implied)
     {
         OrderBooks[orderBookNumber].Build(header, update);
     }
     else if (update.QuoteCondition == QuoteCondition.Implied)
     {
         ImpliedOrderBooks[orderBookNumber].Build(header, update);
     }
 }
Beispiel #3
0
        /// <summary>
        /// Applies the current update to the limit order book.
        /// </summary>
        /// <param name="header"></param>
        /// <param name="update"></param>
        public void Build(Header header, MarketDataIncrementalRefresh.RepeatingGroup update)
        {
            if (update.MDUpdateAction == MDUpdateAction.New)
            {
                New(header, update);
            }
            else if (update.MDUpdateAction == MDUpdateAction.Change)
            {
                Change(header, update);
            }
            else if (update.MDUpdateAction == MDUpdateAction.Delete)
            {
                Delete(header, update);
            }

            UpdateTime = header.SendingTime;
        }
Beispiel #4
0
        /// <summary>
        /// Called when a trade has been decoded from a market data incremental refresh FIX message.
        /// </summary>
        /// <param name="update"></param>
        protected virtual void OnTradeParsed(MarketDataIncrementalRefresh.RepeatingGroup update)
        {
            if (!IsValidTrade(update))
            {
                return;
            }

            int contractIndex = GetContractIndex(update);

            if (contractIndex == NOT_FOUND)
            {
                return;
            }

            messageContainsValidTrade = true;

            OrderBooks[contractIndex].CommitTrade(update.MDEntryPx, currentTime, update.TradeVolume);
        }
Beispiel #5
0
        /// <summary>
        /// Called when a quote has been decoded from a market data incremental refresh FIX message.
        /// </summary>
        /// <param name="update"></param>
        protected virtual void OnQuoteParsed(MarketDataIncrementalRefresh.RepeatingGroup update)
        {
            if (!IsValidQuote(update))
            {
                return;
            }

            int contractIndex = GetContractIndex(update);

            if (contractIndex == NOT_FOUND)
            {
                return;
            }

            orderBookNumber = contractIndex;

            messageContainsValidQuote = true;

            BuildOrderBook(update);
        }
Beispiel #6
0
        // NOTE: In the context of the CME's data platform, a DELETE OrderAction means the deletion of an entire price level
        // from the book, not simply the deletion of a single order.  Deletions of single
        // orders (while the price level remains intact) will be communicated via the
        // CHANGE OrderAction.
        /// <summary>
        /// Removes a price level from the limit order book.
        /// </summary>
        /// <param name="header"></param>
        /// <param name="update"></param>
        private void Delete(Header header, MarketDataIncrementalRefresh.RepeatingGroup update)
        {
            int level = update.MDPriceLevel;

            if (update.MDEntryType == MDEntryType.Bid)
            {
                // TO DO: Find a better way to implement below.
                //if (Bid[level].Price != update.MDEntryPx)
                //{
                //    throw new InvalidOperationException("Rebuild operation is attempting to delete a price level (" + update.MDEntryPx + ") that does not exist in the order book!");
                //}

                ShiftDepthLevelsUp(Bid, header.SendingTime, from: level, to: Depth);

                if (level != Depth)
                {
                    return;
                }

                Bid[level].Delete(header.SendingTime);
            }
            else if (update.MDEntryType == MDEntryType.Offer)
            {
                // TO DO: Find a better way to implement below.
                //if (Ask[level].Price != update.MDEntryPx)
                //{
                //    throw new InvalidOperationException("Rebuild operation is attempting to delete a price level (" + update.MDEntryPx + ") that does not exist in the order book!");
                //}

                ShiftDepthLevelsUp(Ask, header.SendingTime, from: level, to: Depth);

                if (level != Depth)
                {
                    return;
                }

                Ask[level].Delete(header.SendingTime);
            }
        }
Beispiel #7
0
        // NOTE: In the context of the CME's data platform, a NEW OrderAction means the addition of an entire price level
        // to the book, not simply the addition of a single order.  Additions of single
        // orders (to a pre-existing price level) will be communicated via the
        // CHANGE OrderAction.
        /// <summary>
        /// Inserts a new price level into the limit order book.
        /// </summary>
        /// <param name="header"></param>
        /// <param name="update"></param>
        private void New(Header header, MarketDataIncrementalRefresh.RepeatingGroup update)
        {
            int level = update.MDPriceLevel;

            if (update.MDEntryType == MDEntryType.Bid)
            {
                ShiftDepthLevelsDown(Bid, from: Depth, to: level);

                Bid[level].Price          = update.MDEntryPx;
                Bid[level].Size           = update.MDEntrySize;
                Bid[level].UpdateTime     = header.SendingTime;
                Bid[level].NumberOfOrders = update.NumberOfOrders;
            }
            else if (update.MDEntryType == MDEntryType.Offer)
            {
                ShiftDepthLevelsDown(Ask, from: Depth, to: level);

                Ask[level].Price          = update.MDEntryPx;
                Ask[level].Size           = update.MDEntrySize;
                Ask[level].UpdateTime     = header.SendingTime;
                Ask[level].NumberOfOrders = update.NumberOfOrders;
            }
        }
Beispiel #8
0
        private int GetContractIndex(MarketDataIncrementalRefresh.RepeatingGroup update)
        {
            int contractHash = update.SecurityDesc.GetId();

            return(instrumentCollection[0].PertinentContracts(currentTime).IndexOf(contractHash));
        }
Beispiel #9
0
 /// <summary>
 /// Uses various elements of a given message to determine whether or not a quote is valid.
 /// </summary>
 /// <param name="update"></param>
 /// <returns></returns>
 protected virtual bool IsValidQuote(MarketDataIncrementalRefresh.RepeatingGroup update)
 {
     return(update.QuoteCondition != QuoteCondition.ExchangeBest);
 }
Beispiel #10
0
 /// <summary>
 /// Uses various elements of a given message to determine whether or not a trade is valid.
 /// </summary>
 /// <param name="update"></param>
 /// <returns></returns>
 protected virtual bool IsValidTrade(MarketDataIncrementalRefresh.RepeatingGroup update)
 {
     return(update.QuoteCondition != QuoteCondition.ExchangeBest &&
            update.TradeCondition != TradeCondition.PriceCalculatedByGlobex);
 }