private (Orderbook Orderbook, ExchangeQuality PrimaryExchange, string Problem) OnNewOrderbookInternal(
            ExternalOrderbook orderbook)
        {
            var assetPairId = orderbook.AssetPairId;

            if (!_extPricesSettingsService.IsExchangeConfigured(assetPairId, orderbook.ExchangeName))
            {
                Trace.Write(TraceLevelGroupEnum.WarnTrace, assetPairId,
                            $"Skipping not configured exchange {orderbook.ExchangeName}",
                            new { Event = "NotConfiguredExchangeSkipped", orderbook.ExchangeName });
                return(null, null, "Skipping not configured exchange");
            }

            var allOrderbooks = _orderbooksService.AddAndGetByAssetPair(orderbook);
            var now           = orderbook.LastUpdatedTime;

            var(exchangesErrors, validOrderbooks) = MarkExchangesErrors(assetPairId, allOrderbooks, now);
            var primaryExchangeQuality =
                _primaryExchangeService.GetPrimaryExchange(assetPairId, exchangesErrors, now, orderbook.ExchangeName);

            if (primaryExchangeQuality == null)
            {
                return(null, null, "No primary exchange");
            }

            var primaryExchangeName = primaryExchangeQuality.ExchangeName;

            if (primaryExchangeName != orderbook.ExchangeName)
            {
                return(null, primaryExchangeQuality, "Orderbook not from primary exchange");
            }

            if (primaryExchangeQuality.ErrorState == ExchangeErrorStateDomainEnum.Outlier)
            {
                return(null, primaryExchangeQuality, "Primary exchange is an outlier, skipping price update");
            }

            if (!allOrderbooks.TryGetValue(primaryExchangeName, out var primaryOrderbook))
            {
                _log.WriteErrorAsync(nameof(GenerateOrderbookService), null,
                                     new Exception($"{primaryExchangeName} not found in allOrderbooks ({allOrderbooks.Keys.ToJson()})")
                {
                    Data = { { "AssetPairId", assetPairId } }
                });
                return(null, primaryExchangeQuality, "Primary exchange orderbook not found");
            }

            _stopTradesService.FinishCycle(primaryOrderbook, now);
            var resultingOrderbook = Transform(primaryOrderbook, validOrderbooks);

            if (TryFindSkipOrderbookReason(resultingOrderbook) is string reason)
            {
                return(null, primaryExchangeQuality, reason);
            }

            return(resultingOrderbook, primaryExchangeQuality, null);
        }
Esempio n. 2
0
        private void LogCycle(ExternalOrderbook orderbook, [CanBeNull] Orderbook resultingOrderbook, Stopwatch watch,
                              ExchangeQuality primaryExchangeQuality, [CanBeNull] string problem)
        {
            var elapsedMilliseconds = watch.ElapsedMilliseconds;

            if (elapsedMilliseconds > 20)
            {
                _telemetryService.PublishEventMetrics(nameof(GenerateOrderbookService) + '.' + nameof(OnNewOrderbook),
                                                      null,
                                                      new Dictionary <string, double> {
                    { "ProcessingTime", elapsedMilliseconds }
                },
                                                      new Dictionary <string, string>
                {
                    { "AssetPairId", orderbook.AssetPairId },
                    { "Exchange", orderbook.ExchangeName },
                    { "IsPrimary", (orderbook.ExchangeName == primaryExchangeQuality.ExchangeName).ToString() },
                    { "IsSkip", (resultingOrderbook == null).ToString() },
                });
            }

            var bestPrices          = _bestPricesService.Calc(orderbook);
            var resultingBestPrices = resultingOrderbook == null ? null : _bestPricesService.Calc(resultingOrderbook);
            var action = resultingOrderbook == null ? "Skipped" : "Processed";

            Trace.Write(TraceLevelGroupEnum.Trace, orderbook.AssetPairId,
                        $"{action} from {orderbook.ExchangeName}, " +
                        $"primary: {primaryExchangeQuality}, time: {elapsedMilliseconds} ms",
                        new
            {
                Event  = "ExternalOrderbook" + action,
                Reason = problem,
                orderbook.ExchangeName,
                PrimaryExchange     = primaryExchangeQuality,
                ElapsedMilliseconds = elapsedMilliseconds,
                IsSkip = resultingOrderbook == null,
                bestPrices.BestBid,
                bestPrices.BestAsk,
                ResultingBestBid    = resultingBestPrices?.BestBid,
                ResultingBestAsk    = resultingBestPrices?.BestAsk,
                BidsDepth           = orderbook.Bids.Length,
                AsksDepth           = orderbook.Asks.Length,
                ResultingsBidsDepth = resultingOrderbook?.Bids.Length,
                ResultingsAsksDepth = resultingOrderbook?.Asks.Length,
            });
        }