Overall Statistics
Total Orders
1
Average Win
0%
Average Loss
0%
Compounding Annual Return
2.519%
Drawdown
8.200%
Expectancy
0
Start Equity
1000000
End Equity
1087951.22
Net Profit
8.795%
Sharpe Ratio
-0.484
Sortino Ratio
-0.553
Probabilistic Sharpe Ratio
7.761%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
-0.031
Beta
0.323
Annual Standard Deviation
0.051
Annual Variance
0.003
Information Ratio
-0.416
Tracking Error
0.107
Treynor Ratio
-0.077
Total Fees
$3.61
Estimated Strategy Capacity
$3600000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
Portfolio Turnover
0.03%
from AlgorithmImports import *

class StagedVixInvestment(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2022, 1, 3)
        self.SetCash(1000000)

        self.spy = self.AddEquity("SPY", Resolution.Daily).Symbol
        self.vix = self.AddEquity("VIX", Resolution.Daily).Symbol

        self.vix_sma = self.SMA(self.vix, 20, Resolution.Daily)
        self.consecutive_above_sma = 0

        self.invested_stage_1 = False
        self.invested_stage_2 = False
        self.invested_stage_3 = False

        self.Schedule.On(self.DateRules.EveryDay(self.vix), 
                         self.TimeRules.AfterMarketOpen(self.vix, 5), 
                         self.CheckVIXConditions)

    def OnData(self, data: Slice):
        # Stage 1 investment: immediately on first run
        if not self.invested_stage_1:
            self.SetHoldings(self.spy, 0.33)
            self.invested_stage_1 = True
            self.Debug(f"{self.Time.date()} | Initial 33% SPY invested")

    def CheckVIXConditions(self):
        if not self.vix_sma.IsReady or self.vix not in self.CurrentSlice:
            return

        vix_price = self.CurrentSlice[self.vix].Price
        sma_value = self.vix_sma.Current.Value

        # Check if VIX > SMA
        if vix_price > sma_value:
            self.consecutive_above_sma += 1
        else:
            self.consecutive_above_sma = 0  # reset counter if condition breaks

        self.Debug(f"{self.Time.date()} | VIX: {vix_price:.2f}, SMA: {sma_value:.2f}, Days above SMA: {self.consecutive_above_sma}")

        # Stage 2: after 5 consecutive days
        if self.consecutive_above_sma >= 5 and not self.invested_stage_2:
            self.SetHoldings(self.spy, 0.66)
            self.invested_stage_2 = True
            self.Debug(f"{self.Time.date()} | Stage 2: 66% SPY invested")

        # Stage 3: after 7 total consecutive days
        if self.consecutive_above_sma >= 7 and not self.invested_stage_3:
            self.SetHoldings(self.spy, 0.99)
            self.invested_stage_3 = True
            self.Debug(f"{self.Time.date()} | Stage 3: Full 99% SPY invested")