/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using Python.Runtime; using System.Collections.Generic; using QuantConnect.Data.UniverseSelection; namespace QuantConnect.Algorithm.Framework.Selection { /// /// Universe selection model that selects the constituents of an ETF. /// public class ETFConstituentsUniverseSelectionModel : UniverseSelectionModel { private readonly Symbol _etfSymbol; private readonly UniverseSettings _universeSettings; private readonly Func, IEnumerable> _universeFilterFunc; private Universe _universe; /// /// Initializes a new instance of the class /// /// Symbol of the ETF to get constituents for /// Universe settings /// Function to filter universe results public ETFConstituentsUniverseSelectionModel( Symbol etfSymbol, UniverseSettings universeSettings, Func, IEnumerable> universeFilterFunc) { _etfSymbol = etfSymbol; _universeSettings = universeSettings; _universeFilterFunc = universeFilterFunc; } /// /// Initializes a new instance of the class /// /// Symbol of the ETF to get constituents for /// Function to filter universe results public ETFConstituentsUniverseSelectionModel( Symbol etfSymbol, Func, IEnumerable> universeFilterFunc) : this(etfSymbol, null, universeFilterFunc) { } /// /// Initializes a new instance of the class /// /// Symbol of the ETF to get constituents for /// Universe settings /// Function to filter universe results public ETFConstituentsUniverseSelectionModel( Symbol etfSymbol, UniverseSettings universeSettings = null, PyObject universeFilterFunc = null) : this(etfSymbol, universeSettings, universeFilterFunc.ConvertPythonUniverseFilterFunction()) { } /// /// Initializes a new instance of the class /// /// The string ETF ticker symbol /// Universe settings /// Function to filter universe results public ETFConstituentsUniverseSelectionModel( string etfTicker, UniverseSettings universeSettings, Func, IEnumerable> universeFilterFunc) { _etfSymbol = SymbolCache.TryGetSymbol(etfTicker, out var symbol) && symbol.SecurityType == SecurityType.Equity ? symbol : Symbol.Create(etfTicker, SecurityType.Equity, Market.USA); _universeSettings = universeSettings; _universeFilterFunc = universeFilterFunc; } /// /// Initializes a new instance of the class /// /// The string ETF ticker symbol /// Function to filter universe results public ETFConstituentsUniverseSelectionModel( string etfTicker, Func, IEnumerable> universeFilterFunc) : this(etfTicker, null, universeFilterFunc) { } /// /// Initializes a new instance of the class /// /// The string ETF ticker symbol /// Universe settings /// Function to filter universe results public ETFConstituentsUniverseSelectionModel( string etfTicker, UniverseSettings universeSettings = null, PyObject universeFilterFunc = null) : this(etfTicker, universeSettings, universeFilterFunc.ConvertPythonUniverseFilterFunction()) { } /// /// Creates a new ETF constituents universe using this class's selection function /// /// The algorithm instance to create universes for /// The universe defined by this model public override IEnumerable CreateUniverses(QCAlgorithm algorithm) { _universe ??= algorithm?.Universe.ETF(_etfSymbol, _universeSettings, _universeFilterFunc); return new[] { _universe }; } } }