Overall Statistics |
Total Trades 536 Average Win 0.33% Average Loss -0.11% Compounding Annual Return 38.289% Drawdown 7.400% Expectancy 0.108 Net Profit 4.170% Sharpe Ratio 1.613 Probabilistic Sharpe Ratio 53.994% Loss Rate 74% Win Rate 26% Profit-Loss Ratio 3.18 Alpha 0.674 Beta -0.012 Annual Standard Deviation 0.399 Annual Variance 0.159 Information Ratio -3.363 Tracking Error 0.544 Treynor Ratio -53.006 Total Fees $1295.95 |
from Execution.ImmediateExecutionModel import ImmediateExecutionModel from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel class QuantumHorizontalRegulators(QCAlgorithm): def Initialize(self): self.SetStartDate(2020, 3, 24) # Set Start Date #self.SetEndDate(2019, 11, 14) # Set Start Date self.SetCash(100000) # Set Strategy Cash self.AddEquity("SPY", Resolution.Minute) self.scaning = False self.lastToggle = None self.__numberOfSymbols = 100 self.SetUniverseSelection(FineFundamentalUniverseSelectionModel(self.CoarseSelectionFunction, self.FineSelectionFunction, None, None)) self.AddAlpha(FadeTheGapModel(self)) self.SetExecution(ImmediateExecutionModel()) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", 0), self.toggleScan) self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", 45), self.toggleScan) def toggleScan(self): self.scaning = not self.scaning self.lastToggle = self.Time def CoarseSelectionFunction(self, coarse): # Stocks with the most dollar volume traded yesterday sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True) return [ x.Symbol for x in sortedByDollarVolume[:self.__numberOfSymbols] ] def FineSelectionFunction(self, fine): return [ x.Symbol for x in fine ] class FadeTheGapModel(AlphaModel): yest_closes = {} def __init__(self, algo): self.algo = algo def Update(self, algorithm, slice): if algorithm.IsWarmingUp: return [] # If it's the end of the day, update the yesterday close of each indicator if not algorithm.Securities['SPY'].Exchange.ExchangeOpen: for symbol, yest_close in self.yest_closes.items(): if symbol in slice.Bars: self.yest_closes[symbol] = slice.Bars[symbol].Close if not self.algo.scaning: return [] insights = [] duration = algorithm.Time - self.algo.lastToggle insight_mins = 45 - (duration.seconds // 60 % 60) # Create insights for symbols up atleast 10% on the day for symbol, yest_close in self.yest_closes.items(): # If already invested, continue to next symbol if algorithm.Securities[symbol].Invested or symbol not in slice.Bars: continue # Calculate return sign yesterday's close ret = (slice[symbol].Close - yest_close) / yest_close if ret >= 0.1: # Up 10% on the day insights.append(Insight(symbol, timedelta(minutes=insight_mins), InsightType.Price, InsightDirection.Down)) return Insight.Group(insights) def OnSecuritiesChanged(self, algorithm, changes): if len(changes.AddedSecurities) > 0: # Get history of symbols over lookback window added_symbols = [x.Symbol for x in changes.AddedSecurities] history = algorithm.History(added_symbols, 1, Resolution.Daily)['close'] for added in changes.AddedSecurities: # Save yesterday's close closes = history.loc[[str(added.Symbol.ID)]].values if len(closes) < 1: continue self.yest_closes[added.Symbol] = closes[0] for removed in changes.RemovedSecurities: # Delete yesterday's close tracker self.yest_closes.pop(removed.Symbol, None)