Ejemplo n.º 1
0
        //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);
        }