Exemplo n.º 1
0
        /// <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;
            }

            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(_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(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 (EnableOnlyHistoryRequests)
                        {
                            throw new TimeoutException(string.Format("FxcmBrokerage.GetHistory(): Operation took longer than {0} seconds.", (decimal)HistoryResponseTimeout / 1000));
                        }

                        if (++attempt > MaximumHistoryRetryAttempts)
                        {
                            Log.Trace("FxcmBrokerage.GetHistory(): Maximum attempts reached for: " + request.Symbol.Value);
                            break;
                        }

                        Log.Trace("FxcmBrokerage.GetHistory(): Attempt " + attempt + " for: " + request.Symbol.Value);
                        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 }));
                }
            }
        }
Exemplo n.º 3
0
        /// <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());
        }
Exemplo n.º 5
0
        /// <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 });
                }
            }
        }
Exemplo n.º 7
0
        /// <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 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;

                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(ResponseTimeout))
                    {
                        // no response, exit
                        break;
                    }

                    // Add data
                    history.InsertRange(0, _lastHistoryChunk.Where(x => x.Time.Date >= request.StartTimeUtc.Date));

                    if (end != _lastHistoryChunk[0].Time)
                    {
                        // new end date = first datapoint date.
                        end = _lastHistoryChunk[0].Time;
                    }
                    else
                    {
                        break;
                    }
                }

                DataPointCount += history.Count;

                foreach (var data in history)
                {
                    yield return(new Slice(data.EndTime, new[] { data }));
                }
            }
        }