예제 #1
0
        /// <summary>
        /// Get the data feed types for a given <see cref="SecurityType"/> <see cref="Resolution"/>
        /// </summary>
        /// <param name="symbolSecurityType">The <see cref="SecurityType"/> used to determine the types</param>
        /// <param name="resolution">The resolution of the data requested</param>
        /// <param name="isCanonical">Indicates whether the security is Canonical (future and options)</param>
        /// <returns>Types that should be added to the <see cref="SubscriptionDataConfig"/></returns>
        public List <Tuple <Type, TickType> > LookupSubscriptionConfigDataTypes(SecurityType symbolSecurityType, Resolution resolution, bool isCanonical)
        {
            if (isCanonical)
            {
                return(new List <Tuple <Type, TickType> > {
                    new Tuple <Type, TickType>(typeof(ZipEntryName), TickType.Quote)
                });
            }

            return(AvailableDataTypes[symbolSecurityType].Select(tickType => new Tuple <Type, TickType>(LeanData.GetDataType(resolution, tickType), tickType)).ToList());
        }
예제 #2
0
        /// <summary>
        /// Get the last known price using the history provider.
        /// Useful for seeding securities with the correct price
        /// </summary>
        /// <param name="security"><see cref="Security"/> object for which to retrieve historical data</param>
        /// <returns>A single <see cref="BaseData"/> object with the last known price</returns>
        public BaseData GetLastKnownPrice(Security security)
        {
            if (security.Symbol.IsCanonical() || HistoryProvider == null)
            {
                return(null);
            }

            var configs = SubscriptionManager.SubscriptionDataConfigService
                          .GetSubscriptionDataConfigs(security.Symbol);

            var dataTimeZone = MarketHoursDatabase
                               .GetDataTimeZone(security.Symbol.ID.Market, security.Symbol, security.Symbol.SecurityType);

            // For speed and memory usage, use Resolution.Minute as the minimum resolution
            var resolution            = (Resolution)Math.Max((int)Resolution.Minute, (int)configs.GetHighestResolution());
            var isExtendedMarketHours = configs.IsExtendedMarketHours();

            // request QuoteBar for Options and Futures
            var dataType = typeof(BaseData);

            if (security.Type == SecurityType.Option || security.Type == SecurityType.Future)
            {
                dataType = LeanData.GetDataType(resolution, TickType.Quote);
            }

            // Get the config with the largest resolution
            var subscriptionDataConfig = GetMatchingSubscription(security.Symbol, dataType);

            TickType tickType;

            if (subscriptionDataConfig == null)
            {
                dataType = typeof(TradeBar);
                tickType = LeanData.GetCommonTickTypeForCommonDataTypes(dataType, security.Type);
            }
            else
            {
                // if subscription resolution is Tick, we also need to update the data type from Tick to TradeBar/QuoteBar
                if (subscriptionDataConfig.Resolution == Resolution.Tick)
                {
                    dataType = LeanData.GetDataType(resolution, subscriptionDataConfig.TickType);
                    subscriptionDataConfig = new SubscriptionDataConfig(subscriptionDataConfig, dataType, resolution: resolution);
                }

                dataType = subscriptionDataConfig.Type;
                tickType = subscriptionDataConfig.TickType;
            }

            Func <int, BaseData> getLastKnownPriceForPeriods = backwardsPeriods =>
            {
                var startTimeUtc = _historyRequestFactory
                                   .GetStartTimeAlgoTz(security.Symbol, backwardsPeriods, resolution, security.Exchange.Hours)
                                   .ConvertToUtc(_localTimeKeeper.TimeZone);

                var request = new HistoryRequest(
                    startTimeUtc,
                    UtcTime,
                    dataType,
                    security.Symbol,
                    resolution,
                    security.Exchange.Hours,
                    dataTimeZone,
                    resolution,
                    isExtendedMarketHours,
                    configs.IsCustomData(),
                    configs.DataNormalizationMode(),
                    tickType
                    );

                BaseData result = null;
                History(new List <HistoryRequest> {
                    request
                })
                .PushThrough(bar =>
                {
                    if (!bar.IsFillForward)
                    {
                        result = bar;
                    }
                });

                return(result);
            };

            var lastKnownPrice = getLastKnownPriceForPeriods(1);

            if (lastKnownPrice != null)
            {
                return(lastKnownPrice);
            }

            // If the first attempt to get the last know price returns null, it maybe the case of an illiquid security.
            // We increase the look-back period for this case accordingly to the resolution to cover 3 trading days
            var periods =
                resolution == Resolution.Daily ? 3 :
                resolution == Resolution.Hour ? 24 : 1440;

            return(getLastKnownPriceForPeriods(periods));
        }
예제 #3
0
        private void ConvertMinuteFuturesData(Symbol canonical, TickType tickType, Resolution outputResolution, Resolution inputResolution = Resolution.Minute)
        {
            var timeSpans = new Dictionary <Resolution, TimeSpan>()
            {
                { Resolution.Daily, TimeSpan.FromHours(24) },
                { Resolution.Hour, TimeSpan.FromHours(1) },
            };

            var timeSpan = timeSpans[outputResolution];

            var tickTypeConsolidatorMap = new Dictionary <TickType, Func <IDataConsolidator> >()
            {
                { TickType.Quote, () => new QuoteBarConsolidator(timeSpan) },
                { TickType.OpenInterest, () => new OpenInterestConsolidator(timeSpan) },
                { TickType.Trade, () => new TradeBarConsolidator(timeSpan) }
            };

            var consolidators = new Dictionary <string, IDataConsolidator>();
            var configs       = new Dictionary <string, SubscriptionDataConfig>();
            var outputFiles   = new Dictionary <string, StringBuilder>();
            var futures       = new Dictionary <string, Symbol>();

            var date = _fromDate;

            while (date <= _toDate)
            {
                var futureChain = LoadFutureChain(canonical, date, tickType, inputResolution);

                foreach (var future in futureChain)
                {
                    if (!futures.ContainsKey(future.Value))
                    {
                        futures[future.Value] = future;
                        var config = new SubscriptionDataConfig(LeanData.GetDataType(outputResolution, tickType),
                                                                future, inputResolution, TimeZones.NewYork, TimeZones.NewYork,
                                                                false, false, false, false, tickType);
                        configs[future.Value] = config;

                        consolidators[future.Value] = tickTypeConsolidatorMap[tickType].Invoke();

                        var sb = new StringBuilder();
                        outputFiles[future.Value] = sb;

                        consolidators[future.Value].DataConsolidated += (sender, bar) =>
                        {
                            sb.Append(LeanData.GenerateLine(bar, SecurityType.Future, outputResolution) + Environment.NewLine);
                        };
                    }

                    var leanDataReader = new LeanDataReader(configs[future.Value], future, inputResolution, date, _dataDirectory);

                    var data         = leanDataReader.Parse().ToList();
                    var consolidator = consolidators[future.Value];

                    foreach (var bar in data)
                    {
                        consolidator.Update(bar);
                    }
                }
                date = date.AddDays(1);
            }

            //write all results
            foreach (var consolidator in consolidators.Values)
            {
                consolidator.Scan(date);
            }

            var zip     = LeanData.GenerateRelativeZipFilePath(canonical, _fromDate, outputResolution, tickType);
            var zipPath = Path.Combine(_dataDirectory, zip);
            var fi      = new FileInfo(zipPath);

            if (!fi.Directory.Exists)
            {
                fi.Directory.Create();
            }

            foreach (var future in futures.Values)
            {
                var zipEntry = LeanData.GenerateZipEntryName(future, _fromDate, outputResolution, tickType);
                var sb       = outputFiles[future.Value];

                //Uncomment to write zip files
                //QuantConnect.Compression.ZipCreateAppendData(zipPath, zipEntry, sb.ToString());

                Assert.IsTrue(sb.Length > 0);
            }
        }
예제 #4
0
        /// <summary>
        /// Downloads historical data from the brokerage and saves it in LEAN format.
        /// </summary>
        /// <param name="brokerage">The brokerage from where to fetch the data</param>
        /// <param name="symbols">The list of symbols</param>
        /// <param name="startTimeUtc">The starting date/time (UTC)</param>
        /// <param name="endTimeUtc">The ending date/time (UTC)</param>
        public void DownloadAndSave(IBrokerage brokerage, List <Symbol> symbols, DateTime startTimeUtc, DateTime endTimeUtc)
        {
            if (symbols.Count == 0)
            {
                throw new ArgumentException("DownloadAndSave(): The symbol list cannot be empty.");
            }

            if (_tickType != TickType.Trade && _tickType != TickType.Quote)
            {
                throw new ArgumentException("DownloadAndSave(): The tick type must be Trade or Quote.");
            }

            if (_securityType != SecurityType.Future && _securityType != SecurityType.Option)
            {
                throw new ArgumentException($"DownloadAndSave(): The security type must be {SecurityType.Future} or {SecurityType.Option}.");
            }

            if (symbols.Any(x => x.SecurityType != _securityType))
            {
                throw new ArgumentException($"DownloadAndSave(): All symbols must have {_securityType} security type.");
            }

            if (symbols.DistinctBy(x => x.ID.Symbol).Count() > 1)
            {
                throw new ArgumentException("DownloadAndSave(): All symbols must have the same root ticker.");
            }

            var dataType = LeanData.GetDataType(_resolution, _tickType);

            var marketHoursDatabase = MarketHoursDatabase.FromDataFolder();

            var ticker = symbols.First().ID.Symbol;
            var market = symbols.First().ID.Market;

            var canonicalSymbol = Symbol.Create(ticker, _securityType, market);

            var exchangeHours = marketHoursDatabase.GetExchangeHours(canonicalSymbol.ID.Market, canonicalSymbol, _securityType);
            var dataTimeZone  = marketHoursDatabase.GetDataTimeZone(canonicalSymbol.ID.Market, canonicalSymbol, _securityType);

            var historyBySymbol            = new Dictionary <Symbol, List <IGrouping <DateTime, BaseData> > >();
            var historyBySymbolDailyOrHour = new Dictionary <Symbol, List <BaseData> >();

            foreach (var symbol in symbols)
            {
                var historyRequest = new HistoryRequest(
                    startTimeUtc,
                    endTimeUtc,
                    dataType,
                    symbol,
                    _resolution,
                    exchangeHours,
                    dataTimeZone,
                    _resolution,
                    true,
                    false,
                    DataNormalizationMode.Raw,
                    _tickType
                    );

                var history = brokerage.GetHistory(historyRequest)
                              .Select(
                    x =>
                {
                    x.Time = x.Time.ConvertTo(exchangeHours.TimeZone, dataTimeZone);
                    return(x);
                })
                              .ToList();

                if (_resolution == Resolution.Daily || _resolution == Resolution.Hour)
                {
                    historyBySymbolDailyOrHour.Add(symbol, history);
                }
                else
                {
                    // group by date in DataTimeZone
                    var historyByDate = history.GroupBy(x => x.Time.Date).ToList();
                    historyBySymbol.Add(symbol, historyByDate);
                }
            }

            if (_resolution == Resolution.Daily || _resolution == Resolution.Hour)
            {
                SaveDailyOrHour(symbols, canonicalSymbol, historyBySymbolDailyOrHour);
            }
            else
            {
                SaveMinuteOrSecondOrTick(symbols, startTimeUtc, endTimeUtc, canonicalSymbol, historyBySymbol);
            }
        }
예제 #5
0
        public void GetsHistory(Symbol symbol, Resolution resolution, TickType tickType, TimeSpan period, bool shouldBeEmpty)
        {
            var now = new DateTime(2020, 5, 20, 15, 0, 0).RoundDown(resolution.ToTimeSpan());

            var dataType = LeanData.GetDataType(resolution, tickType);

            var requests = new[]
            {
                new HistoryRequest(now.Add(-period),
                                   now,
                                   dataType,
                                   symbol,
                                   resolution,
                                   SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork),
                                   TimeZones.NewYork,
                                   null,
                                   true,
                                   false,
                                   DataNormalizationMode.Adjusted,
                                   tickType)
            };

            var history = _historyProvider.GetHistory(requests, TimeZones.NewYork).ToList();

            if (dataType == typeof(TradeBar))
            {
                foreach (var slice in history)
                {
                    var bar = slice.Bars[symbol];
                    Log.Trace($"{bar.Time}: {bar.Symbol} - O={bar.Open}, H={bar.High}, L={bar.Low}, C={bar.Close}");
                }
            }
            else if (dataType == typeof(QuoteBar))
            {
                foreach (var slice in history)
                {
                    var bar = slice.QuoteBars[symbol];
                    Log.Trace($"{bar.Time}: {bar.Symbol} - O={bar.Open}, H={bar.High}, L={bar.Low}, C={bar.Close}");
                }
            }
            else if (dataType == typeof(Tick))
            {
                foreach (var slice in history)
                {
                    var ticks = slice.Ticks[symbol];
                    foreach (var tick in ticks)
                    {
                        Log.Trace($"{tick.Time}: {tick.Symbol} - B={tick.BidPrice}, A={tick.AskPrice}, P={tick.LastPrice}, Q={tick.Quantity}");
                    }
                }
            }

            Log.Trace("Data points retrieved: " + _historyProvider.DataPointCount);

            if (shouldBeEmpty)
            {
                Assert.IsTrue(history.Count == 0);
            }
            else
            {
                Assert.IsTrue(history.Count > 0);
            }
        }
예제 #6
0
        /// <summary>
        /// Get the last known price using the history provider.
        /// Useful for seeding securities with the correct price
        /// </summary>
        /// <param name="security"><see cref="Security"/> object for which to retrieve historical data</param>
        /// <returns>A single <see cref="BaseData"/> object with the last known price</returns>
        public BaseData GetLastKnownPrice(Security security)
        {
            if (security.Symbol.IsCanonical() || HistoryProvider == null)
            {
                return(null);
            }

            var configs = SubscriptionManager.SubscriptionDataConfigService
                          .GetSubscriptionDataConfigs(security.Symbol);

            // For speed and memory usage, use Resolution.Minute as the minimum resolution
            var resolution            = (Resolution)Math.Max((int)Resolution.Minute, (int)configs.GetHighestResolution());
            var isExtendedMarketHours = configs.IsExtendedMarketHours();

            var startTime = GetStartTimeAlgoTzForSecurity(security.Exchange, 1, resolution, isExtendedMarketHours);
            var endTime   = Time.RoundDown(resolution.ToTimeSpan());

            // request QuoteBar for Options and Futures
            var dataType = typeof(BaseData);

            if (security.Type == SecurityType.Option || security.Type == SecurityType.Future)
            {
                dataType = LeanData.GetDataType(resolution, TickType.Quote);
            }

            // Get the config with the largest resolution
            var subscriptionDataConfig = GetMatchingSubscription(security.Symbol, dataType);

            // if subscription resolution is Tick, we also need to update the data type from Tick to TradeBar/QuoteBar
            if (subscriptionDataConfig != null && subscriptionDataConfig.Resolution == Resolution.Tick)
            {
                dataType = LeanData.GetDataType(resolution, subscriptionDataConfig.TickType);
                subscriptionDataConfig = new SubscriptionDataConfig(subscriptionDataConfig, dataType, resolution: resolution);
            }

            var request = new HistoryRequest(
                startTime.ConvertToUtc(_localTimeKeeper.TimeZone),
                endTime.ConvertToUtc(_localTimeKeeper.TimeZone),
                subscriptionDataConfig == null ? typeof(TradeBar) : subscriptionDataConfig.Type,
                security.Symbol,
                resolution,
                security.Exchange.Hours,
                MarketHoursDatabase.FromDataFolder().GetDataTimeZone(security.Symbol.ID.Market, security.Symbol, security.Symbol.SecurityType),
                resolution,
                isExtendedMarketHours,
                configs.IsCustomData(),
                configs.DataNormalizationMode(),
                subscriptionDataConfig == null ? LeanData.GetCommonTickTypeForCommonDataTypes(typeof(TradeBar), security.Type) : subscriptionDataConfig.TickType
                );

            var history = History(new List <HistoryRequest> {
                request
            }).ToList();

            if (history.Any() && history.First().Values.Any())
            {
                return(history.First().Values.First());
            }

            return(null);
        }