Overall Statistics |
Total Trades 888 Average Win 2.70% Average Loss -2.57% Compounding Annual Return 9.240% Drawdown 51.900% Expectancy 0.214 Net Profit 712.114% Sharpe Ratio 0.456 Probabilistic Sharpe Ratio 0.050% Loss Rate 41% Win Rate 59% Profit-Loss Ratio 1.05 Alpha 0.032 Beta 0.785 Annual Standard Deviation 0.173 Annual Variance 0.03 Information Ratio 0.158 Tracking Error 0.124 Treynor Ratio 0.101 Total Fees $31086.96 Estimated Strategy Capacity $1200000.00 Lowest Capacity Asset XLP RGRPZX100F39 Portfolio Turnover 10.23% |
#from: https://cssanalytics.wordpress.com/2023/08/12/business-cycle-sector-timing/ # region imports from AlgorithmImports import * # endregion class WellDressedYellowCormorant(QCAlgorithm): def Initialize(self): self.SetStartDate(2000,1,1) self.SetCash(100000) self.sigeq = ['SPY'] self.inveq = ['XLP','IYR','XLK'] self.eqs = pd.Series(['XLP','IYR','XLK','XLP'], index=['Recession','Recovery','Expansion','Slowdown']) for eq in list(set(self.sigeq+self.inveq)): self.AddEquity(eq,Resolution.Minute) self.prds = [[3,20],[10,200]] self.Schedule.On(self.DateRules.EveryDay(self.eqs[0]),self.TimeRules.AfterMarketOpen(self.eqs[0], 30),self.InitTrade) self.Trade = False def InitTrade(self): self.Trade = True def OnData(self, data: Slice): if self.Trade: self.hist = self.History(self.sigeq,max([max(p) for p in self.prds]), Resolution.Daily) close = self.hist['close'].unstack(level=0) short = (close.iloc[-self.prds[0][0]:,:].mean()[0] > close.iloc[-self.prds[0][1]:,:].mean()[0]) * 1 long = (close.iloc[-self.prds[1][0]:,:].mean()[0] > close.iloc[-self.prds[1][1]:,:].mean()[0]) * 1 if not(short) and not(long): self.econ = 'Recession' elif short and not(long): self.econ = 'Recovery' elif short and long: self.econ = 'Expansion' else: self.econ = 'Slowdown' inveq = self.eqs[self.econ] self.wts = pd.Series(0,index=self.inveq) self.wts[inveq] = 1 self.SetHoldings([PortfolioTarget(a, b) for a,b in zip(self.wts.index,self.wts)]) self.Trade = False