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