QuantConnect
US ETF Constituents
Introduction
The US ETF Constituents dataset by QuantConnect tracks the constituents and weighting of US Equities in 2,650 ETF listings. The data starts in June 2009 and is delivered on a daily basis (monthly basis before January 2015). 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.
For more information about the US ETF Constituents dataset, including CLI commands and pricing, see the dataset listing.
About the Provider
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.
Getting Started
The following snippet demonstrates how to request data from the US ETF Constituents dataset:
def initialize(self) -> None: self.universe_settings.asynchronous = True # Use the following method for a Classic Algorithm self._universe = self.add_universe(self.universe.etf("SPY", Market.USA, self.universe_settings, self.etf_constituents_filter)) symbol = Symbol.create("SPY", SecurityType.EQUITY, Market.USA) # Use the following method for a Framework Algorithm self.add_universe_selection(ETFConstituentsUniverseSelectionModel(symbol, self.universe_settings, self.etf_constituents_filter)) def etf_constituents_filter(self, constituents: List[ETFConstituentUniverse]) -> List[Symbol]: # Add all Symbols of the ETFConstituentUniverse return [x.symbol for x in constituents]
public override void Initialize() { UniverseSettings.Asynchronous = True; // Use the following method for a Classic Algorithm _universe = AddUniverse(Universe.ETF("SPY", Market.USA, UniverseSettings, ETFConstituentsFilter)); var symbol = QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA); // Use the following method for a Framework Algorithm AddUniverseSelection(new ETFConstituentsUniverseSelectionModel(symbol, UniverseSettings, ETFConstituentsFilter)); } private IEnumerable<Symbol> ETFConstituentsFilter(IEnumerable <ETFConstituentUniverse> constituents) { // Add all Symbols of the ETFConstituentUniverse return constituents.Select(x => x.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:
- Creating an index-tracking algorithm for customized passive portfolio management
- Performing statistical arbitrage with the base ETF
For more example algorithms, see Examples.
Requesting Data
To add US ETF Constituents data to your algorithm, call the AddUniverseadd_universe and Universe.ETFuniverse.etf methods. To select which constituents occupy the universe, provide the ETF Symbol and a selection function.
class ETFConstituentUniverseAlgorithm(QCAlgorithm): def initialize(self) -> None: self.set_start_date(2018, 1, 1) self.set_end_date(2020, 8, 25) self.set_cash(100000) self.universe_settings.asynchronous = True self._universe = self.add_universe(self.universe.etf("SPY", self.universe_settings, self.etf_constituents_filter))
namespace QuantConnect { public class ETFConstituentUniverseAlgorithm : QCAlgorithm { public override void Initialize() { SetStartDate(2018, 1, 1); SetEndDate(2020, 8, 25); SetCash(100000); UniverseSettings.Asynchronous = True; _universe = AddUniverse(Universe.ETF("SPY", UniverseSettings, ETFConstituentsFilter)); } } }
For more information about universe settings, see Settings.
Accessing Data
To access the US ETF Constituent data, use the ETFConstituentUniverse objects in your selection function. The data is available in daily resolution. The Symbol objects you return from your selection function defines the universe constituents.
def etf_constituents_filter(self, constituents: List[ETFConstituentUniverse]) -> List[Symbol]: for c in constituents: self.debug(f'{c.end_time} :: {c.last_update} :: {c.weight} :: {c.shares_held} :: {c.market_value}') return [x.symbol for x in constituents]
public IEnumerable<Symbol> ETFConstituentsFilter(IEnumerable<ETFConstituentUniverse> constituents) { foreach (var c in constituents) { Debug($"{c.EndTime} :: {c.LastUpdate} :: {c.Weight} :: {c.SharesHeld} :: {c.MarketValue}"); } return constituents.Select(c => c.Symbol); }
Historical Data
You can get historical universe data in an algorithm and in the Research Environment.
Historical Universe Data in Algorithms
To get historical universe data in an algorithm, call the Historyhistory method with the Universe object and the lookback period. If there is no data in the period you request, the history result is empty.
var history = History(_universe, 30, Resolution.Daily); foreach (var constituents in history) { foreach (ETFConstituentUniverse constituent in constituents) { Log($"{constituent.Symbol} weight at {constituent.EndTime}: {constituent.Weight}"); } }
history = self.history(self.universe, 30, Resolution.DAILY) for (universe_symbol, time), constituents in history.items(): for constituent in constituents: self.log(f'{constituent.symbol} weight at {constituent.end_time}: {constituent.weight}')
Historical Universe Data in Research
To get historical universe data in research, call the UniverseHistoryuniverse_history method with the Universe object and the lookback period. The UniverseHistoryuniverse_history returns the filtered universe. If there is no data in the period you request, the history result is empty.
var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-30), qb.Time); foreach (var constituents in universeHistory ) { foreach (ETFConstituentUniverse constituent in constituents) { Console.WriteLine($"{constituent.Symbol} weight at {constituent.EndTime}: {constituent.Weight}"); } }
universe_history = qb.universe_history(universe, qb.time-timedelta(30), qb.time) for (universe_symbol, time), constituents in universe_history.items(): for constituent in constituents: print(f"{constituent.symbol} weight at {constituent.end_time}: {constituent.weight}")
You can call the Historyhistory method in Research.
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:
- Creating an index-tracking algorithm for customized passive portfolio management
- Performing statistical arbitrage with the base ETF
For more example algorithms, see Examples.