internal List <OrderBookEntry> Convert(Binance.WsDepth depth, SymbolInformation si)
 {
     return(depth.asks.Select(y => new OrderBookEntry(si)
     {
         Price = Math.Round(decimal.Parse(y[0]), si.PriceDecimals),
         Quantity = Math.Round(decimal.Parse(y[1]), si.QuantityDecimals),
         Side = TradeSide.Sell
     }).Reverse().Concat(depth.bids.Select(y => new OrderBookEntry(si)
     {
         Price = Math.Round(decimal.Parse(y[0]), si.PriceDecimals),
         Quantity = Math.Round(decimal.Parse(y[1]), si.QuantityDecimals),
         Side = TradeSide.Buy
     })
                         ).ToList());
 }
Ejemplo n.º 2
0
 private IEnumerable <OrderBookEntry> ConvertDepth(Binance.WsDepth depth)
 {
     return(depth.bids.Select(y => new OrderBookEntry()
     {
         Price = decimal.Parse(y[0]),
         Quantity = decimal.Parse(y[1]),
         Side = TradeSide.Buy
     }).Concat(depth.asks.Select(y => new OrderBookEntry()
     {
         Price = decimal.Parse(y[0]),
         Quantity = decimal.Parse(y[1]),
         Side = TradeSide.Sell
     })
               ));
 }
        private IEnumerable <OrderBookEntry> OnOrderBook3(Binance.WsDepth depth)
        {
            Debug.Print($"OnOrderBook3() : {System.Threading.Thread.CurrentThread.ManagedThreadId}");
            try
            {
                _lock.Wait();
                if (OrderBook.lastUpdateId == 0)
                {
                    var result = client.GetDepthAsync(depth.symbol, OrderBookMaxItemCount).Result;
                    if (result.Success)
                    {
                        var tmp = Convert(result.Data, OrderBook.SymbolInformation);
                        OrderBook.lastUpdateId = result.Data.lastUpdateId;
                        return(tmp);
                        //Debug.Print($"{lastUpdateId}");
                    }
                }
                if (depth.finalUpdateId <= OrderBook.lastUpdateId)
                {
                    Debug.Print($"{depth.firstUpdateId} : {depth.finalUpdateId}  dropped");
                }
                else if (depth.firstUpdateId <= OrderBook.lastUpdateId + 1 && depth.finalUpdateId >= OrderBook.lastUpdateId + 1)
                {
                    var sw          = Stopwatch.StartNew();
                    var bookUpdates = Convert(depth, OrderBook.SymbolInformation);

                    OrderBook.lastUpdateId = depth.finalUpdateId;
                    Debug.Print($"Update {OrderBook.lastUpdateId} took {sw.ElapsedMilliseconds}ms.");

                    return(bookUpdates);
                }
                else
                {
                    Debug.Print($"{depth.firstUpdateId} : {depth.finalUpdateId}  dropped");
                }
                return(Enumerable.Empty <OrderBookEntry>());
            }
            finally
            {
                _lock.Release();
            }
        }
        private async void OnOrderBook2(Binance.WsDepth depth)
        {
            try
            {
                await _lock.WaitAsync();

                if ((orderBook.Asks.IsEmpty && orderBook.Bids.IsEmpty) || (orderBook.MergeDecimals != (int)cmbMergeDecimals.SelectedValue))
                {
                    var result = await client.GetDepthAsync(depth.symbol, (int)cmbBookSize.SelectedValue);

                    if (result.Success)
                    {
                        var tmp = Convert(result.Data, si);
                        orderBook.Asks.AddRange(tmp.Where(x => x.Side == TradeSide.Sell));
                        orderBook.Bids.AddRange(tmp.Where(x => x.Side == TradeSide.Buy));
                        lastUpdateId = result.Data.lastUpdateId;
                        //Debug.Print($"{lastUpdateId}");
                    }
                }
                if (depth.finalUpdateId <= lastUpdateId)
                {
                    //Debug.Print($"{depth.firstUpdateId}  :  {depth.finalUpdateId}  dropped");
                    return;
                }
                if (depth.firstUpdateId <= lastUpdateId + 1 && depth.finalUpdateId >= lastUpdateId + 1)
                {
                    var sw          = Stopwatch.StartNew();
                    var bookUpdates = Convert(depth, si);
                    foreach (var e in bookUpdates)
                    {
                        //Debug.Print($"Got {e.Price} : {e.Quantity}.");
                        if (e.Quantity == decimal.Zero)
                        {
                            orderBook.Asks.RemoveAll(orderBook.Asks.Where(x => x.Price == e.Price).ToList());
                            orderBook.Bids.RemoveAll(orderBook.Bids.Where(x => x.Price == e.Price).ToList());
                        }
                        else
                        {
                            // add or update
                            var bidsOrAsks = e.Side == TradeSide.Buy ? orderBook.Bids : orderBook.Asks;
                            var item       = bidsOrAsks.LastOrDefault(x => e.Price <= x.Price);
                            if (item != null)
                            {
                                if (e.Price == item.Price)
                                {
                                    item.Quantity = e.Quantity;
                                }
                                else
                                {
                                    var idx = bidsOrAsks.IndexOf(item);
                                    bidsOrAsks.Insert(idx + 1, e);
                                }
                            }
                            else
                            {
                                if (e.Side == TradeSide.Sell)
                                {
                                    orderBook.Asks.Insert(0, e);
                                }
                                else
                                {
                                    orderBook.Bids.Insert(0, e);
                                }
                            }
                        }
                    }

                    lastUpdateId = depth.finalUpdateId;
                    Debug.Print($"Update {lastUpdateId} took {sw.ElapsedMilliseconds}ms.");

                    //if (true)
                    //{
                    //    // remove items which are out of size
                    //    var item = orderBook.FirstOrDefault(x => x.Side == TradeSide.Buy);
                    //    var idx = orderBook.IndexOf(item);
                    //    var count = (int)cmbBookSize.SelectedValue;
                    //    var askCount = idx > count ? count : idx;
                    //    var bidCount = count;

                    //    orderBookCopy.Clear();
                    //    orderBookCopy.AddRange(orderBook.Skip(idx - askCount).Take(askCount + bidCount));
                    //}
                }
                else
                {
                    //Debug.Print($"{depth.firstUpdateId}  :  {depth.finalUpdateId}  dropped");
                }
            }
            finally
            {
                _lock.Release();
            }
        }
        private async void OnOrderBook(Binance.WsDepth depth)
        {
            try
            {
                await _lock.WaitAsync();

                if (orderBook2.IsEmpty)
                {
                    var result = await client.GetDepthAsync(depth.symbol, 1000);

                    if (result.Success)
                    {
                        orderBook2.AddRange(Convert(result.Data, si));
                        lastUpdateId = result.Data.lastUpdateId;
                        //Debug.Print($"{lastUpdateId}");
                    }
                }

                if (depth.finalUpdateId <= lastUpdateId)
                {
                    //Debug.Print($"{depth.firstUpdateId}  :  {depth.finalUpdateId}  dropped");
                    return;
                }
                if (depth.firstUpdateId <= lastUpdateId + 1 && depth.finalUpdateId >= lastUpdateId + 1)
                {
                    var sw          = Stopwatch.StartNew();
                    var bookUpdates = Convert(depth, si);
                    foreach (var e in bookUpdates)
                    {
                        if (e.Quantity == decimal.Zero)
                        {
                            orderBook2.RemoveAll(orderBook2.Where(x => x.Price == e.Price).ToList());
                        }
                        else
                        {
                            // add or update
                            var item = orderBook2.LastOrDefault(x => e.Side == x.Side && e.Price <= x.Price);
                            if (item != null)
                            {
                                if (e.Price == item.Price)
                                {
                                    item.Quantity = e.Quantity;
                                }
                                else
                                {
                                    var idx = orderBook2.IndexOf(item);
                                    orderBook2.Insert(idx + 1, e);
                                    //Debug.Print($"Inserting {e.Price} after {item.Price}");
                                }
                            }
                            else
                            {
                                if (e.Side == TradeSide.Sell)
                                {
                                    orderBook2.Insert(0, e);
                                }
                                else
                                {
                                    item = orderBook2.FirstOrDefault(x => x.Side == e.Side);
                                    var idx = orderBook2.IndexOf(item);
                                    orderBook2.Insert(idx, e);
                                    //Debug.Print($"Inserting {e.Price} before {item.Price}");
                                }
                            }
                        }
                    }
                    {
                        // remove items which are out of size
                        var item = orderBook2.FirstOrDefault(x => x.Side == TradeSide.Buy);
                        var idx  = orderBook2.IndexOf(item);
                        if (false)
                        {
                            var count = (int)cmbBookSize.SelectedValue;
                            while (idx + count < orderBook2.Count)
                            {
                                orderBook2.Remove(orderBook2.Last());
                            }
                            while (idx-- > count)
                            {
                                orderBook2.Remove(orderBook2.First());
                            }
                        }
                        // calculate agg. totals
                        decimal aggTotal = decimal.Zero;
                        for (var i = idx; i < orderBook2.Count; ++i)
                        {
                            aggTotal += orderBook2[i].Total;
                            orderBook2[i].TotalCumulative = aggTotal;
                        }
                        aggTotal = 0;
                        for (var i = idx - 1; i >= 0; --i)
                        {
                            aggTotal += orderBook2[i].Total;
                            orderBook2[i].TotalCumulative = aggTotal;
                        }
                    }
                    lastUpdateId = depth.finalUpdateId;
                    Debug.Print($"Update {lastUpdateId} took {sw.ElapsedMilliseconds}ms.");

                    //if (true)
                    //{
                    //    // remove items which are out of size
                    //    var item = orderBook.FirstOrDefault(x => x.Side == TradeSide.Buy);
                    //    var idx = orderBook.IndexOf(item);
                    //    var count = (int)cmbBookSize.SelectedValue;
                    //    var askCount = idx > count ? count : idx;
                    //    var bidCount = count;

                    //    orderBookCopy.Clear();
                    //    orderBookCopy.AddRange(orderBook.Skip(idx - askCount).Take(askCount + bidCount));
                    //}
                }
                else
                {
                    //Debug.Print($"{depth.firstUpdateId}  :  {depth.finalUpdateId}  dropped");
                }
            }
            finally
            {
                _lock.Release();
            }
        }