Universe Selection

ETF Constituents Universes

Introduction

The ETFConstituentsUniverseSelectionModel selects a daily universe of US Equities based on the constituents of an ETF. These Universe Selection models rely on the US ETF Constituents dataset.

Add ETF Constituents Universe Selection

To add an ETFConstituentsUniverseSelectionModel to your algorithm, in the Initialize method, call the AddUniverseSelection method. The ETFConstituentsUniverseSelectionModel constructor expects an ETF Symbol.

AddUniverseSelection(new ETFConstituentsUniverseSelectionModel(etfSymbol));
self.AddUniverseSelection(ETFConstituentsUniverseSelectionModel(etfSymbol))

The following table describes the arguments the model accepts:

ArgumentData TypeDescriptionDefault Value
etfSymbolSymbolSymbol of the ETF to get constituents for
universeSettingsUniverseSettingsThe universe settings. If you don't provide an argument, the model uses the algorithm.UniverseSettings by default.nullNone
universeFilterFuncFunc<IEnumerable<ETFConstituentData>, IEnumerable<Symbol>>Callable[[List[ETFConstituentData]], List[Symbol]]Function to filter ETF constituents. If you don't provide an argument, the model selects all of the ETF constituents by default.nullNone

If you provide a universeFilterFunc argument, you can use the following attributes of the ETFConstituentData objects to select your universe:

The following example shows how to select the 10 Equities with the largest weight in the SPY ETF:

public override void Initialize()
{
    var symbol = QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA);
    AddUniverseSelection(new ETFConstituentsUniverseSelectionModel(symbol, UniverseSettings, ETFConstituentsFilter));
}

private IEnumerable<Symbol> ETFConstituentsFilter(IEnumerable<ETFConstituentData> constituents)
{
    return constituents.OrderByDescending(c => c.Weight).Take(10).Select(c => c.Symbol);
}
def Initialize(self) -> None:
    symbol = Symbol.Create("SPY", SecurityType.Equity, Market.USA)
    universe = ETFConstituentsUniverseSelectionModel(symbol, self.UniverseSettings, self.ETFConstituentsFilter)
    self.AddUniverseSelection(universe)

def ETFConstituentsFilter(self, constituents: List[ETFConstituentData]) -> List[Symbol]:
    selected = sorted([c for c in constituents if c.Weight],
        key=lambda c: c.Weight, reverse=True)[:10]
    return [c.Symbol for c in selected]

To move the ETF Symbol and the selection function outside of the algorithm class, create a universe selection model that inherits the ETFConstituentsUniverseSelectionModel class.

// In Initialize
AddUniverseSelection(new LargestWeightSPYETFUniverseSelectionModel(UniverseSettings));

// Outside of the algorithm class
class LargestWeightSPYETFUniverseSelectionModel : ETFConstituentsUniverseSelectionModel
{
    public LargestWeightSPYETFUniverseSelectionModel(UniverseSettings universeSettings = null)
        : base(QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA), 
            universeSettings, ETFConstituentsFilter)
    {
    }

    private static IEnumerable<Symbol> ETFConstituentsFilter(IEnumerable<ETFConstituentData> constituents)
    {
        return constituents.OrderByDescending(c => c.Weight).Take(10).Select(c => c.Symbol);
    }
}
# In Initialize
self.AddUniverseSelection(LargestWeightSPYETFUniverseSelectionModel(self.UniverseSettings))

# Outside of the algorithm class
class LargestWeightSPYETFUniverseSelectionModel(ETFConstituentsUniverseSelectionModel):
    def __init__(self, universe_settings: UniverseSettings = None) -> None:
        symbol = Symbol.Create("SPY", SecurityType.Equity, Market.USA)
        super().__init__(symbol, universe_settings, self.ETFConstituentsFilter)

    def ETFConstituentsFilter(self, constituents: List[ETFConstituentData]) -> List[Symbol]:
        selected = sorted([c for c in constituents if c.Weight],
            key=lambda c: c.Weight, reverse=True)[:10]
        return [c.Symbol for c in selected]

To return the current universe constituents from the selection function, return Universe.Unchanged.

To view the implementation of this model, see the LEAN GitHub repositoryLEAN GitHub repository.

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: