Overall Statistics |
Total Trades 1006 Average Win 0.70% Average Loss -0.99% Compounding Annual Return -82.941% Drawdown 83.800% Expectancy -0.347 Net Profit -83.024% Sharpe Ratio -2.67 Probabilistic Sharpe Ratio 0.000% Loss Rate 62% Win Rate 38% Profit-Loss Ratio 0.71 Alpha -0.709 Beta 0.231 Annual Standard Deviation 0.26 Annual Variance 0.068 Information Ratio -2.765 Tracking Error 0.274 Treynor Ratio -3.01 Total Fees $2208.32 Estimated Strategy Capacity $1100000.00 Lowest Capacity Asset CNTE SAI0XJNH6IJP |
#region imports from AlgorithmImports import * #endregion class FadingTheGap(QCAlgorithm): def Initialize(self): #Backtesting parameters self.SetStartDate(2017, 11, 1) self.SetEndDate(2018, 11, 1) self.SetCash(100000) self.minimumDollar = 100 self.maximumDollar = 5000 self.topVolume = 100 # Universe Settings self.UniverseSettings.Resolution = Resolution.Minute self.AddUniverse(self.CoarseSelectionFunction) # Securities list that is dynamically changes by the universe coarse filter self.SecuritiesList = [] # Schedules self.AddEquity("SPY", Resolution.Minute) self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", 1), self.OpeningBar) self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", 45), self.ClosePositions) def CoarseSelectionFunction(self, coarse): # Sort equities by volume - highest volume first sortedByDollarVolume = sorted(coarse, key=lambda c: c.DollarVolume, reverse=True) # Filter equities by price filteredByPrice = [c.Symbol for c in sortedByDollarVolume if c.Price > self.minimumDollar and c.Price < self.maximumDollar] # Retrieve top equities self.SecuritiesList = filteredByPrice[:self.topVolume] return self.SecuritiesList def OpeningBar(self): securityDelta = {} securitySTD = {} securityDeviations = {} # Go through all the top traded securities of the day for symbol in self.SecuritiesList: # Retrieve the previous closing price of those securities history = self.History(symbol, 2, Resolution.Daily) if history.empty: continue previousClose = history.iloc[len(history.index) - 2]['close'] if previousClose <= 0: continue # Retrieve the current day open of the same securities if not self.Securities.ContainsKey(symbol): continue if self.Securities[symbol] is None: continue if self.Securities[symbol].Open <= 0: continue currentOpen = self.Securities[symbol].Open delta = 0 if currentOpen < previousClose: # Record the delta if the open is less than the previous close in securityDelta dictionary delta = currentOpen - previousClose else: continue # Retrieve the standard deviation of the security for the past 60 minutes velocityHistory = self.History(symbol, 60, Resolution.Minute) std = velocityHistory.loc[:, 'close'].std() # Calculate and record the deviation if it is 3 deviations away # 68% (1 sigma deviation) # 95% (2 sigma deviation) # 99.7% (3 sigma deviation) # < -3 says that the drop is a .3% deviation deviation = delta / std if deviation < -3: securityDeviations[symbol] = deviation self.Log(deviation) if len(securityDeviations) > 0: # Sort any notable deviations by ascending order - strongest deviations first sortedDeviations = sorted(securityDeviations.items(), key=lambda x: x[1]) # Retrieve the top two winners topDeviations = sortedDeviations[:2] # Invest 100% in the security with the biggest deviation for security in topDeviations: self.SetHoldings(security[0], 1) def ClosePositions(self): self.Liquidate()