Overall Statistics |
Total Orders 4201 Average Win 0.23% Average Loss -0.29% Compounding Annual Return 1.998% Drawdown 5.900% Expectancy 0.002 Start Equity 100000 End Equity 110411.67 Net Profit 10.412% Sharpe Ratio -0.062 Sortino Ratio -0.071 Probabilistic Sharpe Ratio 4.683% Loss Rate 45% Win Rate 55% Profit-Loss Ratio 0.81 Alpha -0.006 Beta 0.034 Annual Standard Deviation 0.038 Annual Variance 0.001 Information Ratio -0.648 Tracking Error 0.156 Treynor Ratio -0.069 Total Fees $4444.40 Estimated Strategy Capacity $31000000.00 Lowest Capacity Asset BRKB R735QTJ8XC9X Portfolio Turnover 69.49% |
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}')