Exemplo n.º 1
0
        /// <summary>
        /// Update market depth
        /// </summary>
        public void UpdateDepth(IEnumerable <TradeResponse> asks, IEnumerable <TradeResponse> bids, long updateTime)
        {
            if (updateTime <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(updateTime));
            }

            // if nothing was changed then return
            if (updateTime <= LastUpdateTime)
            {
                return;
            }
            if (asks == null && bids == null)
            {
                return;
            }


            void UpdateOrderBook(IEnumerable <TradeResponse> updates, IDictionary <decimal, decimal> orders)
            {
                if (updates != null)
                {
                    foreach (TradeResponse t in updates)
                    {
                        if (t.Quantity != IgnoreVolumeValue)
                        {
                            orders[t.Price] = t.Quantity;
                        }
                        else
                        if (orders.ContainsKey(t.Price))
                        {
                            orders.Remove(t.Price);
                        }
                    }
                }
            }

            // save prev BestPair to OnMarketBestPairChanged raise event
            MarketDepthPair prevBestPair = BestPair;

            // update asks market depth
            UpdateOrderBook(asks, _asks);
            UpdateOrderBook(bids, _bids);
            // set new update time
            LastUpdateTime = updateTime;

            // raise events
            OnMarketDepthChanged(new MarketDepthChangedEventArgs(Asks, Bids, LastUpdateTime.Value));
            if (!BestPair.Equals(prevBestPair))
            {
                OnMarketBestPairChanged(new MarketBestPairChangedEventArgs(BestPair));
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Update market depth
        /// </summary>
        /// <remarks>
        /// How to manage a local order book correctly [1]:
        ///    1. Open a stream to wss://stream.binance.com:9443/ws/bnbbtc@depth
        ///    2. Buffer the events you receive from the stream
        ///    3. Get a depth snapshot from https://www.binance.com/api/v1/depth?symbol=BNBBTC&amp;limit=1000
        /// -> 4. Drop any event where u is less or equal lastUpdateId in the snapshot
        ///    5. The first processed should have U less or equal lastUpdateId+1 AND u equal or greater lastUpdateId+1
        /// -> 6. While listening to the stream, each new event's U should be equal to the previous event's u+1
        /// -> 7. The data in each event is the absolute quantity for a price level
        /// -> 8. If the quantity is 0, remove the price level
        ///    9. Receiving an event that removes a price level that is not in your local order book can happen and is normal.
        /// Reference:
        ///     1. https://github.com/binance/binance-spot-api-docs/blob/master/web-socket-streams.md#how-to-manage-a-local-order-book-correctly
        /// </remarks>
        public void UpdateDepth(IEnumerable <BinanceOrderBookEntry> asks, IEnumerable <BinanceOrderBookEntry> bids, long updateTime)
        {
            if (updateTime <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(updateTime));
            }

            // if nothing was changed then return
            if (updateTime <= LastUpdateTime)
            {
                return;
            }
            if (asks == null && bids == null)
            {
                return;
            }


            void UpdateOrderBook(IEnumerable <BinanceOrderBookEntry> updates, IDictionary <decimal, decimal> orders)
            {
                if (orders == null)
                {
                    throw new ArgumentNullException(nameof(orders));
                }
                if (updates == null)
                {
                    return;
                }

                // WARN: clean orders in cases when connector received orderbook snapshots instead of orderbook updates
                // orders.Clear();

                // update order book
                foreach (BinanceOrderBookEntry t in updates)
                {
                    if (t.Quantity > IgnoreVolumeValue)
                    {
                        orders[t.Price] = t.Quantity;
                    }
                    else
                    if (orders.ContainsKey(t.Price))
                    {
                        orders.Remove(t.Price);
                    }
                }
            }

            // save prev BestPair to OnMarketBestPairChanged raise event
            MarketDepthPair prevBestPair = BestPair;

            // update asks market depth
            UpdateOrderBook(asks, _asks);
            UpdateOrderBook(bids, _bids);
            // set new update time
            LastUpdateTime = updateTime;

            // raise events
            OnMarketDepthChanged(new MarketDepthChangedEventArgs(Asks, Bids, LastUpdateTime.Value));
            if (!BestPair.Equals(prevBestPair))
            {
                OnMarketBestPairChanged(new MarketBestPairChangedEventArgs(BestPair));
            }
        }