Esempio n. 1
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);
        }
Esempio n. 2
0
        public async ValueTask OStart(CancellationToken cancelToken, string symbol)
        {
            BNLogger.SNG.WriteO(this, $"polling service start: symbol => {symbol}...");

            if (__bnconfig.UsePollingTicker == false)
            {
                PollingTasks.Add(Task.Run(async() =>
                {
                    var _client = CreateJsonClient(publicApi.publicClient.ApiUrl);

                    var _o_params = new Dictionary <string, object>();
                    {
                        _o_params.Add("symbol", symbol.ToUpper());
                        _o_params.Add("limit", 20);
                    }

                    var _o_request             = CreateJsonRequest($"/depth", _o_params);
                    var _last_limit_milli_secs = 0L;

                    while (true)
                    {
                        try
                        {
                            await Task.Delay(0);

                            var _waiting_milli_secs = (CUnixTime.NowMilli - __bnconfig.PollingPrevTime) / __bnconfig.PollingTermTime;
                            if (_waiting_milli_secs == _last_limit_milli_secs)
                            {
                                var _waiting = cancelToken.WaitHandle.WaitOne(0);
                                if (_waiting == true)
                                {
                                    break;
                                }

                                await Task.Delay(10);
                            }
                            else
                            {
                                _last_limit_milli_secs = _waiting_milli_secs;

                                // orderbook
                                var _o_json_value = await RestExecuteAsync(_client, _o_request);
                                if (_o_json_value.IsSuccessful && _o_json_value.Content[0] == '{')
                                {
                                    var _o_json_data    = JsonConvert.DeserializeObject <BAOrderBookItem>(_o_json_value.Content);
                                    _o_json_data.symbol = symbol;
                                    _o_json_data.lastId = _last_limit_milli_secs;

                                    var _orderbook = new BAOrderBook
                                    {
                                        stream = "orderbook",
                                        data   = _o_json_data
                                    };

                                    var _o_json_content = JsonConvert.SerializeObject(_orderbook);
                                    Processing.SendReceiveQ(new QMessage {
                                        command = "AP", payload = _o_json_content
                                    });
                                }
                                else
                                {
                                    var _http_status = (int)_o_json_value.StatusCode;
                                    if (_http_status == 403 || _http_status == 418 || _http_status == 429)
                                    {
                                        BNLogger.SNG.WriteQ(this, $"request-limit: symbol => {symbol}, https_status => {_http_status}");

                                        var _waiting = cancelToken.WaitHandle.WaitOne(0);
                                        if (_waiting == true)
                                        {
                                            break;
                                        }

                                        await Task.Delay(1000);     // waiting 1 second
                                    }
                                }
                            }
                        }
                        catch (TaskCanceledException)
                        {
                        }
                        catch (Exception ex)
                        {
                            BNLogger.SNG.WriteX(this, ex.ToString());
                        }
                        //finally
                        {
                            //__semaphore.Release();

                            if (cancelToken.IsCancellationRequested == true)
                            {
                                break;
                            }
                        }

                        var _cancelled = cancelToken.WaitHandle.WaitOne(0);
                        if (_cancelled == true)
                        {
                            break;
                        }
                    }
                },
                                          cancelToken
                                          ));
            }

            await Task.WhenAll(PollingTasks);

            BNLogger.SNG.WriteO(this, $"polling service stopped: symbol => {symbol}...");
        }
Esempio n. 3
0
        private async ValueTask <bool> mergeOrderbook(BAOrderBook orderbook)
        {
            var _result = false;

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

            if (__qOrderBooks.ContainsKey(orderbook.data.symbol) == false)
            {
                _settings.last_orderbook_id = orderbook.data.lastId;

                var _sqo = new SOrderBooks
                {
                    exchange     = BNLogger.SNG.exchange_name,
                    stream       = "snapshot",
                    symbol       = orderbook.data.symbol,
                    sequentialId = orderbook.data.lastId,
                    result       = new SOrderBook()
                };

                foreach (var _oi in orderbook.data.asks)
                {
                    _sqo.result.asks.Add(new SOrderBookItem
                    {
                        action   = "insert",
                        price    = _oi[0],
                        quantity = _oi[1],
                        amount   = _oi[0] * _oi[1],
                        count    = 1
                    });
                }

                foreach (var _oi in orderbook.data.bids)
                {
                    _sqo.result.bids.Add(new SOrderBookItem
                    {
                        action   = "insert",
                        price    = _oi[0],
                        quantity = _oi[1],
                        amount   = _oi[0] * _oi[1],
                        count    = 1
                    });
                }

                __qOrderBooks[_sqo.symbol] = _sqo;

                await publishOrderbook(_sqo);

                _settings.orderbook_count = 0;

                _result = true;
            }
            else if (_settings.last_orderbook_id < orderbook.data.lastId)
            {
                _settings.last_orderbook_id = orderbook.data.lastId;

                var _qob = __qOrderBooks[orderbook.data.symbol];

                var _current_ask_size = orderbook.data.asks.Sum(o => o[1]);
                var _current_bid_size = orderbook.data.bids.Sum(o => o[1]);

                if (_settings.last_order_ask_size != _current_ask_size || _settings.last_order_bid_size != _current_bid_size)
                {
                    if (_settings.before_trade_ask_size != _current_ask_size || _settings.before_trade_bid_size != _current_bid_size)
                    {
                        _result = await updateOrderbook(_qob, orderbook, _settings);

                        _settings.last_order_ask_size = _qob.result.asks.Sum(o => o.quantity);
                        _settings.last_order_bid_size = _qob.result.bids.Sum(o => o.quantity);
#if DEBUG
                        // modified check
                        if (_current_ask_size != _settings.last_order_ask_size || _current_bid_size != _settings.last_order_bid_size)
                        {
                            BNLogger.SNG.WriteQ(this, $"diffb-{orderbook.stream}: timestamp => {_settings.last_orderbook_id}, symbol => {orderbook.data.symbol}, ask_size => {_current_ask_size}, {_settings.last_order_ask_size}, bid_size => {_current_bid_size}, {_settings.last_order_bid_size}");
                        }

                        if (_qob.result.asks.Count + _qob.result.bids.Count != 40)
                        {
                            var _ask_count = _qob.result.asks.Count();
                            var _bid_count = _qob.result.bids.Count();

                            BNLogger.SNG.WriteQ(this, $"diffb-{orderbook.stream}: timestamp => {_settings.last_orderbook_id}, symbol => {orderbook.data.symbol}, ask_count => {_ask_count}, bid_count => {_bid_count}");
                        }
#endif
                    }
                    else
                    {
                        BNLogger.SNG.WriteQ(this, $"trade-{orderbook.stream}: timestamp => {_settings.last_orderbook_id}, symbol => {orderbook.data.symbol}, ask_size => {_current_ask_size}, bid_size => {_current_bid_size}");
                    }
                }
                else
                {
                    BNLogger.SNG.WriteQ(this, $"equal-{orderbook.stream}: timestamp => {_settings.last_orderbook_id}, symbol => {orderbook.data.symbol}, ask_size => {_current_ask_size}, bid_size => {_current_bid_size}");
                }
            }

            return(_result);
        }