public void GetHistory(GetHistoryCtx aCtx, HistoryAnswerHandler aCallback) { try { double lastPrice = GetLastPrice(aCtx.Request.Selection.Symbol); List <Bar> bars; switch (aCtx.Request.Selection.Periodicity) { case Periodicity.Tick: bars = GenerateTickHistory(aCtx.Request.Selection.Interval, aCtx.MaxBars, lastPrice); break; case Periodicity.Range: bars = GenerateRangeHistory(aCtx.Request.Selection.Interval, aCtx.MaxBars, lastPrice); break; default: bars = GenerateHistory(aCtx.Request.Selection, aCtx.MaxBars, lastPrice); break; } bars.Reverse(); aCallback(aCtx, bars); } catch (Exception e) { WriteToLog("GetHistory", e); } }
public void GetHistory(IDataFeed dataFeed, Selection p, HistoryAnswerHandler callback) { if (p.From == DateTime.MinValue && p.BarCount < 1) //use bar count (and end date if specified) { callback(p, new List <Bar>()); return; } var cached = GetFromtCache(p); if (cached.Count > 0 && p.IsEnoughData(cached)) { cached = p.TrimBars(cached); callback(p, cached); return; } _dataCacheManager.GetHistory(p, dataFeed, (@params, data) => { Add2Cache(p, data); cached = p.TrimBars(data); callback(p, cached); }); }
public void GetHistory(Selection parameters, HistoryAnswerHandler callback) { ThreadPool.QueueUserWorkItem(state => { if (!Generators.TryGetValue(parameters.Symbol, out var generator)) { callback(parameters, new List <Bar>()); return; } if ((parameters.From == DateTime.MinValue || parameters.From == DateTime.MaxValue) && (parameters.To == DateTime.MinValue || parameters.To == DateTime.MaxValue)) { if (parameters.BarCount <= 3) { callback(parameters, new List <Bar>()); return; } parameters.To = DateTime.UtcNow; if (parameters.Timeframe == Timeframe.Minute) { parameters.From = parameters.To.AddMinutes(-1 * 3 * parameters.BarCount * parameters.TimeFactor); } else if (parameters.Timeframe == Timeframe.Hour) { parameters.From = parameters.To.AddHours(-1 * 3 * parameters.BarCount * parameters.TimeFactor); } else if (parameters.Timeframe == Timeframe.Day) { parameters.From = parameters.To.AddDays(-1 * 2 * parameters.BarCount * parameters.TimeFactor); } else { parameters.From = parameters.To.AddDays(-1 * parameters.BarCount * parameters.TimeFactor * 31); } } var bars = generator.GenerateHistory(parameters); callback(parameters, bars); }); }
public void GetHistory(GetHistoryCtx aCtx, HistoryAnswerHandler aCallback) { List <Bar> aBars = new List <Bar>(); //doesn't support if (aCtx.Request.Selection.Periodicity == Periodicity.Tick || aCtx.Request.Selection.Periodicity == Periodicity.Range) { aCallback(aCtx, aBars); return; } try { string aData; if (aCtx.FromF.Year < 1900) { aCtx.FromF = new DateTime(1900, 1, 1); } string aURL = BuildUrl2(aCtx.Request.Selection, aCtx.FromF, aCtx.ToF, aCtx.MaxBars); string dateFormat; int dateColumn; if (aCtx.Request.Selection.Periodicity >= Periodicity.Day) { dateFormat = "yyyy-MM-dd"; dateColumn = 1; } else { dateFormat = "yyyy-MM-dd HH:mm"; dateColumn = 0; } string[] aRows; aData = OpenURL(aURL); aRows = aData.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (string item in aRows) { Bar aBar = new Bar(); string[] aCells = item.Split(','); if (aCells.Length == 7) { aBar.Date = DateTime.ParseExact(aCells[dateColumn], dateFormat, null); aBar.Date = TimeZoneInfo.ConvertTimeToUtc(aBar.Date, TimeZoneInfo);// aBar.Open = Double.Parse(aCells[2], m_Culture.NumberFormat); if (Math.Abs(aBar.Open) < Double.Epsilon) { continue; } aBar.High = Double.Parse(aCells[3], m_Culture.NumberFormat); aBar.Low = Double.Parse(aCells[4], m_Culture.NumberFormat); aBar.Close = Double.Parse(aCells[5], m_Culture.NumberFormat); aBar.Volume = Int64.Parse(aCells[6], m_Culture.NumberFormat); } else { throw new ApplicationException("History response is not valid: " + aData); } aBars.Add(aBar); } aBars.Reverse(); } catch (Exception e) { WriteToLog("GetHistory", e); } if (NeedConvertBars(aCtx)) { aBars = CombineBars(aBars, aCtx.Request.Selection.Periodicity, aCtx.Request.Selection.Interval); } aCallback(aCtx, aBars); }
private void ProcessHistoryResponseAsync(string response, int requestId, Selection originalRequestParameters, HistoryAnswerHandler callback) { var data = ParseHistoricalResponse(response, originalRequestParameters.BidAsk == PriceType.Ask); var neededCount = originalRequestParameters.BarCount; if (originalRequestParameters.Timeframe == Timeframe.Minute) { neededCount = neededCount * originalRequestParameters.TimeFactor; } if (originalRequestParameters.Timeframe == Timeframe.Hour) { neededCount = neededCount * originalRequestParameters.TimeFactor * 60; } if (originalRequestParameters.Timeframe == Timeframe.Day) { neededCount = neededCount * originalRequestParameters.TimeFactor; } if (originalRequestParameters.Timeframe == Timeframe.Month) { neededCount = neededCount * originalRequestParameters.TimeFactor * 30; } if (data.Count < neededCount && originalRequestParameters.From > new DateTime(1970, 1, 1) && originalRequestParameters.BarCount != int.MaxValue) { Logger.Warning($"Received less bars ({data.Count}) than expected ({neededCount}) from {Name} for " + originalRequestParameters.Symbol); } if (originalRequestParameters.BidAsk == PriceType.Bid) { var asksId = requestId + 1; if (_bidAskCache.ContainsKey(asksId)) { var merged = MergeBidAskData(data, _bidAskCache[asksId]); _bidAskCache.TryRemove(asksId, out var removedBars); callback(originalRequestParameters, merged); } else { _bidAskCache[requestId] = data; //hold bids and wait for asks } } else if (originalRequestParameters.BidAsk == PriceType.Ask) { var bidsId = requestId - 1; if (_bidAskCache.ContainsKey(bidsId)) { var merged = MergeBidAskData(_bidAskCache[bidsId], data); _bidAskCache.TryRemove(bidsId, out var removedBars); callback(originalRequestParameters, merged); } else { _bidAskCache[requestId] = data; //hold asks and wait for bids } } }
public void GetHistory(Selection parameters, HistoryAnswerHandler callback) { if (_session == null) { throw new ApplicationException("Can't load history. LMAX data feed is not connected."); } var symbol = parameters.Symbol.ToUpper(); var instrument = Securities.FirstOrDefault(i => i.Symbol.Equals(symbol, StringComparison.OrdinalIgnoreCase)); if (instrument == null) { Logger.Warning($"Invalid symbol {parameters.Symbol} passed for history request over {Name} feed"); return; } lock (_historyRequestHandlers) { if (parameters.To == DateTime.MinValue || parameters.To > DateTime.UtcNow) { parameters.To = DateTime.UtcNow; } //calculate start time if (parameters.From == DateTime.MinValue && parameters.BarCount != int.MaxValue) { if (parameters.BarCount < 3) { callback(parameters, new List <Bar>()); return; } if (parameters.To > DateTime.UtcNow) { parameters.To = DateTime.UtcNow; } if (parameters.Timeframe == Timeframe.Minute) { parameters.From = parameters.To.AddMinutes(-1 * 3 * parameters.BarCount * parameters.TimeFactor); } else if (parameters.Timeframe == Timeframe.Hour) { parameters.From = parameters.To.AddHours(-1 * 3 * parameters.BarCount * parameters.TimeFactor); } else if (parameters.Timeframe == Timeframe.Day) { parameters.From = parameters.To.AddDays(-1 * 2 * parameters.BarCount * parameters.TimeFactor); } else if (parameters.Timeframe == Timeframe.Month) { parameters.From = parameters.To.AddDays(-1 * parameters.BarCount * parameters.TimeFactor * 31); } } parameters.From = TimeZoneInfo.ConvertTimeFromUtc(parameters.From, TimeZoneInfo); parameters.To = TimeZoneInfo.ConvertTimeFromUtc(parameters.To, TimeZoneInfo); var bidParams = (Selection)parameters.Clone(); bidParams.BidAsk = PriceType.Bid; var id = ++_id; _historyRequestHandlers.Add(id, callback); _originalHistoryRequestParameters.Add(id, bidParams); _session?.RequestHistoricMarketData(new AggregateHistoricMarketDataRequest(id, instrument.SecurityId, bidParams.From, bidParams.To, FromPeriodToResolution(bidParams.Timeframe), Format.Csv, Option.Bid), () => { }, FailureCallback); var askParams = (Selection)parameters.Clone(); askParams.BidAsk = PriceType.Ask; id = ++_id; _historyRequestHandlers.Add(id, callback); _originalHistoryRequestParameters.Add(id, askParams); _session?.RequestHistoricMarketData(new AggregateHistoricMarketDataRequest(id, instrument.SecurityId, askParams.From, askParams.To, FromPeriodToResolution(askParams.Timeframe), Format.Csv, Option.Ask), () => { }, FailureCallback); // /*var askHistParams = (Selection)parameters.Clone(); * askHistParams.BidAsk = PriceType.Unspecified; * id = ++_id; * _historyRequestHandlers.Add(id, callback); * _originalHistoryRequestParameters.Add(id, askHistParams); * * _session?.RequestHistoricMarketData(new TopOfBookHistoricMarketDataRequest(id, instrument.SecurityId, askParams.From, askParams.To, Format.Csv), * () => { }, FailureCallback);*/ } }
public void GetHistory(Selection parameters, HistoryAnswerHandler callback) { if (parameters.Timeframe < Timeframe.Minute) { Logger.Warning($"{parameters.Timeframe} time frame is not supported by {Name} data feed"); callback(parameters, new List <Bar>(0)); return; } var symbol = parameters.Symbol.ToUpper(); var instrument = Securities.FirstOrDefault(i => i.Symbol == symbol); var currencyPair = _securities.FirstOrDefault(i => i.Value.Symbol == symbol).Key; if (instrument == null || currencyPair == null) { Logger.Warning($"Invalid symbol {parameters.Symbol} passed for history request over {Name} feed", null); callback(parameters, new List <Bar>(0)); return; } if (parameters.To == DateTime.MinValue || parameters.To > DateTime.UtcNow) { parameters.To = DateTime.UtcNow; } //calculate start time if (parameters.From == DateTime.MinValue && parameters.BarCount != Int32.MaxValue) { if (parameters.BarCount < 3) { callback(parameters, new List <Bar>(0)); return; } if (parameters.Timeframe == Timeframe.Minute) { parameters.From = parameters.To.AddMinutes(-1 * 3 * parameters.BarCount * parameters.TimeFactor); } else if (parameters.Timeframe == Timeframe.Hour) { parameters.From = parameters.To.AddHours(-1 * 3 * parameters.BarCount * parameters.TimeFactor); } else if (parameters.Timeframe == Timeframe.Day) { parameters.From = parameters.To.AddDays(-1 * 2 * parameters.BarCount * parameters.TimeFactor); } else if (parameters.Timeframe == Timeframe.Month) { parameters.From = parameters.To.AddDays(-1 * parameters.BarCount * parameters.TimeFactor * 31); } } var barSize = GetBarSize(parameters.Timeframe, parameters.TimeFactor); Task.Run(async() => { var data = await _api.Markets.GetChartData(currencyPair, barSize, parameters.From, parameters.To); if (data != null && data.Count > 0) { var bars = data.Select(i => new Bar(i.Time, i.Open, i.High, i.Low, i.Close, i.Volume)).ToList(); callback(parameters, bars); } else { callback(parameters, new List <Bar>(0)); } }); }
private void RequestHistoryFromFeed(Selection parameters, IDataFeed dataFeed, HistoryAnswerHandler callback) { if (parameters.Timeframe < Timeframe.Minute) { callback(parameters, new List <Bar>(0)); } else { dataFeed.GetHistory(parameters, callback); } }
public void GetHistory(Selection sel, IDataFeed dataFeed, HistoryAnswerHandler callback) { var p = (Selection)sel.Clone(); var requireGetLatestHistory = true; var key = GetSymbolKey(sel.Symbol, sel.DataFeed); if (p.From == DateTime.MinValue) //use bar count (and end date if specified) { p.To = p.To.Year > 1970 ? p.To : DateTime.MaxValue; switch (p.Timeframe) { case Timeframe.Tick: p.BarCount = p.BarCount * p.TimeFactor + 50; break; case Timeframe.Minute: p.BarCount = p.BarCount * p.TimeFactor + 60; requireGetLatestHistory = !_minuteBars.ContainsKey(key); break; case Timeframe.Hour: p.BarCount = p.BarCount * p.TimeFactor * 60 + 8 * 60; requireGetLatestHistory = !_minuteBars.ContainsKey(key); break; case Timeframe.Day: p.BarCount = p.BarCount * p.TimeFactor + 7; requireGetLatestHistory = !_dailyBars.ContainsKey(key); break; case Timeframe.Month: p.BarCount = p.BarCount * p.TimeFactor * 31 + 31; requireGetLatestHistory = !_dailyBars.ContainsKey(key); break; default: System.Diagnostics.Debug.Assert(false); break; } } var expectedFromDate = (p.Timeframe == Timeframe.Day || p.Timeframe == Timeframe.Month) ? DateTime.UtcNow.AddDays(-p.BarCount) : DateTime.UtcNow.AddMinutes(-p.BarCount); p.TimeFactor = 1; var cache = GetHistoryFromDB(p); if (cache?.Count > 0 && cache.First().Date > cache.Last().Date) { cache.Reverse(); } if (!requireGetLatestHistory && cache != null && p.IsEnoughData(cache)) { cache = CommonHelper.AdjustRawBars(sel.Timeframe, sel.TimeFactor, cache); callback(sel, cache); return; } // var lastDateFromDB = GetUtmostStoreDate(p, false); var firstDateFromDB = GetUtmostStoreDate(p, true); if (lastDateFromDB != DateTime.MinValue && (p.From == DateTime.MinValue || p.From > lastDateFromDB) && (firstDateFromDB != DateTime.MinValue && firstDateFromDB < expectedFromDate)) { p.From = lastDateFromDB; } // RequestHistoryFromFeed(p, dataFeed, (@params, data) => { if (data != null && data.Count > 1) { StoreToDB(p, data); } var combineBars = CommonHelper.CombineBars(data, cache); var compressedBars = CommonHelper.CompressBars(combineBars, sel);//convert to timeframe callback(sel, compressedBars); }); }