| 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