/// <summary> /// Adds the specified symbols to the subscription /// </summary> /// <param name="job">Job we're subscribing for:</param> /// <param name="symbols">The symbols to be added keyed by SecurityType</param> public void Subscribe(LiveNodePacket job, IEnumerable <Symbol> symbols) { var symbolsToSubscribe = (from symbol in symbols where !_subscribedSymbols.Contains(symbol) select symbol).ToList(); if (symbolsToSubscribe.Count == 0) { return; } Log.Trace("FxcmBrokerage.Subscribe(): {0}", string.Join(",", symbolsToSubscribe)); var request = new MarketDataRequest(); foreach (var symbol in symbolsToSubscribe) { request.addRelatedSymbol(_fxcmInstruments[_symbolMapper.GetBrokerageSymbol(symbol)]); } request.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SUBSCRIBE); request.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); lock (_locker) { _gateway.sendMessage(request); } foreach (var symbol in symbolsToSubscribe) { _subscribedSymbols.Add(symbol); } }
/// <summary> /// Adds the specified symbols to the subscription /// </summary> /// <param name="job">Job we're subscribing for:</param> /// <param name="symbols">The symbols to be added keyed by SecurityType</param> public void Subscribe(LiveNodePacket job, IEnumerable<Symbol> symbols) { var symbolsToSubscribe = (from symbol in symbols where !_subscribedSymbols.Contains(symbol) && CanSubscribe(symbol) select symbol).ToList(); if (symbolsToSubscribe.Count == 0) return; Log.Trace("FxcmBrokerage.Subscribe(): {0}", string.Join(",", symbolsToSubscribe)); var request = new MarketDataRequest(); foreach (var symbol in symbolsToSubscribe) { TradingSecurity fxcmSecurity; if (_fxcmInstruments.TryGetValue(_symbolMapper.GetBrokerageSymbol(symbol), out fxcmSecurity)) { request.addRelatedSymbol(fxcmSecurity); } } request.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SUBSCRIBE); request.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); lock (_locker) { _gateway.sendMessage(request); } foreach (var symbol in symbolsToSubscribe) { _subscribedSymbols.Add(symbol); } }
/// <summary> /// Adds the specified symbols to the subscription /// </summary> /// <param name="symbols">The symbols to be added keyed by SecurityType</param> private bool Subscribe(IEnumerable <Symbol> symbols) { var request = new MarketDataRequest(); foreach (var symbol in symbols) { TradingSecurity fxcmSecurity; if (_fxcmInstruments.TryGetValue(_symbolMapper.GetBrokerageSymbol(symbol), out fxcmSecurity)) { request.addRelatedSymbol(fxcmSecurity); // cache exchange time zone for symbol DateTimeZone exchangeTimeZone; if (!_symbolExchangeTimeZones.TryGetValue(symbol, out exchangeTimeZone)) { exchangeTimeZone = MarketHoursDatabase.FromDataFolder().GetExchangeHours(Market.FXCM, symbol, symbol.SecurityType).TimeZone; _symbolExchangeTimeZones.Add(symbol, exchangeTimeZone); } } } request.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SUBSCRIBE); request.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); lock (_locker) { _gateway.sendMessage(request); } return(true); }
/// <summary> /// Gets the quotes for the symbol /// </summary> private List <MarketDataSnapshot> GetQuotes(List <string> fxcmSymbols) { // get current quotes for the instrument var request = new MarketDataRequest(); request.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); request.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SNAPSHOT); foreach (var fxcmSymbol in fxcmSymbols) { request.addRelatedSymbol(_fxcmInstruments[fxcmSymbol]); } AutoResetEvent autoResetEvent; lock (_locker) { _currentRequest = _gateway.sendMessage(request); autoResetEvent = new AutoResetEvent(false); _mapRequestsToAutoResetEvents[_currentRequest] = autoResetEvent; } if (!autoResetEvent.WaitOne(ResponseTimeout)) { throw new TimeoutException("FxcmBrokerage.GetQuotes(): Operation took longer than " + $"{((decimal)ResponseTimeout / 1000).ToStringInvariant()} seconds." ); } return(_rates.Where(x => fxcmSymbols.Contains(x.Key)).Select(x => x.Value).ToList()); }
/// <summary> /// Adds the specified symbols to the subscription /// </summary> /// <param name="job">Job we're subscribing for:</param> /// <param name="symbols">The symbols to be added keyed by SecurityType</param> public void Subscribe(LiveNodePacket job, IDictionary<SecurityType, List<Symbol>> symbols) { var symbolsToSubscribe = (from secType in symbols from symbol in secType.Value where !_subscribedSymbols.Contains(symbol) select symbol).ToList(); if (symbolsToSubscribe.Count == 0) return; Log.Trace("FxcmBrokerage.Subscribe(): {0}", string.Join(",", symbolsToSubscribe)); var request = new MarketDataRequest(); foreach (var symbol in symbolsToSubscribe) { request.addRelatedSymbol(_fxcmInstruments[ConvertSymbolToFxcmSymbol(symbol)]); } request.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SUBSCRIBE); request.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); lock (_locker) { _gateway.sendMessage(request); } foreach (var symbol in symbolsToSubscribe) { _subscribedSymbols.Add(symbol); } }
/// <summary> /// Removes the specified symbols to the subscription /// </summary> /// <param name="job">Job we're processing.</param> /// <param name="symbols">The symbols to be removed keyed by SecurityType</param> public void Unsubscribe(LiveNodePacket job, IDictionary <SecurityType, List <string> > symbols) { var symbolsToUnsubscribe = (from secType in symbols from symbol in secType.Value where _subscribedSymbols.Contains(symbol) select symbol).ToList(); if (symbolsToUnsubscribe.Count == 0) { return; } Log.Trace("FxcmBrokerage.Unsubscribe(): {0}", string.Join(",", symbolsToUnsubscribe)); var request = new MarketDataRequest(); foreach (var symbol in symbolsToUnsubscribe) { request.addRelatedSymbol(_fxcmInstruments[ConvertSymbolToFxcmSymbol(symbol)]); } request.setSubscriptionRequestType(SubscriptionRequestTypeFactory.UNSUBSCRIBE); request.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); lock (_locker) { _gateway.sendMessage(request); } foreach (var symbol in symbolsToUnsubscribe) { _subscribedSymbols.Remove(symbol); } }
/// <summary> /// Adds the specified symbols to the subscription /// </summary> /// <param name="symbols">The symbols to be added keyed by SecurityType</param> private void Subscribe(IEnumerable <Symbol> symbols) { var symbolsToSubscribe = (from symbol in symbols where !_subscribedSymbols.Contains(symbol) && CanSubscribe(symbol) select symbol).ToList(); if (symbolsToSubscribe.Count == 0) { return; } Log.Trace("FxcmBrokerage.Subscribe(): {0}", string.Join(",", symbolsToSubscribe)); var request = new MarketDataRequest(); foreach (var symbol in symbolsToSubscribe) { TradingSecurity fxcmSecurity; if (_fxcmInstruments.TryGetValue(_symbolMapper.GetBrokerageSymbol(symbol), out fxcmSecurity)) { request.addRelatedSymbol(fxcmSecurity); // cache exchange time zone for symbol DateTimeZone exchangeTimeZone; if (!_symbolExchangeTimeZones.TryGetValue(symbol, out exchangeTimeZone)) { exchangeTimeZone = MarketHoursDatabase.FromDataFolder().GetExchangeHours(Market.FXCM, symbol, symbol.SecurityType).TimeZone; _symbolExchangeTimeZones.Add(symbol, exchangeTimeZone); } } } request.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SUBSCRIBE); request.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); lock (_locker) { _gateway.sendMessage(request); } foreach (var symbol in symbolsToSubscribe) { _subscribedSymbols.Add(symbol); } }
/// <summary> /// Removes the specified symbols to the subscription /// </summary> /// <param name="symbols">The symbols to be removed keyed by SecurityType</param> private bool Unsubscribe(IEnumerable <Symbol> symbols) { Log.Trace("FxcmBrokerage.Unsubscribe(): {0}", string.Join(",", symbols)); var request = new MarketDataRequest(); foreach (var symbol in symbols) { request.addRelatedSymbol(_fxcmInstruments[_symbolMapper.GetBrokerageSymbol(symbol)]); } request.setSubscriptionRequestType(SubscriptionRequestTypeFactory.UNSUBSCRIBE); request.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); lock (_locker) { _gateway.sendMessage(request); } return(true); }
/// <summary> /// TradingSessionStatus message handler /// </summary> private void OnTradingSessionStatus(TradingSessionStatus message) { if (message.getRequestID() == _currentRequest) { // load instrument list into a dictionary var securities = message.getSecurities(); while (securities.hasMoreElements()) { var security = (TradingSecurity)securities.nextElement(); _fxcmInstruments[security.getSymbol()] = security; } // create map from QuantConnect symbols to FXCM symbols foreach (var kvp in _fxcmInstruments) { var fxcmSymbol = kvp.Key; var tradingSecurity = kvp.Value; var symbol = ConvertSymbol(tradingSecurity); _mapInstrumentSymbols[symbol] = fxcmSymbol; } // get account base currency _fxcmAccountCurrency = message.getParameter("BASE_CRNCY").getValue(); _mapRequestsToAutoResetEvents[_currentRequest].Set(); _mapRequestsToAutoResetEvents.Remove(_currentRequest); // unsubscribe all instruments (only at first logon) if (_subscribedSymbols.Count == 0) { var request = new MarketDataRequest(); foreach (var fxcmSymbol in _fxcmInstruments.Keys) { request.addRelatedSymbol(_fxcmInstruments[fxcmSymbol]); } request.setSubscriptionRequestType(SubscriptionRequestTypeFactory.UNSUBSCRIBE); request.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); _gateway.sendMessage(request); } } }
/// <summary> /// Gets the quotes for the symbol /// </summary> public List<MarketDataSnapshot> GetQuotes(List<string> fxcmSymbols) { // get current quotes for the instrument var request = new MarketDataRequest(); request.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); request.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SNAPSHOT); foreach (var fxcmSymbol in fxcmSymbols) { request.addRelatedSymbol(_fxcmInstruments[fxcmSymbol]); } AutoResetEvent autoResetEvent; lock (_locker) { _currentRequest = _gateway.sendMessage(request); autoResetEvent = new AutoResetEvent(false); _mapRequestsToAutoResetEvents[_currentRequest] = autoResetEvent; } if (!autoResetEvent.WaitOne(ResponseTimeout)) throw new TimeoutException(string.Format("FxcmBrokerage.GetQuotes(): Operation took longer than {0} seconds.", (decimal)ResponseTimeout / 1000)); return _rates.Where(x => fxcmSymbols.Contains(x.Key)).Select(x => x.Value).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; } }
/// <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> /// 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> /// Removes the specified symbols to the subscription /// </summary> /// <param name="job">Job we're processing.</param> /// <param name="symbols">The symbols to be removed keyed by SecurityType</param> public void Unsubscribe(LiveNodePacket job, IEnumerable<Symbol> symbols) { var symbolsToUnsubscribe = (from symbol in symbols where _subscribedSymbols.Contains(symbol) select symbol).ToList(); if (symbolsToUnsubscribe.Count == 0) return; Log.Trace("FxcmBrokerage.Unsubscribe(): {0}", string.Join(",", symbolsToUnsubscribe)); var request = new MarketDataRequest(); foreach (var symbol in symbolsToUnsubscribe) { request.addRelatedSymbol(_fxcmInstruments[_symbolMapper.GetBrokerageSymbol(symbol)]); } request.setSubscriptionRequestType(SubscriptionRequestTypeFactory.UNSUBSCRIBE); request.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); lock (_locker) { _gateway.sendMessage(request); } foreach (var symbol in symbolsToUnsubscribe) { _subscribedSymbols.Remove(symbol); } }
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() != "N") 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); }
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> /// TradingSessionStatus message handler /// </summary> private void OnTradingSessionStatus(TradingSessionStatus message) { if (message.getRequestID() == _currentRequest) { // load instrument list into a dictionary var securities = message.getSecurities(); while (securities.hasMoreElements()) { var security = (TradingSecurity)securities.nextElement(); _fxcmInstruments[security.getSymbol()] = security; } // create map from QuantConnect symbols to FXCM symbols foreach (var fxcmSymbol in _fxcmInstruments.Keys) { var symbol = ConvertFxcmSymbolToSymbol(fxcmSymbol); _mapInstrumentSymbols[symbol] = fxcmSymbol; } // get account base currency _fxcmAccountCurrency = message.getParameter("BASE_CRNCY").getValue(); _mapRequestsToAutoResetEvents[_currentRequest].Set(); _mapRequestsToAutoResetEvents.Remove(_currentRequest); // unsubscribe all instruments var request = new MarketDataRequest(); foreach (var fxcmSymbol in _fxcmInstruments.Keys) { request.addRelatedSymbol(_fxcmInstruments[fxcmSymbol]); } request.setSubscriptionRequestType(SubscriptionRequestTypeFactory.UNSUBSCRIBE); request.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL); _gateway.sendMessage(request); } }
/// <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> /// 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="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; } }