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 = {}