About US ETF Constituents

The US ETF Constituents dataset by QuantConnect tracks the constituents and weighting of US Equities in 2,650 ETF listings. The data starts in January 2009 and is delivered on a daily basis. This dataset is created by tracking the host ETF websites and can be delayed by up to 1 week.

This dataset depends on the US Equity Security Master dataset because the US Equity Security Master dataset contains information on splits, dividends, and symbol changes.


About QuantConnect

QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 160,000 quants are served every month.


About QuantConnect

QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month.


Algorithm Example

from AlgorithmImports import *
from QuantConnect.DataSource import *

class ETFConstituentUniverseAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2016, 1, 1)
        self.set_end_date(2021, 1, 1)
        self.set_cash(100000)
        self.universe_settings.asynchronous = True
        self.universe_settings.resolution = Resolution.MINUTE
        
        # Requesting data
        self.spy = self.add_equity("SPY").symbol
        self._universe = self.add_universe(self.universe.etf(self.spy, self.universe_settings, self.etf_constituents_filter))
        
        # Historical Universe data
        history = self.history(self._universe, 30, Resolution.DAILY)
        for (universe_symbol, time), constituents in history.items():
            for constituent in constituents:
                self.debug(f'{constituent.symbol}: {constituent.weight}')

        self.weight_by_symbol = {}
        
        self.schedule.on(
            self.date_rules.every_day(self.spy),
            self.time_rules.after_market_open(self.spy, 1),
            self.rebalance)

    def etf_constituents_filter(self, constituents: List[ETFConstituentUniverse]) -> List[Symbol]:
        # Get the 10 securities with the largest weight in the index
        selected = sorted([c for c in constituents if c.weight],
            key=lambda c: c.weight, reverse=True)[:10]
        self.weight_by_symbol = {c.symbol: c.weight for c in selected}
        
        return list(self.weight_by_symbol.keys())

    def rebalance(self) -> None:
        spy_weight = sum(self.weight_by_symbol.values())

        if spy_weight > 0:
            for symbol in self.portfolio.Keys:
                if symbol not in self.weight_by_symbol:
                    self.liquidate(symbol)
    
            for symbol, weight in self.weight_by_symbol.items():
                self.set_holdings(symbol, 0.5 * weight / spy_weight)
                
            self.set_holdings(self.spy, -0.5)

    def on_securities_changed(self, changes: SecurityChanges) -> None:
        for security in changes.removed_securities:
            if security.invested:
                self.liquidate(security.symbol, 'Removed From Universe')

        for security in changes.added_securities:
            # Historical data
            history = self.history(security.symbol, 7, Resolution.DAILY)
            self.debug(f'We got {len(history)} from our history request for {security.symbol}')

Example Applications

The ETF Constituents dataset provides an excellent source of tradable universes for strategies without selection bias. When you use an ETF universe, the original ETF can serve as an excellent benchmark for your strategy performance. Other use cases include the following: