Example #1
0
        /// <summary>
        /// Get price depth if a certain volume is traded on one side
        /// i.e. What would be the worst price if the desired volume is traded on the given side
        /// </summary>
        /// <param name="vol">Volume traded</param>
        /// <param name="side">Side of the trade</param>
        /// <returns>Most extreme price traded</returns>
        /// <remarks>This function does not return the best bid/offer after the trade but the price of the last trade. This is significant in cases where the last trade exhausts all volume at a certain price level and best bid/offer falls to the next price level</remarks>
        public double PriceDepth(double vol, char side)
        {
            double    cumulativeVol = 0;
            BookOrder Start         = GetBook(side);
            double    prevPrice     = side.Equals(MDEntryType.BID) ? BestBid.Price : BestOffer.Price;

            for (var current = Start; current != null; current = current.Next)
            {
                cumulativeVol += current.Volume;
                prevPrice      = current.Price;
                if (cumulativeVol >= vol)
                {
                    break;
                }
            }
            return(prevPrice);
        }
Example #2
0
 /// <summary>
 /// Add volume to the order book at the given price level
 /// </summary>
 /// <param name="price">Price level</param>
 /// <param name="vol">Volume at given price level</param>
 /// <param name="side">Side of price level</param>
 /// <remarks>No verification is made to check if the price and side are possible</remarks>
 public void AddOrder(double price, double vol, char side)
 {
     if (side.Equals(MDEntryType.BID))
     {
         BidLock.WaitOne();
         NumBids += 1;
         if (BestBid == null)
         {
             BestBid = new BookOrder(price, vol);
         }
         else
         {
             if (price > BestBid.Price)
             {
                 BookOrder newBestBid = new BookOrder(price, vol, BestBid);
                 BestBid = newBestBid;
             }
             else
             {
                 BookOrder current;
                 BookOrder prev = BestBid;
                 for (current = BestBid; current != null && current.Price > price; prev = current, current = current.Next)
                 {
                     ;
                 }
                 BookOrder newOrder = new BookOrder(price, vol, prev.Next);
                 prev.Next = newOrder;
             }
         }
         if (WorstBidPrice == 0 || WorstBidPrice > price)
         {
             WorstBidPrice = price;
         }
         BidLock.ReleaseMutex();
     }
     else if (side.Equals(MDEntryType.OFFER))
     {
         OfferLock.WaitOne();
         NumOffers += 1;
         if (BestOffer == null)
         {
             BestOffer = new BookOrder(price, vol);
         }
         else
         {
             if (price < BestOffer.Price)
             {
                 BookOrder newBestOffer = new BookOrder(price, vol, BestOffer);
                 BestOffer = newBestOffer;
             }
             else
             {
                 BookOrder current;
                 BookOrder prev = BestOffer;
                 for (current = BestOffer; current != null && current.Price < price; prev = current, current = current.Next)
                 {
                     ;
                 }
                 BookOrder newOrder = new BookOrder(price, vol, prev.Next);
                 prev.Next = newOrder;
             }
         }
         OfferLock.ReleaseMutex();
         if (WorstOfferPrice == 0 || WorstOfferPrice < price)
         {
             WorstOfferPrice = price;
         }
     }
     else
     {
         Log.Write($"Unknown MDEntryType: {side}", 0);
         return;
     }
 }
Example #3
0
 public BookOrder(double price, double vol, BookOrder next = null)
 {
     Price  = price;
     Volume = vol;
     Next   = next;
 }
Example #4
0
 /// <summary>
 /// Remove all volume from the order book at a given price level
 /// </summary>
 /// <param name="price">Price level</param>
 /// <param name="side">Side of the price level</param>
 public void RemoveOrder(double price, char side)
 {
     if (side.Equals(MDEntryType.BID))
     {
         BidLock.WaitOne();
         if (BestBid.Price == price) // remove first
         {
             BestBid = BestBid.Next;
         }
         else if (price < WorstBidPrice)
         {
             Log.Write("Not removing price outside orderbook", 3);
             BidLock.ReleaseMutex();
             return;
         }
         else // if not first
         {
             BookOrder current;
             BookOrder prev = BestBid;
             for (current = BestBid; current != null && current.Price > price; prev = current, current = current.Next)
             {
                 ;
             }
             if (current == null || current.Price != price)
             {
                 Log.Write("Error: Trying to remove inexistant book order", 3);
                 BidLock.ReleaseMutex();
                 return;
             }
             prev.Next = current.Next;
             current   = null;
         }
         NumBids -= 1;
         BidLock.ReleaseMutex();
     }
     else if (side.Equals(MDEntryType.OFFER))
     {
         OfferLock.WaitOne();
         if (BestOffer.Price == price) // remove first
         {
             BestOffer = BestOffer.Next;
         }
         else if (price > WorstOfferPrice)
         {
             Log.Write("Not removing price outside orderbook", 3);
             OfferLock.ReleaseMutex();
             return;
         }
         else // if not first
         {
             BookOrder current;
             BookOrder prev = BestOffer;
             for (current = BestOffer; current != null && current.Price < price; prev = current, current = current.Next)
             {
                 ;
             }
             if (current == null || current.Price != price)
             {
                 Log.Write("Error: Trying to remove inexistant book order", 3);
                 OfferLock.ReleaseMutex();
                 return;
             }
             prev.Next = current.Next;
             current   = null;
         }
         NumOffers -= 1;
         OfferLock.ReleaseMutex();
     }
     else
     {
         Log.Write($"Unknown MDEntryType: {side}", 0);
         return;
     }
 }