Пример #1
0
        /// <summary>
        /// Performs universe selection using the data specified
        /// </summary>
        /// <param name="utcTime">The current utc time</param>
        /// <param name="data">The symbols to remain in the universe</param>
        /// <returns>The data that passes the filter</returns>
        public override IEnumerable <Symbol> SelectSymbols(DateTime utcTime, BaseDataCollection data)
        {
            // date change detection needs to be done in exchange time zone
            var exchangeDate = data.Time.ConvertFromUtc(Option.Exchange.TimeZone).Date;

            if (_cacheDate == exchangeDate)
            {
                return(Unchanged);
            }

            var availableContracts = data.Data.Select(x => x.Symbol);

            // we will only update unique strikes when there is an exchange date change
            _optionFilterUniverse.Refresh(availableContracts, data.Underlying, _lastExchangeDate != exchangeDate);
            _lastExchangeDate = exchangeDate;

            var results = Option.ContractFilter.Filter(_optionFilterUniverse);

            // if results are not dynamic, we cache them and won't call filtering till the end of the day
            if (!results.IsDynamic)
            {
                _cacheDate = data.Time.ConvertFromUtc(Option.Exchange.TimeZone).Date;
            }

            // always prepend the underlying symbol
            return(_underlyingSymbol.Concat(results));
        }
Пример #2
0
        /// <summary>
        /// Gets <see cref="OptionHistory"/> object for a given symbol, date and resolution
        /// </summary>
        /// <param name="symbol">The symbol to retrieve historical option data for</param>
        /// <param name="start">The history request start time</param>
        /// <param name="end">The history request end time. Defaults to 1 day if null</param>
        /// <param name="resolution">The resolution to request</param>
        /// <returns>A <see cref="OptionHistory"/> object that contains historical option data.</returns>
        public OptionHistory GetOptionHistory(Symbol symbol, DateTime start, DateTime?end = null, Resolution?resolution = null)
        {
            if (!end.HasValue || end.Value == start)
            {
                end = start.AddDays(1);
            }

            // Load a canonical option Symbol if the user provides us with an underlying Symbol
            if (symbol.SecurityType != SecurityType.Option && symbol.SecurityType != SecurityType.FutureOption)
            {
                symbol = AddOption(symbol, resolution, symbol.ID.Market).Symbol;
            }

            IEnumerable <Symbol> symbols;

            if (symbol.IsCanonical())
            {
                // canonical symbol, lets find the contracts
                var option = Securities[symbol] as Option;
                var resolutionToUseForUnderlying = resolution ?? SubscriptionManager.SubscriptionDataConfigService
                                                   .GetSubscriptionDataConfigs(symbol)
                                                   .GetHighestResolution();
                if (!Securities.ContainsKey(symbol.Underlying))
                {
                    // only add underlying if not present
                    AddEquity(symbol.Underlying.Value, resolutionToUseForUnderlying);
                }
                var allSymbols = new List <Symbol>();
                for (var date = start; date < end; date = date.AddDays(1))
                {
                    if (option.Exchange.DateIsOpen(date))
                    {
                        allSymbols.AddRange(OptionChainProvider.GetOptionContractList(symbol.Underlying, date));
                    }
                }

                var optionFilterUniverse = new OptionFilterUniverse();
                var distinctSymbols      = allSymbols.Distinct();
                symbols = base.History(symbol.Underlying, start, end.Value, resolution)
                          .SelectMany(x =>
                {
                    // the option chain symbols wont change so we can set 'exchangeDateChange' to false always
                    optionFilterUniverse.Refresh(distinctSymbols, x, exchangeDateChange: false);
                    return(option.ContractFilter.Filter(optionFilterUniverse));
                })
                          .Distinct().Concat(new[] { symbol.Underlying });
            }
            else
            {
                // the symbol is a contract
                symbols = new List <Symbol> {
                    symbol
                };
            }

            return(new OptionHistory(History(symbols, start, end.Value, resolution)));
        }
Пример #3
0
        /// <summary>
        /// Performs universe selection using the data specified
        /// </summary>
        /// <param name="utcTime">The current utc time</param>
        /// <param name="data">The symbols to remain in the universe</param>
        /// <returns>The data that passes the filter</returns>
        public override IEnumerable <Symbol> SelectSymbols(DateTime utcTime, BaseDataCollection data)
        {
            var optionsUniverseDataCollection = data as OptionChainUniverseDataCollection;

            if (optionsUniverseDataCollection == null)
            {
                throw new ArgumentException($"Expected data of type '{typeof(OptionChainUniverseDataCollection).Name}'");
            }

            // date change detection needs to be done in exchange time zone
            var exchangeDate = data.Time.ConvertFromUtc(Option.Exchange.TimeZone).Date;

            if (_cacheDate == exchangeDate)
            {
                return(Unchanged);
            }

            var availableContracts = optionsUniverseDataCollection.Data.Select(x => x.Symbol);

            // we will only update unique strikes when there is an exchange date change
            _optionFilterUniverse.Refresh(availableContracts, optionsUniverseDataCollection.Underlying, _lastExchangeDate != exchangeDate);
            _lastExchangeDate = exchangeDate;

            var results = Option.ContractFilter.Filter(_optionFilterUniverse);

            // if results are not dynamic, we cache them and won't call filtering till the end of the day
            if (!results.IsDynamic)
            {
                _cacheDate = data.Time.ConvertFromUtc(Option.Exchange.TimeZone).Date;
            }

            // always prepend the underlying symbol
#if NETCORE
            var resultingSymbols = LinqExtensions.ToHashSet(_underlyingSymbol.Concat(results));
#else
            var resultingSymbols = _underlyingSymbol.Concat(results).ToHashSet();
#endif

            // we save off the filtered results to the universe data collection for later
            // population into the OptionChain. This is non-ideal and could be remedied by
            // the universe subscription emitting a special type after selection that could
            // be checked for in TimeSlice.Create, but for now this will do
            optionsUniverseDataCollection.FilteredContracts = resultingSymbols;

            return(resultingSymbols);
        }
Пример #4
0
        /// <summary>
        /// Gets <see cref="OptionHistory"/> object for a given symbol, date and resolution
        /// </summary>
        /// <param name="symbol">The symbol to retrieve historical option data for</param>
        /// <param name="start">The history request start time</param>
        /// <param name="end">The history request end time. Defaults to 1 day if null</param>
        /// <param name="resolution">The resolution to request</param>
        /// <returns>A <see cref="OptionHistory"/> object that contains historical option data.</returns>
        public OptionHistory GetOptionHistory(Symbol symbol, DateTime start, DateTime?end = null, Resolution?resolution = null)
        {
            if (!end.HasValue || end.Value == start)
            {
                end = start.AddDays(1);
            }

            // Load a canonical option Symbol if the user provides us with an underlying Symbol
            if (!symbol.SecurityType.IsOption())
            {
                var option = AddOption(symbol, resolution, symbol.ID.Market);

                // Allow 20 strikes from the money for futures. No expiry filter is applied
                // so that any future contract provided will have data returned.
                if (symbol.SecurityType == SecurityType.Future && symbol.IsCanonical())
                {
                    throw new ArgumentException("The Future Symbol provided is a canonical Symbol (i.e. a Symbol representing all Futures), which is not supported at this time. " +
                                                "If you are using the Symbol accessible from `AddFuture(...)`, use the Symbol from `AddFutureContract(...)` instead. " +
                                                "You can use `qb.FutureOptionChainProvider(canonicalFuture, datetime)` to get a list of futures contracts for a given date, and add them to your algorithm with `AddFutureContract(symbol, Resolution)`.");
                }
                if (symbol.SecurityType == SecurityType.Future && !symbol.IsCanonical())
                {
                    option.SetFilter(universe => universe.Strikes(-10, +10));
                }

                symbol = option.Symbol;
            }

            IEnumerable <Symbol> symbols;

            if (symbol.IsCanonical())
            {
                // canonical symbol, lets find the contracts
                var option = Securities[symbol] as Option;
                var resolutionToUseForUnderlying = resolution ?? SubscriptionManager.SubscriptionDataConfigService
                                                   .GetSubscriptionDataConfigs(symbol)
                                                   .GetHighestResolution();
                if (!Securities.ContainsKey(symbol.Underlying))
                {
                    if (symbol.Underlying.SecurityType == SecurityType.Equity)
                    {
                        // only add underlying if not present
                        AddEquity(symbol.Underlying.Value, resolutionToUseForUnderlying);
                    }
                    if (symbol.Underlying.SecurityType == SecurityType.Future && symbol.Underlying.IsCanonical())
                    {
                        AddFuture(symbol.Underlying.ID.Symbol, resolutionToUseForUnderlying);
                    }
                    else if (symbol.Underlying.SecurityType == SecurityType.Future)
                    {
                        AddFutureContract(symbol.Underlying, resolutionToUseForUnderlying);
                    }
                }
                var allSymbols = new List <Symbol>();
                for (var date = start; date < end; date = date.AddDays(1))
                {
                    if (option.Exchange.DateIsOpen(date))
                    {
                        allSymbols.AddRange(OptionChainProvider.GetOptionContractList(symbol.Underlying, date));
                    }
                }

                var optionFilterUniverse = new OptionFilterUniverse();
                var distinctSymbols      = allSymbols.Distinct();
                symbols = base.History(symbol.Underlying, start, end.Value, resolution)
                          .SelectMany(x =>
                {
                    // the option chain symbols wont change so we can set 'exchangeDateChange' to false always
                    optionFilterUniverse.Refresh(distinctSymbols, x, exchangeDateChange: false);
                    return(option.ContractFilter.Filter(optionFilterUniverse));
                })
                          .Distinct().Concat(new[] { symbol.Underlying });
            }
            else
            {
                // the symbol is a contract
                symbols = new List <Symbol> {
                    symbol
                };
            }

            return(new OptionHistory(History(symbols, start, end.Value, resolution)));
        }