Overall Statistics
Total Trades
123
Average Win
7.43%
Average Loss
-0.97%
Compounding Annual Return
3.981%
Drawdown
21.800%
Expectancy
0.995
Net Profit
60.463%
Sharpe Ratio
0.387
Probabilistic Sharpe Ratio
0.546%
Loss Rate
77%
Win Rate
23%
Profit-Loss Ratio
7.69
Alpha
0.003
Beta
0.292
Annual Standard Deviation
0.079
Annual Variance
0.006
Information Ratio
-0.529
Tracking Error
0.123
Treynor Ratio
0.105
Total Fees
$5840.47
Estimated Strategy Capacity
$490000.00
Lowest Capacity Asset
BIL TT1EBZ21QWKL
# region imports
from AlgorithmImports import *
# endregion

class AdaptableYellowLeopard(QCAlgorithm):

    def Initialize(self):
        start = datetime(2011, 1, 1)   # Start date
        end = datetime(2024, 12, 30)    # End date
        cash = 1000000                  # Starting capital
        self.period = 900                # rolling period to consider for drawup and drawdown calculations

        self.SetStartDate(start)  # Set Start Date
        self.SetEndDate(end)
        self.SetCash(cash)  # Set Strategy Cash

        self.AddEquity("SPY", Resolution.Minute)
        self.AddEquity("BIL", Resolution.Minute)
        self.AddEquity("TLT", Resolution.Minute)
        self.AddEquity("IAU", Resolution.Minute)

        self.high = RollingWindow[float](self.period)
        self.low = RollingWindow[float](self.period)
        self.close = RollingWindow[float](self.period)

        self.state1 = False
        self.state2 = False
        self.state3 = False

        # self.spy
        # self.Schedule.On(self.DateRules.MonthEnd("SPY", 1), 
        self.Schedule.On(self.DateRules.EveryDay("SPY"),
            self.TimeRules.BeforeMarketClose("SPY", 2),
            self.FunctionBeforeMarketClose)

    def OnData(self, slice: Slice):
        pass

    def LiquidateExisting(self, symbols):

        for symbol in symbols:

            quantity = self.Portfolio[symbol].Quantity 

            if quantity != 0:
                self.MarketOrder(symbol, -quantity, tag=f"Rebalancing {symbol}")

    def FunctionBeforeMarketClose(self):

        self.close = self.Securities['SPY'].Close
        self.high.Add(self.Securities['SPY'].High)  
        self.low.Add(self.Securities['SPY'].Low)

        if self.high.IsReady:
            dd = abs((self.close / max(self.high)) - 1) * 100
            du = (1 - (min(self.low) / self.close)) * 100

            if dd ==0:
                dd == .0000001    

        # if dd != -1000000:
            ddd = dd
            # ddd = dd / du

            if ddd < 7 and not self.state1:
                # 100% SPY
                self.LiquidateExisting(['BIL', 'TLT', 'IAU'])

                quantity = self.CalculateOrderQuantity("SPY", 1.0)
                self.MarketOrder('SPY', quantity, tag='100% SPY')
                self.state1 = True
                self.state2 = False
                self.state3 = False

            if ddd >= 7 and not self.state2:
                # 50% BIL, 40% TLT, 10% IAU
                self.LiquidateExisting(['SPY'])
                quantity = self.CalculateOrderQuantity("BIL", 1.0)
                self.MarketOrder('BIL', quantity, tag='50% BIL')

                # quantity = self.CalculateOrderQuantity("TLT", 0.2)
                # self.MarketOrder('TLT', quantity, tag='40% TLT')

                # quantity = self.CalculateOrderQuantity("IAU", 1.0)
                # self.MarketOrder('IAU', quantity, tag='10% IAU')


                # quantity = self.CalculateOrderQuantity("BIL", 0.25)
                # self.MarketOrder('BIL', quantity, tag='50% BIL')

                # quantity = self.CalculateOrderQuantity("TLT", 0.2)
                # self.MarketOrder('TLT', quantity, tag='40% TLT')

                # quantity = self.CalculateOrderQuantity("IAU", 0.05)
                # self.MarketOrder('IAU', quantity, tag='10% IAU')

                self.state2 = True
                self.state1 = False
                self.state3 = False

            # if 1.2 >= ddd >= 0.8 and not self.state3:
            #     # 50% SPY, 50% BIL
            #     self.LiquidateExisting(['TLT', 'IAU'])

            #     quantity = self.CalculateOrderQuantity("SPY", 0.25)
            #     self.MarketOrder('SPY', quantity, tag='50% SPY')

            #     quantity = self.CalculateOrderQuantity("BIL", 0.25)
            #     self.MarketOrder('BIL', quantity, tag='50% BIL')
            #     self.state3 = True
            #     self.state1 = False
            #     self.state2 = False