Universe Selection

ETF Constituents Universes

Introduction

The ETFConstituentsUniverseSelectionModel selects a universe of US Equities based on the constituents of an ETF. These Universe Selection models rely on the US ETF Constituents dataset. They run on a daily schedule by default. To adjust the selection schedule, see Schedule.

Add ETF Constituents Universe Selection

To add an ETFConstituentsUniverseSelectionModel to your algorithm, in the Initializeinitialize method, call the AddUniverseSelectionadd_universe_selection method. The ETFConstituentsUniverseSelectionModel constructor expects an ETF ticker.

// Run universe selection asynchronously to speed up your algorithm.
UniverseSettings.Asynchronous = true;
AddUniverseSelection(new ETFConstituentsUniverseSelectionModel("SPY"));
# Run universe selection asynchronously to speed up your algorithm.
self.universe_settings.asynchronous = True
self.add_universe_selection(ETFConstituentsUniverseSelectionModel("SPY"))

The following table describes the arguments the model accepts:

ArgumentData TypeDescriptionDefault Value
etfTickeretf_tickerstringTicker of the ETF to get constituents for. To view the available ETFs, see Supported ETFs.
universeSettingsuniverse_settingsUniverseSettingsThe universe settings. If you don't provide an argument, the model uses the algorithm.UniverseSettingsalgorithm.universe_settings by default.None
universeFilterFuncuniverse_filter_funcFunc<IEnumerable<ETFConstituentUniverse>, IEnumerable<Symbol>>Callable[[List[ETFConstituentUniverse]], List[Symbol]]Function to filter ETF constituents. If you don't provide an argument, the model selects all of the ETF constituents by default.Nonenull

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

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

// Initialize asynchronous settings for speed and use the ETFConstituentsUniverseSelectionModel 
// to select the top 10 SPY constituents by weight, focusing on blue-chip stocks with minimal risk.
public override void Initialize()
{
    UniverseSettings.Asynchronous = true;
    AddUniverseSelection(
        new ETFConstituentsUniverseSelectionModel("SPY", universeFilterFunc: ETFConstituentsFilter)
    );
}

private IEnumerable<Symbol> ETFConstituentsFilter(IEnumerable<ETFConstituentUniverse> constituents)
{
    // Select the 10 largest Equities in the ETF.
    return constituents.OrderByDescending(c => c.Weight).Take(10).Select(c => c.Symbol);
}
# Initialize asynchronous settings for speed and use the ETFConstituentsUniverseSelectionModel 
# to select the top 10 SPY constituents by weight, focusing on blue-chip stocks with minimal risk.
def initialize(self) -> None:
    self.universe_settings.asynchronous = True   
    self.add_universe_selection(
        ETFConstituentsUniverseSelectionModel("SPY", universe_filter_func=self._etf_constituents_filter)
    )

def _etf_constituents_filter(self, constituents: List[ETFConstituentUniverse]) -> List[Symbol]:
    # Select the 10 largest Equities in the ETF.
    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.

// Initialize asynchronous settings for speed and use the LargestWeightSPYETFUniverseSelectionModel 
// to select the top 10 blue-chip SPY constituents by weight, focusing on stocks with minimal risk.
UniverseSettings.Asynchronous = true;
AddUniverseSelection(new LargestWeightSPYETFUniverseSelectionModel());

// Outside of the algorithm class
class LargestWeightSPYETFUniverseSelectionModel : ETFConstituentsUniverseSelectionModel
{
    public LargestWeightSPYETFUniverseSelectionModel(UniverseSettings universeSettings = null)
        : base("SPY", universeFilterFunc: ETFConstituentsFilter)
    {
    }

    private static IEnumerable<Symbol> ETFConstituentsFilter(IEnumerable<ETFConstituentUniverse> constituents)
    {
        // Select the 10 largest Equities in the ETF.
        return constituents.OrderByDescending(c => c.Weight).Take(10).Select(c => c.Symbol);
    }
}
# Initialize asynchronous settings for speed and use the LargestWeightSPYETFUniverseSelectionModel 
# to select the top 10 blue-chip SPY constituents by weight, focusing on stocks with minimal risk.
self.universe_settings.asynchronous = True
self.add_universe_selection(LargestWeightSPYETFUniverseSelectionModel())

# Outside of the algorithm class
class LargestWeightSPYETFUniverseSelectionModel(ETFConstituentsUniverseSelectionModel):
    
    def __init__(self) -> None:
        super().__init__('SPY', universe_filter_func=self._etf_constituents_filter)

    def _etf_constituents_filter(self, constituents: List[ETFConstituentUniverse]) -> List[Symbol]:
        # Select the 10 largest Equities in the ETF.
        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.UnchangedUNCHANGED.

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: