Overall Statistics
Total Orders
42
Average Win
11.28%
Average Loss
-4.45%
Compounding Annual Return
6.016%
Drawdown
30.200%
Expectancy
1.355
Start Equity
100000
End Equity
427149.68
Net Profit
327.150%
Sharpe Ratio
0.268
Sortino Ratio
0.234
Probabilistic Sharpe Ratio
0.210%
Loss Rate
33%
Win Rate
67%
Profit-Loss Ratio
2.53
Alpha
0.011
Beta
0.274
Annual Standard Deviation
0.085
Annual Variance
0.007
Information Ratio
-0.146
Tracking Error
0.136
Treynor Ratio
0.083
Total Fees
$332.22
Estimated Strategy Capacity
$1400000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
Portfolio Turnover
0.45%
# https://quantpedia.com/strategies/january-barometer/
#
# Invest in the equity market in each January. Stay invested in equity markets (via ETF, fund, or futures) only if January return is positive; otherwise, switch investments to T-Bills.
#
# QC implementation changes:
#   - T-bill is replaced by iShares 1-3 Year Treasury Bond ETF.

from AlgorithmImports import *

class JanuaryBarometer(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2000, 1, 1)
        self.SetCash(100000) 
        
        leverage:int = 5
        data:Equity = self.AddEquity("SPY", Resolution.Daily)
        data.SetLeverage(leverage)
        self.market:Symbol = data.Symbol
        
        data:Equity = self.AddEquity("SHY", Resolution.Daily)
        data.SetLeverage(leverage)
        self.bond:Symbol = data.Symbol
        
        self.max_missing_days:int = 5

        self.start_price:float|None = None
        self.recent_month:int = -1
        
    def OnData(self, data):
        if self.recent_month == self.Time.month:
            return
        self.recent_month = self.Time.month
        
        if self.Securities[self.market].GetLastData() and self.Securities[self.bond].GetLastData():
            if (self.Time.date() - self.Securities[self.market].GetLastData().Time.date()).days < 5 and (self.Time.date() - self.Securities[self.bond].GetLastData().Time.date()).days < self.max_missing_days:
                if self.Time.month == 1:
                    self.Liquidate(self.bond)
                    self.SetHoldings(self.market, 1)
                    
                    self.start_price = self.Securities[self.market].Price
                    
                if self.Time.month == 2 and self.start_price:
                    perf:float = self.Securities[self.market].Price / self.start_price - 1
                    if perf > 0:
                        self.SetHoldings(self.market, 1)
                    else:
                        self.start_price = None
                        self.Liquidate(self.market)
                        self.SetHoldings(self.bond, 1)
            else:
                self.Liquidate()
        else:
            self.Liquidate()