//public async Task UpdatePriceCache(TradePriceUpdate priceUpdate) //{ // var baseCurrency = priceUpdate.Market.Split('_')[1]; // var baseSummary = await GetExchangeSummary().ConfigureAwait(false); // var summary = await GetOrCacheBaseSummary(baseCurrency).ConfigureAwait(false); // var summaryItem = summary.FirstOrDefault(x => x.TradePairId == priceUpdate.TradePairId); // var baseSummaryItem = baseSummary.TopMarkets.FirstOrDefault(x => x.TradePairId == priceUpdate.TradePairId); // if (summaryItem != null) // { // summaryItem.Low = priceUpdate.Low.ToString("F8"); // summaryItem.High = priceUpdate.High.ToString("F8"); // summaryItem.Last = priceUpdate.Last.ToString("F8"); // summaryItem.Change = priceUpdate.Change.ToString("F2"); // summaryItem.Volume = priceUpdate.Volume.ToString("F8"); // summaryItem.BaseVolume = priceUpdate.BaseVolume.ToString("F8"); // } // baseSummary.TotalTrades++; // if (baseSummaryItem != null) // { // baseSummaryItem.TotalTrades++; // baseSummaryItem.Change = priceUpdate.Change; // baseSummaryItem.Volume = priceUpdate.Volume; // baseSummaryItem.TotalBase = priceUpdate.BaseVolume; // baseSummaryItem.High = priceUpdate.High; // baseSummaryItem.Low = priceUpdate.Low; // } // await CacheService.UpdateAsync(CacheKey.ExchangeSummary(), baseSummary); // await CacheService.UpdateAsync(CacheKey.ExchangeSummary(baseCurrency), summary); //} public async Task <StockChartDataModel> GetStockChart(int tradePairId, int dataRange, int dataGroup) { var cacheRange = GetCacheRange(dataRange); var cacheResult = await CacheService.GetOrSetHybridAsync(CacheKey.ExchangeStockChart(tradePairId, cacheRange, dataGroup), TimeSpan.FromMinutes(1), async() => { using (var context = ExchangeDataContextFactory.CreateReadOnlyContext()) { Entity.TradeHistory lastTrade; var minutes = dataGroup; //minuteGroups; var chartData = new ConcurrentBag <decimal[]>(); var lastTime = GetChartRange(cacheRange); var tradePairData = await context.TradeHistory .AsNoTracking() .Where(th => th.TradePairId == tradePairId && th.Timestamp >= lastTime) .OrderBy(x => x.Id) //.Take(10000) .Select(th => new { Timestamp = th.Timestamp, Rate = th.Rate, Amount = th.Amount }).ToListNoLockAsync().ConfigureAwait(false); if (tradePairData.IsNullOrEmpty()) { lastTrade = await context.TradeHistory .AsNoTracking() .Where(th => th.TradePairId == tradePairId) .OrderByDescending(x => x.Id) .FirstOrDefaultNoLockAsync().ConfigureAwait(false); if (lastTrade == null) { return(new StockChartDataModel { Candle = new List <decimal[]> { new decimal[] { 0, 0, 0, 0, 0, 0 } }, Volume = new List <VolumePoint> { new VolumePoint { x = 0, y = 0, basev = 0 } } }); } var lastfinish = DateTime.UtcNow; var lasttotalhours = (int)(lastfinish - lastTime).TotalMinutes / minutes; for (int i = 0; i < lasttotalhours; i++) { chartData.Add(new[] { lastfinish.AddMinutes(-(minutes * i)).ToJavaTime(), lastTrade.Rate, lastTrade.Rate, lastTrade.Rate, lastTrade.Rate, 0, 0 }); } } else { var start = tradePairData.Min(x => x.Timestamp); var finish = DateTime.UtcNow; var totalhours = (int)(finish - start).TotalMinutes / minutes; var interval = TimeSpan.FromMinutes(minutes); var dataTest = tradePairData.GroupBy(cr => new { cr.Timestamp.Year, Month = minutes >= 43200 ? (cr.Timestamp.Month / (minutes / 43200)) : cr.Timestamp.Month, Day = minutes >= 1440 ? (cr.Timestamp.Day / (minutes / 1440)) : cr.Timestamp.Day, Hour = minutes >= 60 ? (cr.Timestamp.Hour / (minutes / 60)) : cr.Timestamp.Hour, Minute = minutes < 60 ? (cr.Timestamp.Minute / minutes) * minutes : 0 }).Select(g => new[] { g.Last().Timestamp.ToJavaTime(), g.First().Rate, g.Max(x => x.Rate), g.Min(x => x.Rate), g.Last().Rate, g.Sum(x => x.Amount), g.Sum(x => x.Amount *x.Rate) }).ToList(); for (int i = 0; i < totalhours; i++) { var currentInterval = finish.AddMinutes(-(minutes *i)); var rangeEnd = currentInterval.ToJavaTime(); var rangeStart = currentInterval.Subtract(interval).ToJavaTime(); var data = dataTest.FirstOrDefault(x => x[0] >= rangeStart && x[0] <= rangeEnd); if (data.IsNullOrEmpty()) { var lastClose = dataTest.LastOrDefault(x => x[0] < rangeEnd)?[4] ?? 0m; chartData.Add(new[] { rangeEnd, lastClose, lastClose, lastClose, lastClose, 0, 0 }); } else { data[0] = rangeEnd; chartData.Add(data); } } } var resultData = chartData.OrderBy(x => x[0]); var val = new StockChartDataModel { Candle = resultData.Select(x => new[] { x[0], x[1], x[2], x[3], x[4] }).ToList(), Volume = resultData.Select(x => new VolumePoint { x = x[0], y = x[5], basev = x[6] }).ToList() }; return(val); } }).ConfigureAwait(false); return(cacheResult); }