Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Sortino Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -0.536 Tracking Error 0.188 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
#region imports using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Globalization; using System.Drawing; using QuantConnect; using QuantConnect.Algorithm.Framework; using QuantConnect.Algorithm.Framework.Selection; using QuantConnect.Algorithm.Framework.Alphas; using QuantConnect.Algorithm.Framework.Portfolio; using QuantConnect.Algorithm.Framework.Execution; using QuantConnect.Algorithm.Framework.Risk; using QuantConnect.Parameters; using QuantConnect.Benchmarks; using QuantConnect.Brokerages; using QuantConnect.Util; using QuantConnect.Interfaces; using QuantConnect.Algorithm; using QuantConnect.Indicators; using QuantConnect.Data; using QuantConnect.Data.Consolidators; using QuantConnect.Data.Custom; using QuantConnect.DataSource; using QuantConnect.Data.Fundamental; using QuantConnect.Data.Market; using QuantConnect.Data.UniverseSelection; using QuantConnect.Notifications; using QuantConnect.Orders; using QuantConnect.Orders.Fees; using QuantConnect.Orders.Fills; using QuantConnect.Orders.Slippage; using QuantConnect.Scheduling; using QuantConnect.Securities; using QuantConnect.Securities.Equity; using QuantConnect.Securities.Future; using QuantConnect.Securities.Option; using QuantConnect.Securities.Forex; using QuantConnect.Securities.Crypto; using QuantConnect.Securities.Positions; using QuantConnect.Securities.Interfaces; using QuantConnect.Storage; using QuantConnect.Data.Custom.AlphaStreams; using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm; using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm; #endregion namespace QuantConnect.Algorithm.CSharp { public class ETFUniverseOptions : QCAlgorithm { Symbol _benchmark; List<DateTime> _selections = new List<DateTime>(); public override void Initialize() { SetCash(1000000000); SetStartDate(2020, 1, 1); SetEndDate(2024, 1, 1); UniverseSettings.Resolution = Resolution.Hour; UniverseSettings.DataNormalizationMode = DataNormalizationMode.Raw; Portfolio.SetPositions(SecurityPositionGroupModel.Null); SetSecurityInitializer(security => { var seeder = new FuncSecuritySeeder(GetLastKnownPrices).SeedSecurity(security); security.SetBuyingPowerModel(new ConstantBuyingPowerModel(1)); }); _benchmark = AddEquity("QQQ", dataNormalizationMode: DataNormalizationMode.Raw).Symbol; var etfUniverse = AddUniverse(Universe.ETF("QQQ", Market.USA, UniverseSettings, ETFConstituentsFilter)); AddUniverseOptions(etfUniverse, OptionFilterFunction); } private IEnumerable<Symbol> ETFConstituentsFilter(IEnumerable<ETFConstituentData> constituents) { // Get the 10 securities with the largest weight in the index return constituents.OrderByDescending(c => c.Weight).Take(10).Select(c => c.Symbol); } private OptionFilterUniverse OptionFilterFunction(OptionFilterUniverse optionFilterUniverse) { return optionFilterUniverse.Strikes(0, 2).FrontMonth().CallsOnly(); } } }
#region imports using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Globalization; using System.Drawing; using QuantConnect; using QuantConnect.Algorithm.Framework; using QuantConnect.Algorithm.Framework.Selection; using QuantConnect.Algorithm.Framework.Alphas; using QuantConnect.Algorithm.Framework.Portfolio; using QuantConnect.Algorithm.Framework.Execution; using QuantConnect.Algorithm.Framework.Risk; using QuantConnect.Parameters; using QuantConnect.Benchmarks; using QuantConnect.Brokerages; using QuantConnect.Util; using QuantConnect.Interfaces; using QuantConnect.Algorithm; using QuantConnect.Indicators; using QuantConnect.Data; using QuantConnect.Data.Consolidators; using QuantConnect.Data.Custom; using QuantConnect.DataSource; using QuantConnect.Data.Fundamental; using QuantConnect.Data.Market; using QuantConnect.Data.UniverseSelection; using QuantConnect.Notifications; using QuantConnect.Orders; using QuantConnect.Orders.Fees; using QuantConnect.Orders.Fills; using QuantConnect.Orders.Slippage; using QuantConnect.Scheduling; using QuantConnect.Securities; using QuantConnect.Securities.Equity; using QuantConnect.Securities.Future; using QuantConnect.Securities.Option; using QuantConnect.Securities.Forex; using QuantConnect.Securities.Crypto; using QuantConnect.Securities.Interfaces; using QuantConnect.Storage; using QuantConnect.Data.Custom.AlphaStreams; using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm; using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm; #endregion namespace QuantConnect { /// <summary> /// This universe selection model will chain to the security changes of a given <see cref="UniverseSelectionModel"/> selection /// output and create a new <see cref="OptionChainUniverse"/> for each of them /// /// This class is based on https://www.quantconnect.com/docs/v2/writing-algorithms/algorithm-framework/universe-selection/options-universes#61-Option-Chained-Universe-Selection /// instead of attaching to a Universe, it attaches to a UniverseSelectionModel /// </summary> public class OptionsUniverseSelectionModel : UniverseSelectionModel { private DateTime _nextRefreshTimeUtc; private readonly UniverseSelectionModel _universeSelectionModel; private readonly Func<OptionFilterUniverse, OptionFilterUniverse> _optionFilter; private readonly Dictionary<Universe, IEnumerable<Symbol>> _fundamentalUniverses; /// <summary> /// Gets the next time the framework should invoke the `CreateUniverses` method to refresh the set of universes. /// </summary> public override DateTime GetNextRefreshTimeUtc() { var parentRefreshTime = _universeSelectionModel.GetNextRefreshTimeUtc(); if (parentRefreshTime <= _nextRefreshTimeUtc) { _fundamentalUniverses.Clear(); _nextRefreshTimeUtc = parentRefreshTime; } return _nextRefreshTimeUtc; } /// <summary> /// Creates a new instance of <see cref="OptionsUniverseSelectionModel"/> /// </summary> /// <param name="universeSelectionModel">The universe selection model we want to chain to</param> /// <param name="optionFilter">The option filter universe to use</param> public OptionsUniverseSelectionModel(UniverseSelectionModel universeSelectionModel, Func<OptionFilterUniverse, OptionFilterUniverse> optionFilter = null) { _nextRefreshTimeUtc = DateTime.MaxValue; _universeSelectionModel = universeSelectionModel; _optionFilter = optionFilter; _fundamentalUniverses = new Dictionary<Universe, IEnumerable<Symbol>>(); } /// <summary> /// Creates the universes for this algorithm. Called when the original universeSelectionModel /// or when the symbols it contains change /// </summary> /// <param name="algorithm">The algorithm instance to create universes for</param> /// <returns>The universes to be used by the algorithm</returns> public override IEnumerable<Universe> CreateUniverses(QCAlgorithm algorithm) { _nextRefreshTimeUtc = DateTime.MaxValue; if (_fundamentalUniverses.Count <= 0) { var universes = _universeSelectionModel.CreateUniverses(algorithm); foreach (var universe in universes) { _fundamentalUniverses.Add(universe, Enumerable.Empty<Symbol>()); universe.SelectionChanged += (sender, args) => { // We must create the new option Symbol using the CreateOption(Symbol, ...) overload. // Otherwise, we'll end up loading equity data for the selected Symbol, which won't // work whenever we're loading options data for any non-equity underlying asset class. _fundamentalUniverses[universe] = ((Universe.SelectionEventArgs)args).CurrentSelection .Select(symbol => Symbol.CreateOption( symbol, symbol.ID.Market, symbol.SecurityType.DefaultOptionStyle(), default(OptionRight), 0m, SecurityIdentifier.DefaultDate)) .ToList(); // the universe we were watching changed, this will trigger a call to CreateUniverses _nextRefreshTimeUtc = DateTime.MinValue; }; } } foreach (var kpv in _fundamentalUniverses) { yield return kpv.Key; foreach (var optionSymbol in kpv.Value) { yield return algorithm.CreateOptionChain(optionSymbol, _optionFilter, kpv.Key.UniverseSettings); } } } } }