Overall Statistics
Total Trades
9401
Average Win
0.08%
Average Loss
-0.15%
Compounding Annual Return
1.042%
Drawdown
5.600%
Expectancy
-0.002
Net Profit
5.326%
Sharpe Ratio
0.211
Probabilistic Sharpe Ratio
1.678%
Loss Rate
36%
Win Rate
64%
Profit-Loss Ratio
0.55
Alpha
0.004
Beta
0.032
Annual Standard Deviation
0.037
Annual Variance
0.001
Information Ratio
-0.689
Tracking Error
0.156
Treynor Ratio
0.248
Total Fees
$9603.79
Estimated Strategy Capacity
$170000000.00
Lowest Capacity Asset
BRKB R735QTJ8XC9X
from AlgorithmImports import *
from QuantConnect.DataSource import *

class ETFConstituentsDataAlgorithm(QCAlgorithm):

    def Initialize(self) -> None:
        self.SetStartDate(2016, 1, 1)
        self.SetEndDate(2021, 1, 1)
        self.SetCash(100000)
        
        self.UniverseSettings.Resolution = Resolution.Minute
        
        # Requesting data
        self.spy = self.AddEquity("SPY").Symbol
        self.AddUniverse(self.Universe.ETF(self.spy, self.UniverseSettings, self.ETFConstituentsFilter))
        
        self.weightBySymbol = {}
        
        self.Schedule.On(
            self.DateRules.EveryDay(self.spy),
            self.TimeRules.AfterMarketOpen(self.spy, 1),
            self.Rebalance)

    def ETFConstituentsFilter(self, constituents: List[ETFConstituentData]) -> 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.weightBySymbol = {c.Symbol: c.Weight for c in selected}
        
        return list(self.weightBySymbol.keys())

    def Rebalance(self) -> None:
        spyWeight = sum(self.weightBySymbol.values())

        if spyWeight > 0:
            for symbol in self.Portfolio.Keys:
                if symbol not in self.weightBySymbol:
                    self.Liquidate(symbol)
    
            for symbol, weight in self.weightBySymbol.items():
                self.SetHoldings(symbol, 0.5 * weight / spyWeight)
                
            self.SetHoldings(self.spy, -0.5)

    def OnSecuritiesChanged(self, changes: SecurityChanges) -> None:
        for security in changes.RemovedSecurities:
            if security.Invested:
                self.Liquidate(security.Symbol, 'Removed From Universe')

        for security in changes.AddedSecurities:
            # Historical data
            history = self.History(security.Symbol, 7, Resolution.Daily)
            self.Debug(f'We got {len(history)} from our history request for {security.Symbol}')