Signals-Before-Storms

The model worked. The strategy did not.

A Hidden Markov Model splits eight years of Indian and US markets into calm, stressed and crisis states, and a convex optimizer sets portfolio weights per state. The states are real, and they are volatility states. Volatility carries no direction, so de-risking on the crisis label sells the rebound as reliably as it dodges the crash.

India, walk-forward out of sample, loading. Every number on this page is computed by the same code that prints the scorecard, exported straight from the run.

Growth of 1 unit. The shaded bands are the walk-forward regime path, lightest for Bull and darkest for Crisis. Hover or tap for a dated readout.
Drawdown. This is where the overlay earns its keep on India, and where it does not on the US.
What each state predicts. Volatility rises with the label exactly as intended. So does return, and that is the wrong direction.
The gap, not the level. Two overlapping marginal intervals say nothing about a difference. These books hold the same assets on the same days, so the paired difference is the test the comparison actually rests on.

Why it fails, in three facts

  1. The states order volatility perfectly and return backwards. On both universes the calmest label returns the least and the crisis label the most. Realized volatility and VIX are symmetric in sign: they spike in a crash, then spike again in the rebound.
  2. Days are not a sample size, episodes are. India's crisis label spans 261 days but only 14 episodes. Drop the single longest one and its return goes from +18.4% to +53.6%.
  3. Four rescues failed on criteria written down first. Re-ranking by return, a jump model, volatility targeting, and a drawdown feature. The drawdown feature now tops the India Sharpe table and is still not adopted, because it failed the test it was given.

One apparent discovery was retracted the same day it was written up, by counting episodes. The full log tells it in the order it happened, including the retraction, the pre-registered criteria, and leak-proofing that is asserted by unit tests rather than claimed in prose.

The same model, running live

Everything above is the research window, fixed at 2015 to 2024 so the numbers cannot move under you. The same pipeline, with every knob frozen, also runs forward to the present on a wider set of markets. Nothing was re-fitted or re-chosen to make it work there, which is what makes it a genuine out-of-sample test rather than a second search.

Regime Monitor
Eleven markets across four asset classes, each with its own model. Which state every market is in right now, how confident the filter is, how long it has been there, and what that regime's measured volatility implies for position size. Reads risk, not direction.
The Storm Ledger
The same eleven-market result read as a broadsheet: every price path above its own regime rail, so you can see for yourself that inside the darkest bands several markets are rising. That is the finding, in one image.

The volatility ordering replicates on 11 of 11 markets. The return ordering does not, and it does not fail the same way twice, which is a stronger negative than the one found here.

How it is built

Regime detection
3-state Gaussian HMM via hmmlearn, causal forward filter for every out-of-sample label
Allocation
cvxpy per regime: max Sharpe in Bull, min variance in Bear, equity-capped in Crisis
Validation
expanding walk-forward, model refit per fold, scaling fitted on train only, one-day execution lag
Costs
7.5 bps per rebalance charged to every book alike, benchmarks included
Deflation
probabilistic and deflated Sharpe at 7 declared trials, stationary bootstrap intervals
Data
yfinance daily from 2015: NIFTY, an overnight cash fund and gold on India, SPY, TLT and GLD on the US, plus each market's VIX

Python 3.11+, uv-managed, 80 tests, Apache-2.0. The leak-proofing is asserted rather than stated: flip a future label and the backtest must not notice, or the test fails.