Overall Statistics
Total Trades
47
Average Win
8.99%
Average Loss
-3.73%
Compounding Annual Return
4.674%
Drawdown
27.700%
Expectancy
1.132
Net Profit
201.861%
Sharpe Ratio
0.174
Sortino Ratio
0.149
Probabilistic Sharpe Ratio
0.038%
Loss Rate
38%
Win Rate
62%
Profit-Loss Ratio
2.41
Alpha
0.004
Beta
0.252
Annual Standard Deviation
0.082
Annual Variance
0.007
Information Ratio
-0.196
Tracking Error
0.14
Treynor Ratio
0.057
Total Fees
$366.03
Estimated Strategy Capacity
$1100000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
Portfolio Turnover
0.51%
# 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()