private void WriteStats(ExternalExchangeOrderbookMessage orderbook, ExternalExchangeOrderbookMessage resultingOrderbook, DateTime now) { var bestPrices = _bestPricesService.Calc(orderbook); var resultingBestPrices = _bestPricesService.Calc(resultingOrderbook); _orderbooksStatusService.SetStatus(orderbook.ExchangeName, orderbook.AssetPairId, new OrderbookStatus(bestPrices.BestBid, bestPrices.BestAsk, resultingBestPrices.BestBid, resultingBestPrices.BestAsk, orderbook.Bids.Count, orderbook.Asks.Count, resultingOrderbook.Bids.Count, resultingOrderbook.Asks.Count, now, OrderbookStatusEnum.Valid)); Trace.Write(TraceLevelGroupEnum.Trace, orderbook.AssetPairId, $"Orderbook from {orderbook.ExchangeName} for {resultingOrderbook.AssetPairId}: " + $"{resultingBestPrices.BestBid}/{resultingBestPrices.BestAsk}", new { ResultingAssetPairId = resultingOrderbook.AssetPairId, Event = "ExternalOrderbookProcessed", Source = orderbook.ExchangeName, bestPrices.BestBid, bestPrices.BestAsk, ResultingBestBid = resultingBestPrices.BestBid, ResultingBestAsk = resultingBestPrices.BestAsk, BidsDepth = orderbook.Bids.Count, AsksDepth = orderbook.Asks.Count, ResultingsBidsDepth = resultingOrderbook.Bids.Count, ResultingsAsksDepth = resultingOrderbook.Asks.Count, }); }
private Orderbook CalculateOrderbook(CrossRateCalcInfo info) { var sourceOrderbook1 = _orderbooks.GetValueOrDefault(info.Source1.Id); // ex: btcusd var sourceOrderbook2 = _orderbooks.GetValueOrDefault(info.Source2.Id); // ex: eurusd if (sourceOrderbook1 == null || sourceOrderbook2 == null) { var reason = "No orderbook for " + (sourceOrderbook1 == null ? info.Source1.Id : info.Source2.Id); Trace.Write(TraceLevelGroupEnum.WarnTrace, info.ResultingPairId, "Skipping generating cross-rate: " + reason, new { Event = "CrossRateSkipped", Reason = reason }); return(null); } var bestPrices1 = _bestPricesService.Calc(sourceOrderbook1); // ex: btcusd var bestPrices2 = _bestPricesService.Calc(sourceOrderbook2); // ex: eurusd var crossBid = GetCrossRate(bestPrices1, bestPrices2, info, true); var crossAsk = GetCrossRate(bestPrices1, bestPrices2, info, false); Trace.Write(TraceLevelGroupEnum.Trace, info.ResultingPairId, "Generating cross-rate", new { Event = "CrossRateGenerated", Bid = crossBid, Ask = crossAsk }); return(new Orderbook(info.ResultingPairId, ImmutableArray.Create(new OrderbookPosition(crossBid, 1)), // in future: calc whole orderbook ImmutableArray.Create(new OrderbookPosition(crossAsk, 1)))); }
private (ImmutableHashSet <string>, ImmutableDictionary <string, ExternalOrderbook>) FindBroken( string assetPairId, ImmutableDictionary <string, ExternalOrderbook> enabledOrderbooks) { if (!_extPricesSettingsService.IsStepEnabled(OrderbookGeneratorStepDomainEnum.FindBroken, assetPairId)) { return(ImmutableHashSet <string> .Empty, enabledOrderbooks); } // 1.7*bid > ask > bid > 0 (see LWDEV-4587) var brokenExchanges = enabledOrderbooks.Values .Where(o => { var bestPrices = _bestPricesService.Calc(o); return(bestPrices.BestBid <= 0 || bestPrices.BestAsk < bestPrices.BestBid || 5m / 3m * bestPrices.BestBid <= bestPrices.BestAsk); }) .Select(o => o.ExchangeName) .ToImmutableHashSet(); var nonBrokenExchanges = enabledOrderbooks.RemoveRange(brokenExchanges); return(brokenExchanges, nonBrokenExchanges); }