/// <summary> /// Gets the history for the requested securities /// </summary> /// <param name="requests">The historical data requests</param> /// <param name="sliceTimeZone">The time zone used when time stamping the slice instances</param> /// <returns>An enumerable of the slices of data covering the span specified in each request</returns> public IEnumerable <Slice> GetHistory(IEnumerable <HistoryRequest> requests, DateTimeZone sliceTimeZone) { foreach (var request in requests) { var interval = ToFxcmInterval(request.Resolution); // download data var history = new List <BaseData>(); var end = request.EndTimeUtc; var attempt = 1; while (end > request.StartTimeUtc) { _lastHistoryChunk.Clear(); var mdr = new MarketDataRequest(); mdr.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SNAPSHOT); mdr.setResponseFormat(IFixMsgTypeDefs.__Fields.MSGTYPE_FXCMRESPONSE); mdr.setFXCMTimingInterval(interval); mdr.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); mdr.setFXCMStartDate(new UTCDate(ToJavaDateUtc(request.StartTimeUtc))); mdr.setFXCMStartTime(new UTCTimeOnly(ToJavaDateUtc(request.StartTimeUtc))); mdr.setFXCMEndDate(new UTCDate(ToJavaDateUtc(end))); mdr.setFXCMEndTime(new UTCTimeOnly(ToJavaDateUtc(end))); mdr.addRelatedSymbol(_fxcmInstruments[_symbolMapper.GetBrokerageSymbol(request.Symbol)]); AutoResetEvent autoResetEvent; lock (_locker) { _currentRequest = _gateway.sendMessage(mdr); autoResetEvent = new AutoResetEvent(false); _mapRequestsToAutoResetEvents[_currentRequest] = autoResetEvent; _pendingHistoryRequests.Add(_currentRequest); } if (!autoResetEvent.WaitOne(HistoryResponseTimeout)) { // no response if (++attempt > MaximumHistoryRetryAttempts) { break; } continue; } // Add data lock (_locker) { history.InsertRange(0, _lastHistoryChunk); } var firstDateUtc = _lastHistoryChunk[0].Time.ConvertToUtc(_configTimeZone); if (end != firstDateUtc) { // new end date = first datapoint date. end = request.Resolution == Resolution.Tick ? firstDateUtc.AddMilliseconds(-1) : firstDateUtc.AddSeconds(-1); if (request.StartTimeUtc.AddSeconds(1) >= end) { break; } } else { break; } } DataPointCount += history.Count; foreach (var data in history) { yield return(new Slice(data.EndTime, new[] { data })); } } }
/// <summary> /// Gets the history for the requested security /// </summary> /// <param name="request">The historical data request</param> /// <returns>An enumerable of bars covering the span specified in the request</returns> public override IEnumerable <BaseData> GetHistory(HistoryRequest request) { if (!_symbolMapper.IsKnownLeanSymbol(request.Symbol)) { Log.Trace("FxcmBrokerage.GetHistory(): Invalid symbol: {0}, no history returned", request.Symbol.Value); yield break; } // cache exchange time zone for symbol DateTimeZone exchangeTimeZone; if (!_symbolExchangeTimeZones.TryGetValue(request.Symbol, out exchangeTimeZone)) { exchangeTimeZone = MarketHoursDatabase.FromDataFolder().GetExchangeHours(Market.FXCM, request.Symbol, request.Symbol.SecurityType).TimeZone; _symbolExchangeTimeZones.Add(request.Symbol, exchangeTimeZone); } var interval = ToFxcmInterval(request.Resolution); // download data var history = new List <BaseData>(); var lastEndTime = DateTime.MinValue; var end = request.EndTimeUtc; var attempt = 1; while (end > request.StartTimeUtc) { Log.Debug(string.Format("FxcmBrokerage.GetHistory(): Requesting {0:O} to {1:O}", end, request.StartTimeUtc)); _lastHistoryChunk.Clear(); var mdr = new MarketDataRequest(); mdr.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SNAPSHOT); mdr.setResponseFormat(IFixMsgTypeDefs.__Fields.MSGTYPE_FXCMRESPONSE); mdr.setFXCMTimingInterval(interval); mdr.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); mdr.setFXCMStartDate(new UTCDate(ToJavaDateUtc(request.StartTimeUtc))); mdr.setFXCMStartTime(new UTCTimeOnly(ToJavaDateUtc(request.StartTimeUtc))); mdr.setFXCMEndDate(new UTCDate(ToJavaDateUtc(end))); mdr.setFXCMEndTime(new UTCTimeOnly(ToJavaDateUtc(end))); mdr.addRelatedSymbol(_fxcmInstruments[_symbolMapper.GetBrokerageSymbol(request.Symbol)]); AutoResetEvent autoResetEvent; lock (_locker) { _currentRequest = _gateway.sendMessage(mdr); autoResetEvent = new AutoResetEvent(false); _mapRequestsToAutoResetEvents[_currentRequest] = autoResetEvent; _pendingHistoryRequests.Add(_currentRequest); } if (!autoResetEvent.WaitOne(HistoryResponseTimeout)) { // No response can mean genuine timeout or the history data has ended. // 90% of the time no response because no data; widen the search net to 5m if we don't get a response: if (request.StartTimeUtc.AddSeconds(300) >= end) { break; } // 5% of the time its because the data ends at a specific, repeatible time not close to our desired endtime: if (end == lastEndTime) { Log.Trace("FxcmBrokerage.GetHistory(): Request for {0} ended at {1:O}", request.Symbol.Value, end); break; } // 5% of the time its because of an internet / time of day / api settings / timeout: throw if this is the *second* attempt. if (EnableOnlyHistoryRequests && lastEndTime != DateTime.MinValue) { throw new TimeoutException(string.Format("FxcmBrokerage.GetHistory(): History operation ending in {0:O} took longer than {1} seconds. This may be because there is no data, retrying...", end, (decimal)HistoryResponseTimeout / 1000)); } // Assuming Timeout: If we've already retried quite a few times, lets bail. if (++attempt > MaximumHistoryRetryAttempts) { Log.Trace("FxcmBrokerage.GetHistory(): Maximum attempts reached for: " + request.Symbol.Value); break; } // Assuming Timeout: Save end time and if have the same endtime next time, break since its likely there's no data after that time. lastEndTime = end; Log.Trace("FxcmBrokerage.GetHistory(): Attempt " + attempt + " for: " + request.Symbol.Value + " ended at " + lastEndTime.ToString("O")); continue; } // Add data lock (_locker) { history.InsertRange(0, _lastHistoryChunk); } var firstDateUtc = _lastHistoryChunk[0].Time.ConvertToUtc(exchangeTimeZone); if (end != firstDateUtc) { // new end date = first datapoint date. end = request.Resolution == Resolution.Tick ? firstDateUtc.AddMilliseconds(-1) : firstDateUtc.AddSeconds(-1); if (request.StartTimeUtc.AddSeconds(10) >= end) { break; } } else { break; } } foreach (var data in history) { yield return(data); } }
/// <summary> /// Get historical data enumerable for a single symbol, type and resolution given this start and end time (in UTC). /// </summary> /// <param name="symbol">Symbol for the data we're looking for.</param> /// <param name="resolution">Resolution of the data request</param> /// <param name="startUtc">Start time of the data in UTC</param> /// <param name="endUtc">End time of the data in UTC</param> /// <returns>Enumerable of base data for this symbol</returns> public IEnumerable<BaseData> Get(Symbol symbol, Resolution resolution, DateTime startUtc, DateTime endUtc) { if (!_symbolMapper.IsKnownLeanSymbol(symbol)) throw new ArgumentException("Invalid symbol requested: " + symbol.Value); if (symbol.ID.SecurityType != SecurityType.Forex && symbol.ID.SecurityType != SecurityType.Cfd) throw new NotSupportedException("SecurityType not available: " + symbol.ID.SecurityType); if (endUtc <= startUtc) throw new ArgumentException("The end date must be greater than the start date."); Console.WriteLine("Logging in..."); // create the gateway _gateway = GatewayFactory.createGateway(); // register the message listeners with the gateway _gateway.registerGenericMessageListener(this); _gateway.registerStatusMessageListener(this); // create local login properties var loginProperties = new FXCMLoginProperties(_userName, _password, _terminal, _server); // log in _gateway.login(loginProperties); // initialize session RequestTradingSessionStatus(); Console.WriteLine("Downloading {0} data from {1} to {2}...", resolution, startUtc.ToString("yyyyMMdd HH:mm:ss"), endUtc.ToString("yyyyMMdd HH:mm:ss")); // Find best FXCM parameters var interval = FxcmBrokerage.ToFxcmInterval(resolution); var totalTicks = (endUtc - startUtc).Ticks; // download data var totalBaseData = new List<BaseData>(); var end = endUtc; do // { //show progress progressBar(Math.Abs((end - endUtc).Ticks), totalTicks, Console.WindowWidth / 2,'█'); _currentBaseData.Clear(); var mdr = new MarketDataRequest(); mdr.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SNAPSHOT); mdr.setResponseFormat(IFixMsgTypeDefs.__Fields.MSGTYPE_FXCMRESPONSE); mdr.setFXCMTimingInterval(interval); mdr.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); mdr.setFXCMStartDate(new UTCDate(FxcmBrokerage.ToJavaDateUtc(startUtc))); mdr.setFXCMStartTime(new UTCTimeOnly(FxcmBrokerage.ToJavaDateUtc(startUtc))); mdr.setFXCMEndDate(new UTCDate(FxcmBrokerage.ToJavaDateUtc(end))); mdr.setFXCMEndTime(new UTCTimeOnly(FxcmBrokerage.ToJavaDateUtc(end))); mdr.addRelatedSymbol(_fxcmInstruments[_symbolMapper.GetBrokerageSymbol(symbol)]); AutoResetEvent autoResetEvent; lock (_locker) { _currentRequest = _gateway.sendMessage(mdr); autoResetEvent = new AutoResetEvent(false); _mapRequestsToAutoResetEvents[_currentRequest] = autoResetEvent; } if (!autoResetEvent.WaitOne(1000 * 5)) { // no response, exit break; } // Add data totalBaseData.InsertRange(0, _currentBaseData.Where(x => x.Time.Date >= startUtc.Date)); if (end != _currentBaseData[0].Time) { // new end date = first datapoint date. end = _currentBaseData[0].Time; } else { break; } } while (end > startUtc); Console.WriteLine("\nLogging out..."); // log out _gateway.logout(); // remove the message listeners _gateway.removeGenericMessageListener(this); _gateway.removeStatusMessageListener(this); return totalBaseData.ToList(); }
/// <summary> /// Get historical data enumerable for a single symbol, type and resolution given this start and end time (in UTC). /// </summary> /// <param name="symbol">Symbol for the data we're looking for.</param> /// <param name="resolution">Resolution of the data request</param> /// <param name="startUtc">Start time of the data in UTC</param> /// <param name="endUtc">End time of the data in UTC</param> /// <returns>Enumerable of base data for this symbol</returns> public IEnumerable <BaseData> Get(Symbol symbol, Resolution resolution, DateTime startUtc, DateTime endUtc) { if (!_symbolMapper.IsKnownLeanSymbol(symbol)) { throw new ArgumentException("Invalid symbol requested: " + symbol.Value); } if (symbol.ID.SecurityType != SecurityType.Forex && symbol.ID.SecurityType != SecurityType.Cfd) { throw new NotSupportedException("SecurityType not available: " + symbol.ID.SecurityType); } if (endUtc <= startUtc) { throw new ArgumentException("The end date must be greater than the start date."); } Console.WriteLine("Logging in..."); // create the gateway _gateway = GatewayFactory.createGateway(); // register the message listeners with the gateway _gateway.registerGenericMessageListener(this); _gateway.registerStatusMessageListener(this); // create local login properties var loginProperties = new FXCMLoginProperties(_userName, _password, _terminal, _server); // log in _gateway.login(loginProperties); // initialize session RequestTradingSessionStatus(); Console.WriteLine("Downloading {0} data from {1} to {2}...", resolution, startUtc.ToString("yyyyMMdd HH:mm:ss"), endUtc.ToString("yyyyMMdd HH:mm:ss")); // Find best FXCM parameters var interval = FxcmBrokerage.ToFxcmInterval(resolution); var totalTicks = (endUtc - startUtc).Ticks; // download data var totalBaseData = new List <BaseData>(); var end = endUtc; do // { //show progress progressBar(Math.Abs((end - endUtc).Ticks), totalTicks, Console.WindowWidth / 2, '█'); _currentBaseData.Clear(); var mdr = new MarketDataRequest(); mdr.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SNAPSHOT); mdr.setResponseFormat(IFixMsgTypeDefs.__Fields.MSGTYPE_FXCMRESPONSE); mdr.setFXCMTimingInterval(interval); mdr.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); mdr.setFXCMStartDate(new UTCDate(FxcmBrokerage.ToJavaDateUtc(startUtc))); mdr.setFXCMStartTime(new UTCTimeOnly(FxcmBrokerage.ToJavaDateUtc(startUtc))); mdr.setFXCMEndDate(new UTCDate(FxcmBrokerage.ToJavaDateUtc(end))); mdr.setFXCMEndTime(new UTCTimeOnly(FxcmBrokerage.ToJavaDateUtc(end))); mdr.addRelatedSymbol(_fxcmInstruments[_symbolMapper.GetBrokerageSymbol(symbol)]); AutoResetEvent autoResetEvent; lock (_locker) { _currentRequest = _gateway.sendMessage(mdr); autoResetEvent = new AutoResetEvent(false); _mapRequestsToAutoResetEvents[_currentRequest] = autoResetEvent; } if (!autoResetEvent.WaitOne(1000 * 5)) { // no response, exit break; } // Add data totalBaseData.InsertRange(0, _currentBaseData.Where(x => x.Time.Date >= startUtc.Date)); if (end != _currentBaseData[0].Time) { // new end date = first datapoint date. end = _currentBaseData[0].Time; } else { break; } } while (end > startUtc); Console.WriteLine("\nLogging out..."); // log out _gateway.logout(); // remove the message listeners _gateway.removeGenericMessageListener(this); _gateway.removeStatusMessageListener(this); return(totalBaseData.ToList()); }
/// <summary> /// Get historical data enumerable for a single symbol, type and resolution given this start and end time (in UTC). /// </summary> /// <param name="symbol">Symbol for the data we're looking for.</param> /// <param name="resolution">Resolution of the data request</param> /// <param name="startUtc">Start time of the data in UTC</param> /// <param name="endUtc">End time of the data in UTC</param> /// <returns>Enumerable of base data for this symbol</returns> public IEnumerable<BaseData> Get(Symbol symbol, Resolution resolution, DateTime startUtc, DateTime endUtc) { if (!_symbolMapper.IsKnownLeanSymbol(symbol)) throw new ArgumentException("Invalid symbol requested: " + symbol.Value); if (resolution == Resolution.Tick) throw new NotSupportedException("Resolution not available: " + resolution); if (symbol.ID.SecurityType != SecurityType.Forex && symbol.ID.SecurityType != SecurityType.Cfd) throw new NotSupportedException("SecurityType not available: " + symbol.ID.SecurityType); if (endUtc < startUtc) throw new ArgumentException("The end date must be greater or equal than the start date."); Console.WriteLine("Logging in..."); // create the gateway _gateway = GatewayFactory.createGateway(); // register the message listeners with the gateway _gateway.registerGenericMessageListener(this); _gateway.registerStatusMessageListener(this); // create local login properties var loginProperties = new FXCMLoginProperties(_userName, _password, _terminal, _server); // log in _gateway.login(loginProperties); // initialize session RequestTradingSessionStatus(); Console.WriteLine("Downloading data from {0} to {1}...", startUtc.ToShortDateString(), endUtc.ToShortDateString()); // download bars var totalBars = new List<TradeBar>(); // calculate the maximum time span for one request (using 10-second bars) const int maxBarsPerRequest = 300; var timeSpanPerRequest = TimeSpan.FromSeconds(maxBarsPerRequest * 10); var start = startUtc; var end = startUtc + timeSpanPerRequest; // request loop while (start < endUtc.AddDays(1)) { _currentBars.Clear(); var mdr = new MarketDataRequest(); mdr.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SNAPSHOT); mdr.setResponseFormat(IFixMsgTypeDefs.__Fields.MSGTYPE_FXCMRESPONSE); mdr.setFXCMTimingInterval(FXCMTimingIntervalFactory.SEC10); mdr.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); mdr.setFXCMStartDate(new UTCDate(ToJavaDateUtc(start))); mdr.setFXCMStartTime(new UTCTimeOnly(ToJavaDateUtc(start))); mdr.setFXCMEndDate(new UTCDate(ToJavaDateUtc(end))); mdr.setFXCMEndTime(new UTCTimeOnly(ToJavaDateUtc(end))); mdr.addRelatedSymbol(_fxcmInstruments[_symbolMapper.GetBrokerageSymbol(symbol)]); AutoResetEvent autoResetEvent; lock (_locker) { _currentRequest = _gateway.sendMessage(mdr); autoResetEvent = new AutoResetEvent(false); _mapRequestsToAutoResetEvents[_currentRequest] = autoResetEvent; } if (!autoResetEvent.WaitOne(1000)) { // no response, continue loop start = end.AddSeconds(10); // if saturday, fast-forward to sunday if (start.DayOfWeek == DayOfWeek.Saturday) start = start.AddDays(1); end = start + timeSpanPerRequest; continue; } var lastBarTime = _currentBars[_currentBars.Count - 1].Time; if (lastBarTime < start) { // no more data available, exit loop break; } // add bars received totalBars.AddRange(_currentBars.Where(x => x.Time.Date <= endUtc.Date)); // calculate time span for next request start = lastBarTime.AddSeconds(10); end = start + timeSpanPerRequest; if (start >= DateTime.UtcNow) { // data in the future not available, exit loop break; } } Console.WriteLine("Logging out..."); // log out _gateway.logout(); // remove the message listeners _gateway.removeGenericMessageListener(this); _gateway.removeStatusMessageListener(this); switch (resolution) { case Resolution.Second: foreach (var bar in totalBars) yield return bar; break; case Resolution.Minute: case Resolution.Hour: case Resolution.Daily: foreach (var bar in AggregateBars(symbol, totalBars, resolution.ToTimeSpan())) yield return bar; break; } }
/// <summary> /// Gets the history for the requested securities /// </summary> /// <param name="requests">The historical data requests</param> /// <param name="sliceTimeZone">The time zone used when time stamping the slice instances</param> /// <returns>An enumerable of the slices of data covering the span specified in each request</returns> public IEnumerable<Slice> GetHistory(IEnumerable<HistoryRequest> requests, DateTimeZone sliceTimeZone) { foreach (var request in requests) { var interval = ToFxcmInterval(request.Resolution); // download data var history = new List<BaseData>(); var end = request.EndTimeUtc; var attempt = 1; while (end > request.StartTimeUtc) { _lastHistoryChunk.Clear(); var mdr = new MarketDataRequest(); mdr.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SNAPSHOT); mdr.setResponseFormat(IFixMsgTypeDefs.__Fields.MSGTYPE_FXCMRESPONSE); mdr.setFXCMTimingInterval(interval); mdr.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); mdr.setFXCMStartDate(new UTCDate(ToJavaDateUtc(request.StartTimeUtc))); mdr.setFXCMStartTime(new UTCTimeOnly(ToJavaDateUtc(request.StartTimeUtc))); mdr.setFXCMEndDate(new UTCDate(ToJavaDateUtc(end))); mdr.setFXCMEndTime(new UTCTimeOnly(ToJavaDateUtc(end))); mdr.addRelatedSymbol(_fxcmInstruments[_symbolMapper.GetBrokerageSymbol(request.Symbol)]); AutoResetEvent autoResetEvent; lock (_locker) { _currentRequest = _gateway.sendMessage(mdr); autoResetEvent = new AutoResetEvent(false); _mapRequestsToAutoResetEvents[_currentRequest] = autoResetEvent; _pendingHistoryRequests.Add(_currentRequest); } if (!autoResetEvent.WaitOne(HistoryResponseTimeout)) { // no response if (++attempt > MaximumHistoryRetryAttempts) { break; } continue; } // Add data lock (_locker) { history.InsertRange(0, _lastHistoryChunk); } var firstDateUtc = _lastHistoryChunk[0].Time.ConvertToUtc(_configTimeZone); if (end != firstDateUtc) { // new end date = first datapoint date. end = request.Resolution == Resolution.Tick ? firstDateUtc.AddMilliseconds(-1) : firstDateUtc.AddSeconds(-1); if (request.StartTimeUtc.AddSeconds(1) >= end) break; } else { break; } } DataPointCount += history.Count; foreach (var data in history) { yield return new Slice(data.EndTime, new[] { data }); } } }
/// <summary> /// Get historical data enumerable for a single symbol, type and resolution given this start and end time (in UTC). /// </summary> /// <param name="symbol">Symbol for the data we're looking for.</param> /// <param name="type">Security type</param> /// <param name="resolution">Resolution of the data request</param> /// <param name="startUtc">Start time of the data in UTC</param> /// <param name="endUtc">End time of the data in UTC</param> /// <returns>Enumerable of base data for this symbol</returns> public IEnumerable <BaseData> Get(Symbol symbol, SecurityType type, Resolution resolution, DateTime startUtc, DateTime endUtc) { if (!_instruments.ContainsKey(symbol.Value)) { throw new ArgumentException("Invalid symbol requested: " + symbol.Value); } if (resolution == Resolution.Tick) { throw new NotSupportedException("Resolution not available: " + resolution); } if (type != SecurityType.Forex && type != SecurityType.Cfd) { throw new NotSupportedException("SecurityType not available: " + type); } if (endUtc < startUtc) { throw new ArgumentException("The end date must be greater or equal than the start date."); } Console.WriteLine("Logging in..."); // create the gateway _gateway = GatewayFactory.createGateway(); // register the message listeners with the gateway _gateway.registerGenericMessageListener(this); _gateway.registerStatusMessageListener(this); // create local login properties var loginProperties = new FXCMLoginProperties(_userName, _password, _terminal, _server); // log in _gateway.login(loginProperties); // initialize session RequestTradingSessionStatus(); Console.WriteLine("Downloading data from {0} to {1}...", startUtc.ToShortDateString(), endUtc.ToShortDateString()); // download bars var totalBars = new List <TradeBar>(); // calculate the maximum time span for one request (using 10-second bars) const int maxBarsPerRequest = 300; var timeSpanPerRequest = TimeSpan.FromSeconds(maxBarsPerRequest * 10); var start = startUtc; var end = startUtc + timeSpanPerRequest; // request loop while (start < endUtc.AddDays(1)) { _currentBars.Clear(); var mdr = new MarketDataRequest(); mdr.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SNAPSHOT); mdr.setResponseFormat(IFixMsgTypeDefs.__Fields.MSGTYPE_FXCMRESPONSE); mdr.setFXCMTimingInterval(FXCMTimingIntervalFactory.SEC10); mdr.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); mdr.setFXCMStartDate(new UTCDate(ToJavaDateUtc(start))); mdr.setFXCMStartTime(new UTCTimeOnly(ToJavaDateUtc(start))); mdr.setFXCMEndDate(new UTCDate(ToJavaDateUtc(end))); mdr.setFXCMEndTime(new UTCTimeOnly(ToJavaDateUtc(end))); mdr.addRelatedSymbol(_fxcmInstruments[_mapInstrumentSymbols[symbol]]); AutoResetEvent autoResetEvent; lock (_locker) { _currentRequest = _gateway.sendMessage(mdr); autoResetEvent = new AutoResetEvent(false); _mapRequestsToAutoResetEvents[_currentRequest] = autoResetEvent; } if (!autoResetEvent.WaitOne(1000)) { // no response, continue loop start = end.AddSeconds(10); // if saturday, fast-forward to sunday if (start.DayOfWeek == DayOfWeek.Saturday) { start = start.AddDays(1); } end = start + timeSpanPerRequest; continue; } var lastBarTime = _currentBars[_currentBars.Count - 1].Time; if (lastBarTime < start) { // no more data available, exit loop break; } // add bars received totalBars.AddRange(_currentBars.Where(x => x.Time.Date <= endUtc.Date)); // calculate time span for next request start = lastBarTime.AddSeconds(10); end = start + timeSpanPerRequest; if (start >= DateTime.UtcNow) { // data in the future not available, exit loop break; } } Console.WriteLine("Logging out..."); // log out _gateway.logout(); // remove the message listeners _gateway.removeGenericMessageListener(this); _gateway.removeStatusMessageListener(this); switch (resolution) { case Resolution.Second: foreach (var bar in totalBars) { yield return(bar); } break; case Resolution.Minute: case Resolution.Hour: case Resolution.Daily: foreach (var bar in AggregateBars(symbol, totalBars, resolution.ToTimeSpan())) { yield return(bar); } break; } }