private OhlcData CollectApi(TimeRange range, OhlcData results) { var apiresults = ApiAdapters.Select(x => x.GetRange(range)).FirstOrDefault(o => o.IsNotEmpty()); results = results ?? new OhlcData(range.TimeResolution); results.Merge(apiresults); return(results); }
public override OhlcData Include(TimeRange rangeAttempted, OhlcData data, bool acceptLiveRange = false) { base.Include(rangeAttempted, data, acceptLiveRange); this.SavePublic(); return(data); }
public void Merge(OhlcData data) { foreach (var i in data) { RemoveAll(x => x.DateTimeUtc == i.DateTimeUtc); Add(i); } }
private void RequestFullDaily() { var range = TimeRange.EveryDayTillNow; OverviewOhlc = Request(range, true); if (OverviewOhlc.IsEmpty()) { throw new Exception("Data range missing during " + nameof(Init)); } UtcDataStart = OverviewOhlc.Min(x => x.DateTimeUtc); }
public OhlcData GetRange(TimeRange timeRange) { lock (Lock) { Ctx.Status("Requesting local data @" + Ctx.Network.Name); var seriesId = _adapter.SeriesId; var r = GetDbCollection().Where(x => x.SeriesId == seriesId && x.DateTimeUtcTicks >= timeRange.UtcFrom.Ticks && x.DateTimeUtcTicks <= timeRange.UtcTo.Ticks).ToList(); var d = new OhlcData(timeRange.TimeResolution); d.AddRange(r); return(d); } }
private void StoreResults(TimeRange timeRange, OhlcData results) { var clone = new OhlcData(results); // ienumerable modifications during storage process. if (timeRange.TimeResolution != TimeResolution.Day) { clone.RemoveAll(x => x.DateTimeUtc.IsLive(timeRange.TimeResolution)); } ThreadPool.QueueUserWorkItem(delegate { lock (_storageLock) Parallel.ForEach(StorageAdapters, a => a.StoreRange(clone, timeRange)); }); }
private OhlcData ContinuousOrMergedStorage(TimeRange timeRange, bool allowLive = false) { var partials = new List <OhlcData>(); foreach (var r in StorageAdapters.Select(x => x.GetRange(timeRange))) { if (r.IsEmpty()) { continue; } if (!allowLive) { r.RemoveAll(x => x.CollectedNearLive); } if (r.IsCovering(timeRange)) { return(r.HasGap() ? null : r); } partials.Add(r); } if (!partials.Any()) { return(null); } var mergedData = new OhlcData(partials.First()); mergedData.ConvertedFrom = partials.Select(x => x.ConvertedFrom).FirstOrDefault(x => x != null) ?? mergedData.ConvertedFrom; foreach (var i in partials) { mergedData.Merge(i); } if (!timeRange.IsFromInfinity && mergedData.HasGap()) { return(null); } return(mergedData); }
public OhlcData GetRange(TimeRange timeRange) { lock (Lock) { Ctx.Status("Requesting in-memory data"); var seriesId = _adapter.SeriesId; if (!CoverageMap.Covers(timeRange)) { return(null); } var r = MemoryCache.Where(x => x.SeriesId == seriesId && x.DateTimeUtc >= timeRange.UtcFrom && x.DateTimeUtc <= timeRange.UtcTo).ToList(); var d = new OhlcData(timeRange.TimeResolution); d.AddRange(r); return(d); } }
public void StoreRange(OhlcData data, TimeRange rangeAttempted) { lock (Lock) { if (data == null) { return; } if (CoverageMap.Found.Covers(rangeAttempted)) { return; } Parallel.ForEach(data, x => x.SeriesId = _adapter.SeriesId); MemoryCache.AddRange(data); CoverageMap.Include(rangeAttempted, data); } }
private OhlcData RequestInternal(TimeRange timeRange, bool allowLive = false) { if (!_apiAdapters.Any() && !_storageAdapters.Any()) { return(null); } if (!StorageEnabled && !ApiEnabled) { return(null); } lock (_lock) { OhlcData results = null; if (StorageEnabled) { results = ContinuousOrMergedStorage(timeRange, allowLive); } var hasRemaining = results.IsEmpty() ? null : results.Remaining(timeRange); if (ApiEnabled && (results.IsEmpty() || hasRemaining != null)) { results = CollectApi(hasRemaining ?? timeRange, results); } Ctx.Status(results.IsNotEmpty() ? "Data received, processing." : "No data received."); if (StorageEnabled && results.IsNotEmpty()) { StoreResults(timeRange, results); } return(results); } }
public virtual OhlcData Include(TimeRange rangeAttempted, OhlcData data, bool acceptLiveRange = false) { var range = data.GetTimeRange(rangeAttempted.TimeResolution); if (!acceptLiveRange) { range = range.RemoveLiveRange(); rangeAttempted = rangeAttempted.RemoveLiveRange(); } if (data.IsNotEmpty()) { Found.Add(range); } else { Unavailable.Add(rangeAttempted); } if (!Unavailable.Covers(rangeAttempted) && !Found.Covers(rangeAttempted)) { Requested.Add(rangeAttempted); } var foundMin = Found.MinimumFrom(); var missingMin = Unavailable.MinimumFrom(); var minDate = foundMin < missingMin ? foundMin : missingMin; if (minDate != DateTime.MaxValue) { UtcEarliestEntry = UtcEarliestEntry > minDate ? minDate : UtcEarliestEntry; } return(data); }
public void StoreRange(OhlcData data, TimeRange rangeAttempted) { lock (Lock) { if (data == null) { return; } var isInDb = CoverageMap.Found.Covers(rangeAttempted); if (isInDb) { return; } var seriesId = _adapter.SeriesId; var col = PublicContext.I.GetCollection <OhlcEntry>(); data.ForEach(x => x.SeriesId = seriesId); col.Upsert(data); CoverageMap.Include(rangeAttempted, data); } }
public OhlcData(OhlcData data) : this(data.Resolution, data) { Resolution = data.Resolution; ConvertedFrom = data.ConvertedFrom; Network = data.Network; }
private OhlcData Convert(TimeRange range) { Ctx.Status("Converting @" + Ctx.PrimaryApiProvider.Title + " " + Ctx.CurrencyConversionApiProvider.Title + " [1]"); var pc = new OhlcContext(new AssetPair(Ctx.Pair.Asset1, Ctx.AssetIntermediary), Ctx.TimeResolution, range, L); var r1 = ApiCoordinator.GetOhlc(Ctx.PrimaryApiProvider, pc); if (r1.IsNull) { return(null); } var d1 = r1.Response.OhlcData; Ctx.Status("Converting @" + Ctx.PrimaryApiProvider.Title + " " + Ctx.CurrencyConversionApiProvider.Title + " [2]"); var pc2 = new OhlcContext(new AssetPair(Ctx.AssetIntermediary, Ctx.Pair.Asset2), Ctx.TimeResolution, range, L); var r2 = ApiCoordinator.GetOhlc(Ctx.CurrencyConversionApiProvider, pc2); if (r2.IsNull) { return(null); } var d2 = r2.Response.OhlcData; if (d1.IsEmpty() || d2.IsEmpty()) { return(null); } if (d1.Count != d2.Count) { return(null); } var ohcldata = new OhlcData(_adapter.TimeResolution) { ConvertedFrom = Ctx.AssetIntermediary, Network = Ctx.PrimaryApiProvider.Network }; var seriesid = OhlcUtilities.GetHash(Ctx.Pair, range.TimeResolution, ohcldata.Network); foreach (var i in d1) { var i2 = d2.FirstOrDefault(x => x.DateTimeUtc == i.DateTimeUtc); if (i2 == null) { return(null); } ohcldata.Add(new OhlcEntry(seriesid, i.DateTimeUtc, Ctx.PrimaryApiProvider, Ctx.CurrencyConversionApiProvider, Ctx.AssetIntermediary) { Open = i.Open * i2.Open, Close = i.Close * i2.Close, High = i.High * i2.High, Low = i.Low * i2.Low, VolumeTo = 0, VolumeFrom = i2.VolumeFrom, WeightedAverage = 0 }); } return(ohcldata); }
public OhlcDataResponse(TimeResolution resolution) { OhlcData = new OhlcData(resolution); }