Пример #1
0
        private async ValueTask <bool> updateTradeItem(SOrderBooks qob, List <BTradeItem> tradeItems, string stream)
        {
            var _rqo = new SOrderBooks
            {
                exchange     = BNLogger.SNG.exchange_name,
                stream       = stream,
                symbol       = qob.symbol,
                sequentialId = tradeItems.Max(t => t.timestamp),
                result       = new SOrderBook()
            };

            var _settings = __qSettings.ContainsKey(qob.symbol)
                          ? __qSettings[qob.symbol]
                          : __qSettings[qob.symbol] = new Settings();

            lock (__qOrderBooks)
            {
                _settings.before_trade_ask_size = qob.result.asks.Sum(o => o.quantity);
                _settings.before_trade_bid_size = qob.result.bids.Sum(o => o.quantity);

                foreach (var _t in tradeItems.OrderBy(t => t.timestamp))
                {
                    if (_settings.last_trade_time >= _t.timestamp)
                    {
                        continue;
                    }

                    _settings.last_trade_time = _t.timestamp;

                    var _ask = qob.result.asks.Where(o => o.price == _t.price).SingleOrDefault();
                    if (_ask != null)
                    {
                        if (_ask.quantity <= _t.quantity)
                        {
                            var _aoi = new SOrderBookItem
                            {
                                action   = "delete",
                                price    = _ask.price,
                                quantity = _ask.quantity,
                                amount   = _ask.price * _ask.quantity,
                                count    = 1
                            };

                            _rqo.result.asks.Add(_aoi);
                            _ask.quantity = 0;
                        }
                        else
                        {
                            _ask.quantity -= _t.quantity;

                            var _aoi = new SOrderBookItem
                            {
                                action   = "update",
                                price    = _ask.price,
                                quantity = _ask.quantity,
                                amount   = _ask.price * _ask.quantity,
                                count    = 1
                            };

                            _rqo.result.asks.Add(_aoi);
                        }
                    }

                    var _bid = qob.result.bids.Where(o => o.price == _t.price).SingleOrDefault();
                    if (_bid != null)
                    {
                        if (_bid.quantity <= _t.quantity)
                        {
                            var _aoi = new SOrderBookItem
                            {
                                action   = "delete",
                                price    = _bid.price,
                                quantity = _bid.quantity,
                                amount   = _bid.price * _bid.quantity,
                                count    = 1
                            };

                            _rqo.result.bids.Add(_aoi);
                            _bid.quantity = 0;
                        }
                        else
                        {
                            _bid.quantity -= _t.quantity;

                            var _aoi = new SOrderBookItem
                            {
                                action   = "update",
                                price    = _bid.price,
                                quantity = _bid.quantity,
                                amount   = _bid.price * _bid.quantity,
                                count    = 1
                            };

                            _rqo.result.bids.Add(_aoi);
                        }
                    }

                    // orderbook에 해당 하는 price-level 보다 안쪽에 위치한 level들은 삭제 해야 한다.
                    var _strange_asks = qob.result.asks.Where(o => o.price < _t.price);
                    if (_strange_asks.Count() > 0)
                    {
                        foreach (var _qox in _strange_asks)
                        {
                            var _aoi = new SOrderBookItem
                            {
                                action   = "delete",
                                price    = _qox.price,
                                quantity = _qox.quantity,
                                amount   = _qox.price * _qox.quantity,
                                count    = 1
                            };

                            _rqo.result.asks.Add(_aoi);
                            _qox.quantity = 0;
                        }
                    }

                    var _strange_bids = qob.result.bids.Where(o => o.price > _t.price);
                    if (_strange_bids.Count() > 0)
                    {
                        foreach (var _qox in _strange_bids)
                        {
                            var _aoi = new SOrderBookItem
                            {
                                action   = "delete",
                                price    = _qox.price,
                                quantity = _qox.quantity,
                                amount   = _qox.price * _qox.quantity,
                                count    = 1
                            };

                            _rqo.result.bids.Add(_aoi);
                            _qox.quantity = 0;
                        }
                    }
                }

                qob.sequentialId = _rqo.sequentialId;

                qob.result.asks.RemoveAll(o => o.quantity == 0);
                qob.result.bids.RemoveAll(o => o.quantity == 0);
            }

            if (_rqo.result.asks.Count + _rqo.result.bids.Count > 0)
            {
                await publishOrderbook(_rqo);

                //_settings.orderbook_count = 0;
            }

            return(true);
        }
Пример #2
0
        private async ValueTask <bool> updateOrderbook(SOrderBooks qob, SOrderBooks cob, Settings settings)
        {
            var _nob = new SOrderBooks
            {
                exchange     = cob.exchange,
                stream       = "diffbooks",
                symbol       = cob.symbol,
                action       = cob.action,
                sequentialId = cob.sequentialId,

                result = new SOrderBook
                {
                    timestamp = cob.result.timestamp,
                    askSumQty = 0,
                    bidSumQty = 0
                }
            };

            lock (__qOrderBooks)
            {
                foreach (var _ci in cob.result.asks)
                {
                    var _qi = qob.result.asks.Where(o => o.price == _ci.price).SingleOrDefault();
                    if (_qi == null)
                    {
                        var _ici = new SOrderBookItem
                        {
                            action   = "insert",
                            id       = _ci.id,
                            price    = _ci.price,
                            quantity = _ci.quantity,
                            amount   = _ci.price * _ci.quantity,
                            count    = 1
                        };

                        _nob.result.asks.Add(_ici);
                        qob.result.asks.Add(_ici);

                        _nob.result.askSumQty += _ci.quantity;
                    }
                    else if (_qi.quantity != _ci.quantity)
                    {
                        _nob.result.asks.Add(new SOrderBookItem
                        {
                            action   = "update",
                            id       = _qi.id,
                            price    = _qi.price,
                            quantity = _ci.quantity,
                            amount   = _qi.price * _ci.quantity,
                            count    = 1
                        });

                        _qi.quantity = _ci.quantity;
                        _qi.amount   = _qi.price * _qi.quantity;

                        _nob.result.askSumQty += _ci.quantity;
                    }
                }

                foreach (var _ci in cob.result.bids)
                {
                    var _qi = qob.result.bids.Where(o => o.price == _ci.price).SingleOrDefault();
                    if (_qi == null)
                    {
                        var _ici = new SOrderBookItem
                        {
                            action   = "insert",
                            id       = _ci.id,
                            price    = _ci.price,
                            quantity = _ci.quantity,
                            amount   = _ci.price * _ci.quantity,
                            count    = 1
                        };

                        _nob.result.bids.Add(_ici);
                        qob.result.bids.Add(_ici);

                        _nob.result.bidSumQty += _ci.quantity;
                    }
                    else if (_qi.quantity != _ci.quantity)
                    {
                        _nob.result.bids.Add(new SOrderBookItem
                        {
                            action   = "update",
                            id       = _qi.id,
                            price    = _qi.price,
                            quantity = _ci.quantity,
                            amount   = _qi.price * _ci.quantity,
                            count    = 1
                        });

                        _qi.quantity = _ci.quantity;
                        _qi.amount   = _qi.quantity * _qi.price;

                        _nob.result.bidSumQty += _ci.quantity;
                    }
                }

                foreach (var _qi in qob.result.asks)
                {
                    var _ci = cob.result.asks.Where(o => o.price == _qi.price).SingleOrDefault();
                    if (_ci == null)
                    {
                        _nob.result.asks.Add(new SOrderBookItem
                        {
                            action   = "delete",
                            id       = _qi.id,
                            price    = _qi.price,
                            quantity = _qi.quantity,
                            amount   = _qi.price * _qi.quantity,
                            count    = 1
                        });

                        _nob.result.askSumQty -= _qi.quantity;

                        _qi.quantity = 0;
                        _qi.amount   = 0;
                    }
                }

                foreach (var _qi in qob.result.bids)
                {
                    var _ci = cob.result.bids.Where(o => o.price == _qi.price).SingleOrDefault();
                    if (_ci == null)
                    {
                        _nob.result.bids.Add(new SOrderBookItem
                        {
                            action   = "delete",
                            id       = _qi.id,
                            price    = _qi.price,
                            quantity = _qi.quantity,
                            amount   = _qi.price * _qi.quantity,
                            count    = 1
                        });

                        _nob.result.bidSumQty -= _qi.quantity;

                        _qi.quantity = 0;
                        _qi.amount   = 0;
                    }
                }

                qob.result.asks.RemoveAll(o => o.quantity == 0);
                qob.result.bids.RemoveAll(o => o.quantity == 0);
            }

            if (++settings.orderbook_count == __gmconfig.SnapshotSkipCounter)
            {
                qob.sequentialId = cob.sequentialId;
                await snapshotOrderbook(_nob.symbol);
            }
            else
            {
                _nob.result.asks.RemoveAll(o => o.quantity == 0);
                _nob.result.bids.RemoveAll(o => o.quantity == 0);

                if (_nob.result.asks.Count > 0 || _nob.result.bids.Count > 0)
                {
                    await publishOrderbook(_nob);
                }
            }

            return(true);
        }
Пример #3
0
        private async ValueTask <bool> updateOrderbook(SOrderBooks qob, BAOrderBook orderbook, Settings settings)
        {
            var _dqo = new SOrderBooks
            {
                exchange     = BNLogger.SNG.exchange_name,
                stream       = "diffbooks",
                symbol       = orderbook.data.symbol,
                sequentialId = orderbook.data.lastId,
                result       = new SOrderBook()
            };

            lock (__qOrderBooks)
            {
                foreach (var _oi in orderbook.data.asks)
                {
                    var _ask = qob.result.asks.Where(o => o.price == _oi[0]).SingleOrDefault();
                    if (_ask == null)
                    {
                        var _aoi = new SOrderBookItem
                        {
                            action   = "insert",
                            price    = _oi[0],
                            quantity = _oi[1],
                            amount   = _oi[0] * _oi[1],
                            count    = 1
                        };

                        _dqo.result.asks.Add(_aoi);
                        qob.result.asks.Add(_aoi);
                    }
                    else if (_ask.quantity != _oi[1])
                    {
                        var _aoi = new SOrderBookItem
                        {
                            action   = "update",
                            price    = _oi[0],
                            quantity = _oi[1],
                            amount   = _oi[0] * _oi[1],
                            count    = 1
                        };

                        _dqo.result.asks.Add(_aoi);
                        _ask.quantity = _oi[1];
                    }
                }

                foreach (var _oi in orderbook.data.bids)
                {
                    var _bid = qob.result.bids.Where(o => o.price == _oi[0]).SingleOrDefault();
                    if (_bid == null)
                    {
                        var _boi = new SOrderBookItem
                        {
                            action   = "insert",
                            price    = _oi[0],
                            quantity = _oi[1],
                            amount   = _oi[0] * _oi[1],
                            count    = 1
                        };

                        _dqo.result.bids.Add(_boi);
                        qob.result.bids.Add(_boi);
                    }
                    else if (_bid.quantity != _oi[1])
                    {
                        var _boi = new SOrderBookItem
                        {
                            action   = "update",
                            price    = _oi[0],
                            quantity = _oi[1],
                            amount   = _oi[0] * _oi[1],
                            count    = 1
                        };

                        _dqo.result.bids.Add(_boi);
                        _bid.quantity = _oi[1];
                    }
                }

                foreach (var _qi in qob.result.asks)
                {
                    var _ask = orderbook.data.asks.Where(o => o[0] == _qi.price).SingleOrDefault();
                    if (_ask == null)
                    {
                        _dqo.result.asks.Add(new SOrderBookItem
                        {
                            action   = "delete",
                            price    = _qi.price,
                            quantity = _qi.quantity,
                            amount   = _qi.price * _qi.quantity,
                            count    = 1
                        });

                        _qi.quantity = 0;
                    }
                }

                foreach (var _qi in qob.result.bids)
                {
                    var _bid = orderbook.data.bids.Where(o => o[0] == _qi.price).SingleOrDefault();
                    if (_bid == null)
                    {
                        _dqo.result.bids.Add(new SOrderBookItem
                        {
                            action   = "delete",
                            price    = _qi.price,
                            quantity = _qi.quantity,
                            amount   = _qi.price * _qi.quantity,
                            count    = 1
                        });

                        _qi.quantity = 0;
                    }
                }

                qob.result.asks.RemoveAll(o => o.quantity == 0);
                qob.result.bids.RemoveAll(o => o.quantity == 0);
            }

            if (++settings.orderbook_count == __bnconfig.OrderBookCounter)
            {
                settings.orderbook_count = 0;

                qob.sequentialId = orderbook.data.lastId;
                await snapshotOrderbook(_dqo.exchange, _dqo.symbol);
            }
            else
            {
                await publishOrderbook(_dqo);
            }

            return(true);
        }