public async Task <ApiMarketsResult> GetMarkets(string baseMarket, int hours)
        {
            hours = Math.Min(hours, 168);
            var cacheResult = await CacheService.GetOrSetHybridAsync(CacheKey.ApiMarkets(baseMarket, hours), TimeSpan.FromSeconds(20), async() =>
            {
                var lastTime   = DateTime.UtcNow.AddHours(-hours);
                var tradePairs = await TradePairReader.GetTradePairs().ConfigureAwait(false);
                if (!tradePairs.Any())
                {
                    return new ApiMarketsResult {
                        Error = $"Markets not found", Success = true,
                    }
                }
                ;

                var markets = string.IsNullOrEmpty(baseMarket) ? tradePairs : tradePairs.Where(x => x.BaseSymbol == baseMarket).ToList();
                using (var context = ExchangeDataContextFactory.CreateReadOnlyContext())
                {
                    var allTrades = await context.Trade
                                    .AsNoTracking()
                                    .Where(x => (x.Status == Enums.TradeStatus.Partial || x.Status == Enums.TradeStatus.Pending))
                                    .Select(x => new
                    {
                        TradePairId = x.TradePairId,
                        Type        = x.Type,
                        Rate        = x.Rate,
                        Amount      = x.Amount
                    }).ToListNoLockAsync().ConfigureAwait(false);

                    var allTradeHistory = await context.TradeHistory
                                          .AsNoTracking()
                                          .Where(x => x.Timestamp > lastTime)
                                          .Select(x => new
                    {
                        Id          = x.Id,
                        TradePairId = x.TradePairId,
                        Rate        = x.Rate,
                        Amount      = x.Amount
                    })
                                          .OrderBy(x => x.Id)
                                          .ToListNoLockAsync().ConfigureAwait(false);

                    var results = new ConcurrentBag <ApiMarket>();
                    foreach (var tradePair in markets)
                    {
                        var trades = allTrades
                                     .Where(x => x.TradePairId == tradePair.TradePairId)
                                     .Select(x => new
                        {
                            Type   = x.Type,
                            Rate   = x.Rate,
                            Amount = x.Amount
                        }).ToList();

                        var tradeHistory = allTradeHistory
                                           .Where(x => x.TradePairId == tradePair.TradePairId)
                                           .Select(x => new
                        {
                            Id     = x.Id,
                            Rate   = x.Rate,
                            Amount = x.Amount
                        })
                                           .OrderBy(x => x.Id)
                                           .ToList();

                        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);
                        }

                        results.Add(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(new ApiMarketsResult
                    {
                        Success = true,
                        Data = results.OrderBy(x => x.Label).ToList()
                    });
                }
            });