/* * 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 System.Collections.Generic; using System.Linq; using QuantConnect.Data.Fundamental; using QuantConnect.Data.UniverseSelection; using QuantConnect.Securities; namespace QuantConnect.Algorithm.Framework.Selection { /// /// Provides a base class for defining equity coarse/fine fundamental selection models /// public abstract class FundamentalUniverseSelectionModel : UniverseSelectionModel { private readonly bool _filterFineData; private readonly UniverseSettings _universeSettings; private readonly ISecurityInitializer _securityInitializer; /// /// Initializes a new instance of the class /// /// True to also filter using fine fundamental data, false to only filter on coarse data protected FundamentalUniverseSelectionModel(bool filterFineData) : this(filterFineData, null, null) { } /// /// Initializes a new instance of the class /// /// True to also filter using fine fundamental data, false to only filter on coarse data /// The settings used when adding symbols to the algorithm, specify null to use algorthm.UniverseSettings /// Optional security initializer invoked when creating new securities, specify null to use algorithm.SecurityInitializer protected FundamentalUniverseSelectionModel(bool filterFineData, UniverseSettings universeSettings, ISecurityInitializer securityInitializer) { _filterFineData = filterFineData; _universeSettings = universeSettings; _securityInitializer = securityInitializer; } /// /// Creates a new fundamental universe using this class's selection functions /// /// The algorithm instance to create universes for /// The universe defined by this model public override IEnumerable CreateUniverses(QCAlgorithm algorithm) { var universe = CreateCoarseFundamentalUniverse(algorithm); if (_filterFineData) { universe = new FineFundamentalFilteredUniverse(universe, fine => SelectFine(algorithm, fine)); } yield return universe; } /// /// Creates the coarse fundamental universe object. /// This is provided to allow more flexibility when creating coarse universe, such as using algorithm.Universe.DollarVolume.Top(5) /// /// The algorithm instance /// The coarse fundamental universe public virtual Universe CreateCoarseFundamentalUniverse(QCAlgorithm algorithm) { var universeSettings = _universeSettings ?? algorithm.UniverseSettings; var securityInitializer = _securityInitializer ?? algorithm.SecurityInitializer; return new CoarseFundamentalUniverse(universeSettings, securityInitializer, coarse => { // if we're using fine fundamental selection than exclude symbols without fine data if (_filterFineData) { coarse = coarse.Where(c => c.HasFundamentalData); } return SelectCoarse(algorithm, coarse); }); } /// /// Defines the coarse fundamental selection function. /// /// The algorithm instance /// The coarse fundamental data used to perform filtering /// An enumerable of symbols passing the filter public abstract IEnumerable SelectCoarse(QCAlgorithm algorithm, IEnumerable coarse); /// /// Defines the fine fundamental selection function. /// /// The algorithm instance /// The fine fundamental data used to perform filtering /// An enumerable of symbols passing the filter public virtual IEnumerable SelectFine(QCAlgorithm algorithm, IEnumerable fine) { // default impl performs no filtering of fine data return fine.Select(f => f.Symbol); } /// /// Convenience method for creating a selection model that uses only coarse data /// /// Selects symbols from the provided coarse data set /// A new universe selection model that will select US equities according to the selection function specified public static IUniverseSelectionModel Coarse(Func, IEnumerable> coarseSelector) { return new CoarseFundamentalUniverseSelectionModel(coarseSelector); } /// /// /// /// Selects symbols from the provided coarse data set /// Selects symbols from the provided fine data set (this set has already been filtered according to the coarse selection) /// A new universe selection model that will select US equities according to the selection functions specified public static IUniverseSelectionModel Fine(Func, IEnumerable> coarseSelector, Func, IEnumerable> fineSelector) { return new FineFundamentalUniverseSelectionModel(coarseSelector, fineSelector); } } }