public static long TicksPerPeriod(PriceHistoryPeriod period) { switch (period) { case PriceHistoryPeriod.Minutes15: return(TimeSpan.TicksPerMinute * 15); case PriceHistoryPeriod.Minutes30: return(TimeSpan.TicksPerMinute * 30); case PriceHistoryPeriod.Hour: return(TimeSpan.TicksPerHour); case PriceHistoryPeriod.Hours4: return(TimeSpan.TicksPerHour * 4); case PriceHistoryPeriod.Day: return(TimeSpan.TicksPerDay); case PriceHistoryPeriod.Week: return(TicksPerWeek); default: throw new InvalidOperationException($"{period} doesn't support ticks."); } }
public PriceHistoryPeriodManager(PriceHistoryPeriod period, int market, IAnalyticsStorage analyticsStorage) { this.analyticsStorage = analyticsStorage ?? throw new ArgumentNullException(nameof(analyticsStorage)); Market = market; framesUnit = new MemoryCache(new MemoryCacheOptions { ExpirationScanFrequency = TimeSpan.FromSeconds(15), SizeLimit = 3_000_000 });
/// <summary> /// /// </summary> /// <param name="startTime">Trimmed date time</param> /// <param name="period"></param> public PriceHistoryFrame(DateTime startTime, PriceHistoryPeriod period, int market, double open) { StartTime = UpdatedAt = startTime; Period = period; Market = market; Open = Close = open; }
public static DateTime GetNextFrameDate(this DateTime dateTime, PriceHistoryPeriod period) { switch (period) { case PriceHistoryPeriod.Month: return(dateTime.AddMonths(1)); default: return(dateTime.AddTicks(TicksPerPeriod(period))); } }
public static DateTime Trim(this DateTime dateTime, PriceHistoryPeriod period) { switch (period) { case PriceHistoryPeriod.Month: return(new DateTime(dateTime.Year, dateTime.Month, 1, 0, 0, 0, dateTime.Kind).Date); default: var trimmed = dateTime.Ticks - dateTime.Ticks % TicksPerPeriod(period); return(new DateTime(trimmed, dateTime.Kind)); } }
public Task <int> GetFirstPriceHistoryFrameDate(int market, PriceHistoryPeriod period) { var firstId = PriceHistoryExtensions.EncodeId(market, (int)period, 0); var firstFrame = frames .OrderByDescending(f => f.Id) .FirstOrDefault(f => f.Id >= firstId); if (firstFrame == null) { return(Task.FromResult(0)); } return(Task.FromResult(PriceHistoryExtensions.DecodeId(firstFrame.Id).timestamp)); }
public override void SetValues(string rawValues) { var values = rawValues.Split('-', StringSplitOptions.RemoveEmptyEntries); if (values.Length != 2) //Market, FramePeriod { throw new ArgumentException("Market or FramePeriod property is not specified."); } SetMarket(values[0]); if (!Enum.TryParse <PriceHistoryPeriod>(values[1], out var framePeriod)) { throw new ArgumentException($"{framePeriod} is not valid FramePeriod value."); } FramePeriod = framePeriod; }
public async Task <int> GetFirstPriceHistoryFrameDate(int market, PriceHistoryPeriod period) { var firstId = PriceHistoryExtensions.EncodeId(market, (int)period, 0); var firstFrame = await priceHistoryCollection .Find(Builders <PriceHistoryFrameModel> .Filter.Gte(f => f.Id, firstId)) .SortBy(e => e.Id) .FirstOrDefaultAsync(); if (firstFrame == null) { return(0); } return(PriceHistoryExtensions.DecodeId(firstFrame.Id).timestamp); }
private DateTime GetMinDateForPeriod(PriceHistoryPeriod period) { var date = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc); if (period == PriceHistoryPeriod.Month) { return(date); } while (true) { date = date.AddTicks(PriceHistoryPeriodHelper.TicksPerPeriod(PriceHistoryPeriod.Minutes15)); if (date.Ticks % PriceHistoryPeriodHelper.TicksPerPeriod(period) == 0) { return(date); } } }
/// <summary> /// Get diff between two dates in specified periods. DateTime values must be already trimmed /// </summary> /// <param name="dateFrom"></param> /// <param name="periodDateTime"></param> /// <param name="period"></param> /// <returns></returns> public static int GetDiff(this DateTime dateFrom, DateTime dateTo, PriceHistoryPeriod period) { if (dateFrom > dateTo) { throw new InvalidOperationException("Date from is greater than date to."); } switch (period) { case PriceHistoryPeriod.Month: var totalDiff = 0; while ((dateTo - dateFrom).TotalDays > 0) { dateFrom = dateFrom.AddMonths(1); totalDiff++; } return(totalDiff); default: return((int)Math.Floor(decimal.Divide(dateTo.Ticks - dateFrom.Ticks, TicksPerPeriod(period)))); } }
public static long EncodeAssetTradesResolution(int market, PriceHistoryPeriod period) { return((uint.MaxValue * (long)market) + (int)period); }
/// <summary> /// /// </summary> /// <param name="cursor">Unix timestamp</param> /// <param name="market"></param> /// <param name="framePeriod"></param> /// <returns></returns> public async Task <(List <PriceHistoryFrame> frames, int nextCursor)> GetPriceHistory(int cursor, int market, PriceHistoryPeriod framePeriod) { var managerId = EncodeAssetTradesResolution(market, framePeriod); var cursorDate = cursor == 0 ? default : DateTimeOffset.FromUnixTimeSeconds(cursor).UtcDateTime; var res = await managers[managerId].GetPriceHistoryForDate(cursorDate); return( res.frames, nextCursor: (res.nextCursor == default ? 0 : (int)((DateTimeOffset)res.nextCursor).ToUnixTimeSeconds()) ); }
public Task <List <PriceHistoryFrameModel> > GetPriceHistory(int cursorTimeStamp, int toUnixTimeStamp, int asset, PriceHistoryPeriod period) { var cursorId = PriceHistoryExtensions.EncodeId(asset, (int)period, cursorTimeStamp); var toId = PriceHistoryExtensions.EncodeId(asset, (int)period, toUnixTimeStamp); var result = frames .Where(f => f.Id >= cursorId && f.Id < toId) .OrderByDescending(f => f.Id) .ToList(); return(Task.FromResult(result)); }
public async Task <List <PriceHistoryFrameModel> > GetPriceHistory(int cursorTimeStamp, int toUnixTimeStamp, int asset, PriceHistoryPeriod period) { var cursorId = PriceHistoryExtensions.EncodeId(asset, (int)period, cursorTimeStamp); var toId = PriceHistoryExtensions.EncodeId(asset, (int)period, toUnixTimeStamp); var query = priceHistoryCollection.Find( Builders <PriceHistoryFrameModel> .Filter.And( Builders <PriceHistoryFrameModel> .Filter.Gte(f => f.Id, cursorId), Builders <PriceHistoryFrameModel> .Filter.Lt(f => f.Id, toId) ) ).SortByDescending(x => x.Id); return(await query .ToListAsync()); }