Esempio n. 1
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);
            }
        }
Esempio n. 2
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;
        }
Esempio n. 3
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;
            }
        }
Esempio n. 4
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;
            }
        }
Esempio n. 5
0
        public event HeaderEventHandler HeaderParsed = delegate { }; // Initializing to the empty anonymous method will ensure that the event is never null, even if no methods are subscribed to it.

        /// <summary>
        /// Wrapper around the 'HeaderParsed' event, called when the header of a message has been parsed.
        /// </summary>
        internal void OnHeaderParsed(Header header)
        {
            HeaderEventHandler invoker = HeaderParsed;

            invoker(header);
        }
Esempio n. 6
0
        public event DecodeStatusEventHandler DecodeStarted = delegate { }; // Initializing to the empty anonymous method will ensure that the event is never null, even if no methods are subscribed to it.

        /// <summary>
        /// Provides methods and properties for decoding FIX messages.
        /// </summary>
        public Decoder()
        {
            trailer = new Trailer();
            header = new Header(tag, value, trailer, this);
            xupdate = new MarketDataIncrementalRefresh(tag, value, trailer, this);
            logout = new Logout(tag, value, trailer);
            logon = new Logon(tag, value, trailer);
            vupdate = new MarketDataRequest(tag, value, trailer);
            fupdate = new SecurityStatus(tag, value, trailer);
            dupdate = new SecurityDefinition(tag, value, trailer);
            rupdate = new QuoteRequest(tag, value, trailer);
            wupdate = new MarketDataSnapshotFullRefresh(tag, value, trailer);
            message = new Message();
        }
Esempio n. 7
0
        /// <summary>
        /// Called when the header of a FIX message has been decoded.
        /// </summary>
        /// <param name="header"></param>
        protected virtual void OnHeaderParsed(Header header)
        {
            this.header = header;
            currentTime = header.SendingTime;

            RollOrderBooks(currentTime);

            messageContainsValidTrade = false;
            messageContainsValidQuote = false;
        }