public async Task <ApiMarketResult> GetMarket(string market, int hours) { var tradePair = await GetMarketTradePair(market).ConfigureAwait(false); if (tradePair == null) { return new ApiMarketResult { Error = $"Market {market} not found", Success = true, } } ; hours = Math.Min(hours, 168); var cacheResult = await CacheService.GetOrSetHybridAsync(CacheKey.ApiMarket(hours, tradePair.TradePairId), TimeSpan.FromSeconds(20), async() => { var lastTime = DateTime.UtcNow.AddHours(-hours); using (var context = ExchangeDataContextFactory.CreateReadOnlyContext()) { var trades = await context.Trade .AsNoTracking() .Where(x => x.TradePairId == tradePair.TradePairId && (x.Status == Enums.TradeStatus.Partial || x.Status == Enums.TradeStatus.Pending)) .Select(x => new { Type = x.Type, Rate = x.Rate, Amount = x.Amount }).ToListNoLockAsync().ConfigureAwait(false); var tradeHistory = await context.TradeHistory .AsNoTracking() .Where(x => x.TradePairId == tradePair.TradePairId && x.Timestamp > lastTime) .Select(x => new { Id = x.Id, Rate = x.Rate, Amount = x.Amount }) .OrderBy(x => x.Id) .ToListNoLockAsync().ConfigureAwait(false); var ask = 0m; var bid = 0m; var buyVolume = 0m; var sellVolume = 0m; var buyBaseVolume = 0m; var sellBaseVolume = 0m; if (trades.Any()) { var sellOrders = trades.Where(x => x.Type == Enums.TradeHistoryType.Sell).OrderBy(x => x.Rate).ToList(); if (sellOrders.Any()) { ask = sellOrders.First().Rate; sellVolume = Math.Round(sellOrders.Sum(x => x.Amount), 8); sellBaseVolume = Math.Round(sellOrders.Sum(x => x.Amount *x.Rate), 8); } var buyOrders = trades.Where(x => x.Type == Enums.TradeHistoryType.Buy).OrderByDescending(x => x.Rate).ToList(); if (buyOrders.Any()) { bid = buyOrders.First().Rate; buyVolume = Math.Round(buyOrders.Sum(x => x.Amount), 8); buyBaseVolume = Math.Round(buyOrders.Sum(x => x.Amount *x.Rate), 8); } } var change = 0m; var volume = 0m; var baseVolume = 0m; var open = tradePair.LastTrade; var close = tradePair.LastTrade; var high = tradePair.LastTrade; var low = tradePair.LastTrade; var last = tradePair.LastTrade; if (tradeHistory.Any()) { var firstTrade = tradeHistory.FirstOrDefault(); var lastTrade = tradeHistory.LastOrDefault(); high = tradeHistory.Max(x => x.Rate); low = tradeHistory.Min(x => x.Rate); open = firstTrade.Rate; close = lastTrade.Rate; last = lastTrade.Rate; change = open.GetPercentChanged(close); volume = tradeHistory.Sum(x => x.Amount); baseVolume = Math.Round(tradeHistory.Sum(x => x.Amount *x.Rate), 8); } return(new ApiMarketResult { Success = true, Data = new ApiMarket { Label = tradePair.Market.Replace("_", "/"), TradePairId = tradePair.TradePairId, Change = open.GetPercentChanged(close), AskPrice = ask, BidPrice = bid, BuyVolume = buyVolume, SellVolume = sellVolume, LastPrice = last, High = high, Low = low, Volume = volume, Open = open, Close = close, BaseVolume = baseVolume, BuyBaseVolume = buyBaseVolume, SellBaseVolume = sellBaseVolume } }); } }); return(cacheResult); }