After the disappointing results of volatility targeting in the last post, I tried a different approach to risk management: VIX regime switching. Instead of continuously adjusting weights based on realised vol, this strategy makes a binary decision — are we in a calm market or a fearful one — and holds a different fixed allocation for each regime.
The results are more interesting.
The Strategy
Signal.VIX monitors the VIX index and switches between two child portfolios:
- Low-vol regime (VIX below 20): 70% QQQ / 20% BIL / 10% GLD — risk-on, same as the baseline
- High-vol regime (VIX above 30): 40% QQQ / 40% BIL / 20% GLD — risk-off, much more defensive
- Between 20–30: hysteresis — stick with whatever regime you are currently in
The hysteresis band is important. Without it, the portfolio would thrash back and forth every time VIX crosses the threshold, racking up fees.
low_vol = ti.Portfolio("low_vol", [
ti.Select.All(),
ti.Weigh.Ratio(weights={"QQQ": 0.7, "BIL": 0.2, "GLD": 0.1}),
ti.Action.Rebalance(),
], TICKERS)
high_vol = ti.Portfolio("high_vol", [
ti.Select.All(),
ti.Weigh.Ratio(weights={"QQQ": 0.4, "BIL": 0.4, "GLD": 0.2}),
ti.Action.Rebalance(),
], TICKERS)
vix_regime = ti.Portfolio("vix_regime", [
ti.Signal.Monthly(),
ti.Signal.VIX(high=30, low=20, data=vix_data),
ti.Action.Rebalance(),
], [low_vol, high_vol])
The parent/child architecture is one of my favourite features of TiPortfolio. You can nest portfolios and the parent controls when to switch between children.
Results (2019–2024)
sharpe 0.687
calmar 0.632
sortino 0.923
max_drawdown -0.209
cagr 0.132
total_return 1.382
final_value 23815.691
total_fee 2.260
rebalance_count 83
Compared against the fixed-ratio baseline and QQQ-only:
vix_regime qqq_only fixed_70_20_10
sharpe 0.687 0.684 0.642
calmar 0.632 0.547 0.546
sortino 0.923 0.889 0.833
max_drawdown -0.209 -0.351 -0.264
cagr 0.132 0.192 0.144
final_value 23815.691 34106.625 25588.316
total_fee 2.260 0.233 0.939
The VIX regime strategy has the best risk-adjusted returns of everything I have tested so far. Sharpe of 0.687, Sortino of 0.923, Calmar of 0.632 — all better than the fixed 70/20/10 and actually beating QQQ-only on a risk-adjusted basis.
The max drawdown is only -20.9%, compared to -26.4% for fixed ratio and -35.1% for QQQ-only. That is the VIX switch doing its job — during the 2020 COVID crash and 2022 rate hike cycle, VIX spiked above 30 and the portfolio shifted to the defensive allocation.
The Trade-Off
The total return is lower than QQQ-only (138% vs 241%). If you bought QQQ on day one and held, you made more money. But you also lived through a -35% drawdown.
The VIX strategy gave you a much smoother ride — the worst month was only -6.3% vs -9.7% for the fixed ratio portfolio. For someone who would panic-sell during a crash, this matters a lot in practice.
Total return numbers don't tell the whole story. A -35% drawdown can cause behavioural mistakes. The portfolio you can stick with through a crash is often worth more than the theoretically superior one you abandon at the bottom.
My Take
This is the most promising strategy in the series so far. It is simple (just a threshold rule on VIX), it has a clear rationale, and the results hold up.
The CAGR of 13.2% is only slightly below the fixed ratio baseline of 14.4%, but with meaningfully lower volatility and drawdown. That is a good trade.
The limitation is that VIX is US equity volatility — this works well for a QQQ-heavy portfolio but may not generalise to other asset classes.
Next I look at something completely different: a dollar-neutral pair trade.
This Series
- Part 1: Fixed Ratio Rebalancing
- Part 2: Volatility Targeting
- Part 3: VIX Regime Switching ← you are here
- Part 4: Dollar-Neutral Pair Trade
- Part 5: Beta-Neutral Dynamic Strategy
- Part 6: Auto Investment Plan (DCA)