private MarketDepth CreateNew(Depth quotes)
        {
            var newDepth = new MarketDepth();

            newDepth.Time = DateTime.UtcNow;

            newDepth.SecurityNameCode = quotes.Symbol;

            var needDepth = _allDepths.Find(d => d.SecurityNameCode == newDepth.SecurityNameCode);

            if (needDepth != null)
            {
                _allDepths.Remove(needDepth);
            }

            var bids = quotes.Data.Bids;
            var asks = quotes.Data.Asks;

            foreach (var bid in bids)
            {
                newDepth.Bids.Add(new MarketDepthLevel()
                {
                    Price = bid[0].ToDecimal(),
                    Bid   = bid[1].ToDecimal(),
                });
            }

            foreach (var ask in asks)
            {
                newDepth.Asks.Add(new MarketDepthLevel()
                {
                    Price = ask[0].ToDecimal(),
                    Ask   = ask[1].ToDecimal(),
                });
            }

            _allDepths.Add(newDepth);

            return(newDepth.GetCopy());
        }
Beispiel #2
0
        /// <summary>
        /// updated market depth
        /// обновился стакан котировок
        /// </summary>
        /// <param name="bitMaxDepth"></param>
        private void ClientUpdateMarketDepth(Depth bitMaxDepth)
        {
            try
            {
                lock (_depthLocker)
                {
                    if (_depths == null)
                    {
                        _depths = new List <MarketDepth>();
                    }

                    if (bitMaxDepth.asks == null ||
                        bitMaxDepth.bids == null)
                    {
                        return;
                    }

                    var needDepth = _depths.Find(depth =>
                                                 depth.SecurityNameCode == bitMaxDepth.s.Replace('/', '-'));

                    if (needDepth == null)
                    {
                        needDepth = new MarketDepth();
                        needDepth.SecurityNameCode = bitMaxDepth.s.Replace('/', '-');
                        _depths.Add(needDepth);
                    }

                    for (int i = 0; i < bitMaxDepth.asks.Count; i++)
                    {
                        var needPrice =
                            bitMaxDepth.asks[i][0].ToDecimal();

                        var needLevel = needDepth.Asks.Find(l => l.Price == needPrice);

                        var qty =
                            bitMaxDepth.asks[i][1].ToDecimal();

                        if (needLevel != null)
                        {
                            if (qty == 0)
                            {
                                needDepth.Asks.Remove(needLevel);
                                needLevel = needDepth.Bids.Find(l => l.Price == needPrice);

                                if (needLevel != null)
                                {
                                    needDepth.Bids.Remove(needLevel);
                                }
                            }
                            else
                            {
                                needLevel.Ask = qty;
                            }
                        }
                        else
                        {
                            if (qty == 0)
                            {
                                continue;
                            }
                            needDepth.Asks.Add(new MarketDepthLevel()
                            {
                                Ask   = qty,
                                Price = needPrice,
                            });
                            _needSortAsks = true;
                        }
                    }

                    for (int i = 0; i < bitMaxDepth.bids.Count; i++)
                    {
                        var needPrice =
                            bitMaxDepth.bids[i][0].ToDecimal();

                        var needLevel = needDepth.Bids.Find(l => l.Price == needPrice);

                        var qty =
                            bitMaxDepth.bids[i][1].ToDecimal();

                        if (needLevel != null)
                        {
                            if (qty == 0)
                            {
                                needDepth.Bids.Remove(needLevel);
                                needLevel = needDepth.Asks.Find(l => l.Price == needPrice);

                                if (needLevel != null)
                                {
                                    needDepth.Asks.Remove(needLevel);
                                }
                            }
                            else
                            {
                                needLevel.Bid = qty;
                            }
                        }
                        else
                        {
                            if (qty == 0)
                            {
                                continue;
                            }

                            needDepth.Bids.Add(new MarketDepthLevel()
                            {
                                Bid   = qty,
                                Price = needPrice,
                            });
                            _needSortBids = true;
                        }
                    }

                    if (_needSortAsks)
                    {
                        needDepth.Asks.Sort((a, b) =>
                        {
                            if (a.Price > b.Price)
                            {
                                return(1);
                            }
                            else if (a.Price < b.Price)
                            {
                                return(-1);
                            }
                            else
                            {
                                return(0);
                            }
                        });
                        _needSortAsks = false;
                    }

                    if (_needSortBids)
                    {
                        needDepth.Bids.Sort((a, b) =>
                        {
                            if (a.Price > b.Price)
                            {
                                return(-1);
                            }
                            else if (a.Price < b.Price)
                            {
                                return(1);
                            }
                            else
                            {
                                return(0);
                            }
                        });
                        _needSortBids = false;
                    }
                    if (needDepth.Asks.Count > 20)
                    {
                        needDepth.Asks.RemoveRange(20, needDepth.Asks.Count - 20);
                    }
                    if (needDepth.Bids.Count > 20)
                    {
                        needDepth.Bids.RemoveRange(20, needDepth.Bids.Count - 20);
                    }

                    needDepth.Time = ServerTime;

                    if (needDepth.Time == DateTime.MinValue)
                    {
                        return;
                    }

                    if (MarketDepthEvent != null)
                    {
                        MarketDepthEvent(needDepth.GetCopy());
                    }
                }
            }
            catch (Exception error)
            {
                SendLogMessage(error.ToString(), LogMessageType.Error);
            }
        }