/// <summary> /// Connects the client to the broker's remote servers /// </summary> public override void Connect() { if (IsConnected) { return; } Log.Trace("FxcmBrokerage.Connect()"); _cancellationTokenSource = new CancellationTokenSource(); // create new thread to fire order events in queue _orderEventThread = new Thread(() => { while (!_cancellationTokenSource.IsCancellationRequested) { OrderEvent orderEvent; if (!_orderEventQueue.TryDequeue(out orderEvent)) { Thread.Sleep(1); continue; } OnOrderEvent(orderEvent); } }); _orderEventThread.Start(); while (!_orderEventThread.IsAlive) { Thread.Sleep(1); } // 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); // load instruments, accounts, orders, positions LoadInstruments(); LoadAccounts(); LoadOpenOrders(); LoadOpenPositions(); }
/// <summary> /// Connects the client to the broker's remote servers /// </summary> public override void Connect() { if (IsConnected) { return; } Log.Trace("FxcmBrokerage.Connect()"); _cancellationTokenSource = new CancellationTokenSource(); // create new thread to fire order events in queue if (!EnableOnlyHistoryRequests) { _orderEventThread = new Thread(() => { while (!_cancellationTokenSource.IsCancellationRequested) { try { OrderEvent orderEvent; if (!_orderEventQueue.TryDequeue(out orderEvent)) { Thread.Sleep(1); continue; } OnOrderEvent(orderEvent); } catch (Exception exception) { Log.Error(exception); } } }) { IsBackground = true }; _orderEventThread.Start(); while (!_orderEventThread.IsAlive) { Thread.Sleep(1); } } // 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); loginProperties.addProperty(IConnectionManager.APP_INFO, "QuantConnect"); // log in try { _gateway.login(loginProperties); } catch (Exception err) { var message = err.Message.Contains("ORA-20101") ? "Incorrect login credentials" : err.Message.Contains("ORA-20003") ? "API connections are not available on Mini accounts. If you have a standard account contact [email protected] to enable API access" : err.Message; _cancellationTokenSource.Cancel(); throw new BrokerageException(message, err.InnerException); } // create new thread to manage disconnections and reconnections if (!EnableOnlyHistoryRequests) { _connectionMonitorThread = new Thread(() => { _lastReadyMessageTime = DateTime.UtcNow; try { while (!_cancellationTokenSource.IsCancellationRequested) { TimeSpan elapsed; lock (_lockerConnectionMonitor) { elapsed = DateTime.UtcNow - _lastReadyMessageTime; } if (!_connectionLost && elapsed > TimeSpan.FromSeconds(10)) { _connectionLost = true; OnMessage(BrokerageMessageEvent.Disconnected("Connection with FXCM server lost. " + "This could be because of internet connectivity issues. ")); } else if (_connectionLost && IsWithinTradingHours()) { Log.Trace("FxcmBrokerage.ConnectionMonitorThread(): Attempting reconnection..."); try { // log out try { _gateway.logout(); } catch (Exception) { // ignored } // remove the message listeners _gateway.removeGenericMessageListener(this); _gateway.removeStatusMessageListener(this); // register the message listeners with the gateway _gateway.registerGenericMessageListener(this); _gateway.registerStatusMessageListener(this); // log in _gateway.login(loginProperties); // load instruments, accounts, orders, positions LoadInstruments(); if (!EnableOnlyHistoryRequests) { LoadAccounts(); LoadOpenOrders(); LoadOpenPositions(); } _connectionLost = false; OnMessage(BrokerageMessageEvent.Reconnected("Connection with FXCM server restored.")); } catch (Exception exception) { Log.Trace("FxcmBrokerage.ConnectionMonitorThread(): reconnect failed."); Log.Error(exception); } } Thread.Sleep(5000); } } catch (Exception exception) { Log.Error(exception); } }) { IsBackground = true }; _connectionMonitorThread.Start(); while (!_connectionMonitorThread.IsAlive) { Thread.Sleep(1); } } // load instruments, accounts, orders, positions LoadInstruments(); if (!EnableOnlyHistoryRequests) { LoadAccounts(); LoadOpenOrders(); LoadOpenPositions(); } }
/// <summary> /// Connects the client to the broker's remote servers /// </summary> public override void Connect() { if (IsConnected) { return; } Log.Trace("FxcmBrokerage.Connect()"); _cancellationTokenSource = new CancellationTokenSource(); // create new thread to fire order events in queue _orderEventThread = new Thread(() => { while (!_cancellationTokenSource.IsCancellationRequested) { OrderEvent orderEvent; if (!_orderEventQueue.TryDequeue(out orderEvent)) { Thread.Sleep(1); continue; } OnOrderEvent(orderEvent); } }); _orderEventThread.Start(); while (!_orderEventThread.IsAlive) { Thread.Sleep(1); } // 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); // create new thread to manage disconnections and reconnections _connectionMonitorThread = new Thread(() => { _lastReadyMessageTime = DateTime.UtcNow; try { while (!_cancellationTokenSource.IsCancellationRequested) { TimeSpan elapsed; lock (_lockerConnectionMonitor) { elapsed = DateTime.UtcNow - _lastReadyMessageTime; } if (!_connectionLost && elapsed > TimeSpan.FromSeconds(5)) { _connectionLost = true; OnMessage(BrokerageMessageEvent.Disconnected("Connection with FXCM server lost. " + "This could be because of internet connectivity issues. ")); } else if (_connectionLost && elapsed <= TimeSpan.FromSeconds(5)) { try { _gateway.relogin(); _connectionLost = false; OnMessage(BrokerageMessageEvent.Reconnected("Connection with FXCM server restored.")); } catch (Exception exception) { Log.Error(exception); } } else if (_connectionError) { try { // log out _gateway.logout(); // remove the message listeners _gateway.removeGenericMessageListener(this); _gateway.removeStatusMessageListener(this); // register the message listeners with the gateway _gateway.registerGenericMessageListener(this); _gateway.registerStatusMessageListener(this); // log in _gateway.login(loginProperties); // load instruments, accounts, orders, positions LoadInstruments(); LoadAccounts(); LoadOpenOrders(); LoadOpenPositions(); _connectionError = false; _connectionLost = false; OnMessage(BrokerageMessageEvent.Reconnected("Connection with FXCM server restored.")); } catch (Exception exception) { Log.Error(exception); } } Thread.Sleep(5000); } } catch (Exception exception) { Log.Error(exception); } }); _connectionMonitorThread.Start(); while (!_connectionMonitorThread.IsAlive) { Thread.Sleep(1); } // load instruments, accounts, orders, positions LoadInstruments(); LoadAccounts(); LoadOpenOrders(); LoadOpenPositions(); }
public void Run() { _gateway = GatewayFactory.createGateway(); // register the generic message listener with the gateway _gateway.registerGenericMessageListener(this); // register the status message listener with the gateway _gateway.registerStatusMessageListener(this); // attempt to login with the local login properties Console.WriteLine("Logging in..."); var loginProperties = new FXCMLoginProperties(UserName, Password, Terminal, Server); // disable the streaming rates (default automatic subscriptions) loginProperties.addProperty(IConnectionManager.__Fields.MSG_FLAGS, IFixDefs.__Fields.CHANNEL_MARKET_DATA.ToString()); _gateway.login(loginProperties); Console.WriteLine("Logged in.\n"); // get instrument list Console.WriteLine("Requesting trading session status..."); lock (_locker) { _currentRequest = _gateway.requestTradingSessionStatus(); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestTradingSessionStatusEvent.WaitOne(); Console.WriteLine("Instruments: {0}\n", _securities.Count); foreach (var pair in _securities) { var security = pair.Value; Console.WriteLine(security.getSymbol() + " " + security.getCurrency() + " " + security.getFXCMSubscriptionStatus() + " " + security.getRoundLot() + " " + security.getContractMultiplier() + " " + security.getFXCMMinQuantity() + " " + security.getFXCMMaxQuantity() + " " + security.getFXCMSymPointSize() + " " + security.getFactor() + " " + security.getFXCMSymPrecision() + " " + security.getProduct() + " " + security.getFXCMProductID() + " " + (security.getFXCMProductID() == IFixValueDefs.__Fields.FXCMPRODUCTID_FOREX ? "Forex" : "CFD")); } Console.WriteLine(); // get account list Console.WriteLine("Requesting account list..."); lock (_locker) { _currentRequest = _gateway.requestAccounts(); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestAccountListEvent.WaitOne(); Console.WriteLine("Accounts: {0}\n", _accounts.Count); // use first account var accountId = _accounts.Keys.First(); // we are unable to continue if Hedging enabled if (_accounts[accountId].getParties().getFXCMPositionMaintenance() == "Y") { throw new NotSupportedException("The Lean engine does not support accounts with Hedging enabled. Please contact FXCM support to disable Hedging and try again."); } // get open order list Console.WriteLine("Requesting open order list..."); lock (_locker) { _currentRequest = _gateway.requestOpenOrders(); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestOrderEvent.WaitOne(); Console.WriteLine("Open orders: {0}\n", _orders.Keys.Count); // cancel all open orders if (_orders.Keys.Count > 0) { Console.WriteLine("Cancelling open orders..."); foreach (var order in _orders.Values.ToList()) { Console.WriteLine("Cancelling order {0}...", order.getOrderID()); var request = MessageGenerator.generateOrderCancelRequest("", order.getOrderID(), order.getSide(), order.getAccount()); lock (_locker) { _currentRequest = _gateway.sendMessage(request); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestOrderEvent.WaitOne(); Console.WriteLine("Order {0} cancelled.", order.getOrderID()); } _orders.Clear(); Console.WriteLine("Open orders cancelled.\n"); } // get open position list Console.WriteLine("Requesting open position list..."); lock (_locker) { _currentRequest = _gateway.requestOpenPositions(); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestPositionListEvent.WaitOne(); Console.WriteLine("Open position list complete.\n"); // get closed position list Console.WriteLine("Requesting closed position list..."); lock (_currentRequest) { _currentRequest = _gateway.requestClosedPositions(); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestPositionListEvent.WaitOne(); Console.WriteLine("Closed position list complete.\n"); // get current quotes for the instrument if (_securities.ContainsKey(Symbol)) { Console.WriteLine("Requesting market data for " + Symbol + "..."); var request = new MarketDataRequest(); request.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); request.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SNAPSHOT); request.addRelatedSymbol(_securities[Symbol]); lock (_locker) { _currentRequest = _gateway.sendMessage(request); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestMarketDataEvent.WaitOne(); Console.WriteLine(Symbol + " - Bid: {0} Ask: {1}\n", _rates[Symbol].getBidClose(), _rates[Symbol].getAskClose()); } // submit limit order Console.WriteLine("Submitting limit order..."); var limitOrderRequest = MessageGenerator.generateOpenOrder(0.7, accountId, 10000, SideFactory.BUY, Symbol, ""); limitOrderRequest.setOrdType(OrdTypeFactory.LIMIT); limitOrderRequest.setTimeInForce(TimeInForceFactory.GOOD_TILL_CANCEL); lock (_locker) { _currentRequest = _gateway.sendMessage(limitOrderRequest); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestOrderEvent.WaitOne(); Console.WriteLine("Limit order submitted.\n"); var limitOrder = _orderRequests[_currentRequest]; // update limit order Console.WriteLine("Updating limit order..."); var orderReplaceRequest = MessageGenerator.generateOrderReplaceRequest("", limitOrder.getOrderID(), limitOrder.getSide(), limitOrder.getOrdType(), 0.8, limitOrder.getAccount()); lock (_locker) { _currentRequest = _gateway.sendMessage(orderReplaceRequest); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestOrderEvent.WaitOne(); Console.WriteLine("Limit order updated.\n"); // cancel limit order Console.WriteLine("Cancelling limit order..."); var orderCancelRequest = MessageGenerator.generateOrderCancelRequest("", limitOrder.getOrderID(), limitOrder.getSide(), limitOrder.getAccount()); lock (_locker) { _currentRequest = _gateway.sendMessage(orderCancelRequest); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestOrderEvent.WaitOne(); Console.WriteLine("Limit order cancelled.\n"); // submit stop market order Console.WriteLine("Submitting stop market order..."); var stopMarketOrderRequest = MessageGenerator.generateOpenOrder(0.7, accountId, 10000, SideFactory.SELL, Symbol, ""); stopMarketOrderRequest.setOrdType(OrdTypeFactory.STOP); stopMarketOrderRequest.setTimeInForce(TimeInForceFactory.GOOD_TILL_CANCEL); lock (_locker) { _currentRequest = _gateway.sendMessage(stopMarketOrderRequest); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestOrderEvent.WaitOne(); Console.WriteLine("Stop market order submitted.\n"); var stopMarketOrder = _orderRequests[_currentRequest]; // cancel stop market order Console.WriteLine("Cancelling stop market order..."); orderCancelRequest = MessageGenerator.generateOrderCancelRequest("", stopMarketOrder.getOrderID(), stopMarketOrder.getSide(), stopMarketOrder.getAccount()); lock (_locker) { _currentRequest = _gateway.sendMessage(orderCancelRequest); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestOrderEvent.WaitOne(); Console.WriteLine("Stop market order cancelled.\n"); // submit stop limit order Console.WriteLine("Submitting stop limit order..."); var stopLimitOrderRequest = MessageGenerator.generateOpenOrder(0.7, accountId, 10000, SideFactory.SELL, Symbol, ""); stopLimitOrderRequest.setOrdType(OrdTypeFactory.STOP_LIMIT); stopLimitOrderRequest.setStopPx(0.695); stopLimitOrderRequest.setTimeInForce(TimeInForceFactory.GOOD_TILL_CANCEL); lock (_locker) { _currentRequest = _gateway.sendMessage(stopLimitOrderRequest); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestOrderEvent.WaitOne(); Console.WriteLine("Stop limit order submitted.\n"); var stopLimitOrder = _orderRequests[_currentRequest]; // cancel stop limit order Console.WriteLine("Cancelling stop limit order..."); orderCancelRequest = MessageGenerator.generateOrderCancelRequest("", stopLimitOrder.getOrderID(), stopLimitOrder.getSide(), stopLimitOrder.getAccount()); lock (_locker) { _currentRequest = _gateway.sendMessage(orderCancelRequest); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestOrderEvent.WaitOne(); Console.WriteLine("Stop limit order cancelled.\n"); // submit market order (buy) Console.WriteLine("Submitting buy market order..."); var buyOrder = MessageGenerator.generateMarketOrder(accountId, 10000, SideFactory.BUY, Symbol, ""); lock (_locker) { _currentRequest = _gateway.sendMessage(buyOrder); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestOrderEvent.WaitOne(); Console.WriteLine("Buy market order submitted.\n"); // submit market order (sell) Console.WriteLine("Submitting sell market order..."); var sellOrder = MessageGenerator.generateMarketOrder(accountId, 10000, SideFactory.SELL, Symbol, ""); lock (_locker) { _currentRequest = _gateway.sendMessage(sellOrder); Console.WriteLine("\tRequestId = {0}\n", _currentRequest); } _requestOrderEvent.WaitOne(); Console.WriteLine("Sell market order submitted.\n"); Console.WriteLine(); Console.WriteLine("Press Return to Logout and exit.\n"); Console.ReadKey(); // log out Console.WriteLine("Logging out..."); _gateway.logout(); Console.WriteLine("Logged out."); // remove the generic message listener, stop listening to updates _gateway.removeGenericMessageListener(this); // remove the status message listener, stop listening to status changes _gateway.removeStatusMessageListener(this); }
/// <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="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; } }