public HistoricalOhlcSource(ICacheFactory cacheFactory, BfProductCode productCode, TimeSpan frameSpan, DateTime endFrom, TimeSpan span, string cacheFolderBasePath) { // Create database file if not exists automatically _cache = cacheFactory.GetOhlcCache(productCode, frameSpan); var requestedCount = Convert.ToInt32(span.TotalMinutes / frameSpan.TotalMinutes); endFrom = endFrom.Round(frameSpan); var startTo = endFrom - span + frameSpan; var end = endFrom - span + frameSpan; _source = Observable.Create <IFxOhlcvv>(observer => { var query = _cache.GetOhlcsBackward(endFrom, span); if (query.Count() == requestedCount) { query.ForEach(ohlc => observer.OnNext(ohlc)); } else { // Cryptowatch accepts close-time based range CryptowatchOhlcSource.Get(productCode, frameSpan, endFrom + frameSpan, startTo + frameSpan).OrderByDescending(e => e.Start).ForEach(ohlc => { _cache.Add(new DbHistoricalOhlc(ohlc, frameSpan)); observer.OnNext(ohlc); }); _cache.SaveChanges(); } observer.OnCompleted(); return(() => { }); }); // Cryptowatchの取得リミットに到達していた場合の対処 }
DbSet <DbHistoricalOhlc> GetOhlc(TimeSpan frameSpan) { if (!CryptowatchOhlcSource.IsSupportedFrameSpan(frameSpan)) { throw new NotSupportedException("frame span is not supported."); } var ctx = _ohlcs.GetOrAdd(frameSpan, _ => { var dbFolderPath = Path.Combine(_cacheFolderBasePath, ProductCode.ToString()); Directory.CreateDirectory(dbFolderPath); var dbFileName = string.Format("OHLC_{0}.db3", Convert.ToInt32(frameSpan.TotalMinutes)); return(new OhlcSqliteDbContext("data source=" + Path.Combine(dbFolderPath, dbFileName))); }); return(ctx.Instance); }