/// <summary>
            /// Transform received data into BaseData object
            /// </summary>
            /// <param name="e">Received data</param>
            /// <param name="requestData">Request information</param>
            /// <returns>BaseData object</returns>
            private BaseData GetData(LookupEventArgs e, HistoryRequest requestData)
            {
                var isEquity = requestData.SecurityType == SecurityType.Equity;
                var scale    = isEquity ? 1000m : 1m;

                try
                {
                    switch (e.Type)
                    {
                    case LookupType.REQ_HST_TCK:
                        var t    = (LookupTickEventArgs)e;
                        var time = isEquity ? t.DateTimeStamp : t.DateTimeStamp.ConvertTo(TimeZones.NewYork, TimeZones.EasternStandard);
                        return(new Tick(time, requestData.Symbol, (decimal)t.Last * scale, (decimal)t.Bid * scale, (decimal)t.Ask * scale));

                    case LookupType.REQ_HST_INT:
                        var i = (LookupIntervalEventArgs)e;
                        if (i.DateTimeStamp == DateTime.MinValue)
                        {
                            return(null);
                        }
                        var istartTime = i.DateTimeStamp - requestData.Resolution.ToTimeSpan();
                        if (!isEquity)
                        {
                            istartTime = istartTime.ConvertTo(TimeZones.NewYork, TimeZones.EasternStandard);
                        }
                        return(new TradeBar(istartTime, requestData.Symbol, (decimal)i.Open * scale, (decimal)i.High * scale, (decimal)i.Low * scale, (decimal)i.Close * scale, i.PeriodVolume));

                    case LookupType.REQ_HST_DWM:
                        var d = (LookupDayWeekMonthEventArgs)e;
                        if (d.DateTimeStamp == DateTime.MinValue)
                        {
                            return(null);
                        }
                        var dstartTime = d.DateTimeStamp - requestData.Resolution.ToTimeSpan();
                        if (!isEquity)
                        {
                            dstartTime = dstartTime.ConvertTo(TimeZones.NewYork, TimeZones.EasternStandard);
                        }
                        return(new TradeBar(dstartTime, requestData.Symbol, (decimal)d.Open * scale, (decimal)d.High * scale, (decimal)d.Low * scale, (decimal)d.Close * scale, d.PeriodVolume));

                    // we don't need to handle these other types
                    case LookupType.REQ_SYM_SYM:
                    case LookupType.REQ_SYM_SIC:
                    case LookupType.REQ_SYM_NAC:
                    case LookupType.REQ_TAB_MKT:
                    case LookupType.REQ_TAB_SEC:
                    case LookupType.REQ_TAB_MKC:
                    case LookupType.REQ_TAB_SIC:
                    case LookupType.REQ_TAB_NAC:
                    default:
                        return(null);
                    }
                }
                catch (Exception err)
                {
                    Log.Error("Encountered error while processing request: " + e.Id);
                    Log.Error(err);
                    return(null);
                }
            }
Beispiel #2
0
        /// <summary>
        /// Creates a subscription to process the request
        /// </summary>
        private Subscription CreateSubscription(HistoryRequest request, DateTime start, DateTime end)
        {
            // data reader expects these values in local times
            start = start.ConvertFromUtc(request.ExchangeHours.TimeZone);
            end   = end.ConvertFromUtc(request.ExchangeHours.TimeZone);

            var config = new SubscriptionDataConfig(request.DataType,
                                                    request.Symbol,
                                                    request.Resolution,
                                                    request.TimeZone,
                                                    request.ExchangeHours.TimeZone,
                                                    request.FillForwardResolution.HasValue,
                                                    request.IncludeExtendedMarketHours,
                                                    false,
                                                    request.IsCustomData
                                                    );

            var security = new Security(request.ExchangeHours, config, new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency));

            IEnumerator <BaseData> reader = new SubscriptionDataReader(config,
                                                                       start,
                                                                       end,
                                                                       ResultHandlerStub.Instance,
                                                                       config.SecurityType == SecurityType.Equity ? _mapFileProvider.Get(config.Market) : MapFileResolver.Empty,
                                                                       _factorFileProvider,
                                                                       Time.EachTradeableDay(request.ExchangeHours, start, end),
                                                                       false,
                                                                       includeAuxilliaryData: false
                                                                       );

            // optionally apply fill forward behavior
            if (request.FillForwardResolution.HasValue)
            {
                var readOnlyRef = Ref.CreateReadOnly(() => request.FillForwardResolution.Value.ToTimeSpan());
                reader = new FillForwardEnumerator(reader, security.Exchange, readOnlyRef, security.IsExtendedMarketHours, end, config.Increment);
            }

            // since the SubscriptionDataReader performs an any overlap condition on the trade bar's entire
            // range (time->end time) we can end up passing the incorrect data (too far past, possibly future),
            // so to combat this we deliberately filter the results from the data reader to fix these cases
            // which only apply to non-tick data

            reader = new SubscriptionFilterEnumerator(reader, security, end);
            reader = new FilterEnumerator <BaseData>(reader, data =>
            {
                // allow all ticks
                if (config.Resolution == Resolution.Tick)
                {
                    return(true);
                }
                // filter out future data
                if (data.EndTime > end)
                {
                    return(false);
                }
                // filter out data before the start
                return(data.EndTime > start);
            });

            var timeZoneOffsetProvider = new TimeZoneOffsetProvider(security.Exchange.TimeZone, start, end);

            return(new Subscription(null, security, config, reader, timeZoneOffsetProvider, start, end, false));
        }
            /// <summary>
            /// Populate request data
            /// </summary>
            public IEnumerable <Slice> ProcessHistoryRequests(HistoryRequest request)
            {
                // we can only process equity/forex types here
                if (request.SecurityType != SecurityType.Forex && request.SecurityType != SecurityType.Equity)
                {
                    yield break;
                }

                // Set this process status
                _inProgress = true;

                var symbol = request.Symbol.Value;

                if (request.SecurityType == SecurityType.Forex)
                {
                    symbol = symbol + ".FXCM";
                }

                var      start = request.StartTimeUtc.ConvertFromUtc(TimeZones.NewYork);
                DateTime?end   = request.EndTimeUtc.ConvertFromUtc(TimeZones.NewYork);

                // if we're within a minute of now, don't set the end time
                if (request.EndTimeUtc >= DateTime.UtcNow.AddMinutes(-1))
                {
                    end = null;
                }

                Log.Trace(string.Format("HistoryPort.ProcessHistoryJob(): Submitting request: {0}-{1}: {2} {3}->{4}", request.SecurityType, symbol, request.Resolution, start, end ?? DateTime.UtcNow.AddMinutes(-1)));

                int id;
                var reqid = string.Empty;

                switch (request.Resolution)
                {
                case Resolution.Tick:
                    id    = RequestTickData(symbol, start, end, true);
                    reqid = CreateRequestID(LookupType.REQ_HST_TCK, id);
                    break;

                case Resolution.Daily:
                    id    = RequestDailyData(symbol, start, end, true);
                    reqid = CreateRequestID(LookupType.REQ_HST_DWM, id);
                    break;

                default:
                    var interval = new Interval(GetPeriodType(request.Resolution), 1);
                    id    = RequestIntervalData(symbol, interval, start, end, true);
                    reqid = CreateRequestID(LookupType.REQ_HST_INT, id);
                    break;
                }

                _requestDataByRequestId[reqid] = request;

                while (_inProgress)
                {
                    continue;
                }

                // After all data arrive, we pass it to the algorithm through memory and write to a file
                foreach (var key in _currentRequest.Keys)
                {
                    List <BaseData> tradeBars;
                    if (_currentRequest.TryRemove(key, out tradeBars))
                    {
                        foreach (var tradeBar in tradeBars)
                        {
                            // Returns IEnumerable<Slice> object
                            yield return(new Slice(tradeBar.Time, new[] { tradeBar }));
                        }
                    }
                }
            }