Overall Statistics |
Total Trades 146 Average Win 0.03% Average Loss -0.04% Compounding Annual Return -2.187% Drawdown 1.300% Expectancy -0.117 Net Profit -0.375% Sharpe Ratio -0.574 Probabilistic Sharpe Ratio 20.842% Loss Rate 54% Win Rate 46% Profit-Loss Ratio 0.90 Alpha -0.027 Beta 0.049 Annual Standard Deviation 0.026 Annual Variance 0.001 Information Ratio -2.485 Tracking Error 0.103 Treynor Ratio -0.306 Total Fees $146.00 Estimated Strategy Capacity $13000000.00 Lowest Capacity Asset SMID XJLTRYSI6U79 Portfolio Turnover 2.71% |
# region imports from AlgorithmImports import * # endregion class EarningsContinuation(QCAlgorithm): def Initialize(self): self.SetStartDate(2021, 9, 12) # Set Start Date self.SetEndDate(2021, 11, 12) self.SetCash(100000) # Set Strategy Cash self.UniverseSettings.Resolution = Resolution.Daily self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction) #self.UniverseSettings.DataNormalizationMode = DataNormalizationMode.Raw self.entryTime = datetime.min self.gaps= {} self.strongclose = 0 self.openPositions ={} self.finalfilter = [] self.longs = [] self.tickets = [] self.AddEquity("SPY", Resolution.Daily) self.SetBenchmark("SPY") self.Schedule.On(self.DateRules.EveryDay("SPY"),self.TimeRules.AfterMarketOpen("SPY", 5),self.EveryMarketOpen) def CoarseSelectionFunction(self,coarse): sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True) byprice = [x for x in sortedByDollarVolume if x.DollarVolume > 1000000 and x.Price > 5 and x.HasFundamentalData] byprice = [x.Symbol for x in byprice] return byprice def FineSelectionFunction(self,fine): fineUniverse = [] yesterday = self.Time - timedelta(days=1) for x in fine: if x.EarningReports.FileDate == yesterday and x.MarketCap > 5e7: self.Log(f'stock{x.Symbol.Value} has earnings on {x.EarningReports.FileDate}') fineUniverse.append(x) symbols = [x.Symbol for x in fineUniverse] #if self.IsWarmingUp: return price = self.History(symbols, timedelta(days=2), Resolution.Daily) # two days index - 0 is yesterday #price = self.History(Tradebar, symbols, start_time = yesterday, end_time = self.Time, Resolution.Daily) #dataNormalizationMode=DataNormalizationMode.Raw #Strong earnings close, then buy the next day #ex. ORCL 9/13/2021 reported earnings after the market closed for sec in symbols: try: earningsdayopen = price.loc[sec]['open'][0] earningsdayclose = price.loc[sec]['close'][0] earningsdayhigh = price.loc[sec]['high'][0] afterearningsopen = price.loc[sec]['open'][-1] except: self.Debug(f"History data unavailable for {sec}") continue closestrength= (earningsdayclose-earningsdayopen)/(earningsdayhigh-earningsdayopen) percentGap = (afterearningsopen / earningsdayclose) - 1 if closestrength >=0.8 and percentGap > 0.01: self.longs.append(sec) self.Log(f"adding {sec} to long list with strength close{closestrength} and gap up of {percentGap}") return self.longs def OnSecuritiesChanged(self, changes): for security in changes.AddedSecurities: if security != 'SPY': self.Log(f'about to trade {security}') self.MarketOrder(security,10) self.entryTime = self.Time self.openPositions[security] = self.entryTime def EveryMarketOpen(self): for position in list(self.openPositions.keys()): if self.openPositions[position] + timedelta(days=5) <= self.Time : self.Liquidate(position.Symbol) self.openPositions.pop(position) else: continue