Overall Statistics
Total Trades
25328
Average Win
0.02%
Average Loss
-0.02%
Compounding Annual Return
-27.824%
Drawdown
29.900%
Expectancy
-0.121
Net Profit
-28.146%
Sharpe Ratio
-2.974
Probabilistic Sharpe Ratio
0.000%
Loss Rate
56%
Win Rate
44%
Profit-Loss Ratio
1.00
Alpha
-0.347
Beta
0.437
Annual Standard Deviation
0.092
Annual Variance
0.008
Information Ratio
-4.463
Tracking Error
0.099
Treynor Ratio
-0.624
Total Fees
$25513.28
class CalibratedHorizontalCompensator(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2019, 1, 30)  # Set Start Date
        self.SetCash(100000)  # Set Strategy Cash
        # Add SPY to set scheduled events
        self.AddEquity("SPY", Resolution.Minute)
        # Setting Universe
        self.UniverseSettings.Resolution = Resolution.Minute
        self.SetUniverseSelection(QC500UniverseSelectionModel())
        # Dictionary to keep track of previous close for each symbol
        self.previousClose = {}
        # Dictionary to keep track of weekly cumulative performance for each symbol
        self.performance = {}
        
        # Our Scheduled Events
        self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 30), self.Rebalance)
        self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY", 1), self.OnMarketClose)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Friday) , self.TimeRules.BeforeMarketClose("SPY", 5), self.GetTopPerformers)
        
        # list for top performers of week
        self.top = []
    
    def OnSecuritiesChanged(self, changes):
        
        for security in changes.AddedSecurities:
            symbol = security.Symbol
            # Make a history call for symbol to get last closing price
            if symbol not in self.previousClose:
                history = self.History(symbol, 1, Resolution.Daily)
                if not history.empty:
                    history = history.close.unstack(0)[symbol]
                    if not history.empty:
                        self.previousClose[symbol] = history[0]
            
        # Remove symbols from previous close as they are removed from the universe
        for security in changes.RemovedSecurities:
            symbol = security.Symbol
            self.previousClose.pop(symbol, None)
                
    def Rebalance(self):
        # Dictionary to keep track of percent change from last close
        percentChange = {}
        
        # Populate Dictionary
        for symbol, previousClose in self.previousClose.items():
            if self.CurrentSlice.ContainsKey(symbol):
                price = self.CurrentSlice[symbol].Close
                change = (price - previousClose)/previousClose
                percentChange[symbol] = change
        
        # Symbols under consideration
        symbols = list(percentChange.keys())
        # Sort symbols by percent change
        sortedSymbols = sorted(symbols, key=lambda x : percentChange[x], reverse = True)
        # Get top 50 symbols
        selected = sortedSymbols[:50]
        # Set holdings equally to those symbols
        for symbol in selected:
            self.SetHoldings(symbol, 1 / len(selected))
    
    def OnMarketClose(self):
        # Store cumulative performance for symbols in portfolio
        for kvp in self.Portfolio:
            symbol = kvp.Key
            holding = kvp.Value
            if holding.Invested:
                if symbol not in self.performance:
                    self.performance[symbol] = holding.UnrealizedProfitPercent
                else:
                    self.performance[symbol] = self.performance[symbol] + holding.UnrealizedProfitPercent
        # Liquidate portfolio        
        self.Liquidate()
        
        # Store new previous close values
        for symbol in self.previousClose:
            if self.CurrentSlice.ContainsKey(symbol):
                self.previousClose[symbol] = self.CurrentSlice[symbol].Close
        
            
    def GetTopPerformers(self):
        # Symbols under consideration
        symbols = list(self.performance.keys())
        # Symbols sorted by performance
        sortedSymbols = sorted(symbols, key=lambda x: self.performance[x], reverse=True)
        # Top 10 performers
        self.top = sortedSymbols[:10]
        # Reset performances
        self.performance = {}