Trade Holistic /Alpha Explainer Download Markdown
Research paper · Alpha Explainer

Regime-Based Portfolio Allocation with Hidden Markov Models and Reinforcement Learning

A 3-state HMM sorts the market into calm, transitional and crisis regimes, then a small, readable RL policy decides what to hold in each one.

Authors: Ajay Kumar Verma, Nunik Srikandi Putri, Neo Paul LesupiPublished: 2026-05-27Venue: arXiv preprint (q-fin), not peer-reviewedGenerated: 2026-10-16Trust: machine-confirmedRead: 7 min
regime detectionhidden markov modelreinforcement learningasset allocationregime gating

Core idea: Label the volatility regime with an HMM, then hold what has worked best in that regime.

Strategy family
regime switching, tactical allocation, ML/AI
Markets
US equity ETFs, treasuries, gold
Timeframes
1D
Data needed
daily closes, VIX
Complexity
intermediate
MCI RELEVANCESame two-layer design as MCI: classify the regime first, then switch exposure. The paper's transitional state plays the role of MCI's indecision ranges.

TL;DR

The idea in plain language

Markets don't behave the same way all the time. Calm periods, nervous periods and crashes each have their own "personality": different volatility, different winners and different correlations. The paper's bet is simple:

  1. Figure out which personality the market is in right now (the regime).
  2. Hold whatever has historically worked best in that regime.

The regime is "hidden" because you can't observe it directly. You only see daily returns, and you infer the regime from how those returns behave. That's what a Hidden Markov Model is built for.

1 · Data Daily SPY, TLT, GLD log returns + ΔVIX 2004–2025 2 · Regime model 3-state Gaussian HMM fit with EM, picked by BIC Hamilton filter · Viterbi path 3 · Regime label Low vol Transitional High vol / crisis 4a · Rule rotation Top-1 asset per regime or 60/40 top-two 4b · RL policy tabular policy iteration 7 discrete weight mixes 5 · Trade at t+1 (1-day lag) Train on first 70% of history, test on the last 30% out-of-sample. Zero transaction costs in the baseline.
How the system works, end to end

How it works

Step 1: Data

Daily closing prices for SPY, TLT, GLD and the VIX from Yahoo Finance, covering 2004 to 2025. Prices become daily log returns, and the VIX becomes a daily change (ΔVIX) to capture volatility shocks.1

Step 2: A warm-up Markov chain

Before the HMM, the authors bin ΔVIX into 3 volatility buckets and count how often the market moves from one bucket to another. The buckets turn out to be sticky: once you're in one, you tend to stay. That stickiness is the empirical reason a regime model makes sense at all.

Step 3: The Hidden Markov Model

State 0 Low volatility 50.8% of days State 1 Transitional 43.0% of days State 2 High vol / crisis 6.2% of days stay 0.939 stay 0.909 stay 0.874 0.061 → ← 0.073 0.018 → ← 0.126 Daily transition probabilities from the paper's Table 2(b). Jumps straight between State 0 and State 2 are ~0. Calm and crisis are only connected through the transitional regime, the "indecision" zone.
The three regimes and how the market moves between them

Regime character and share of days, per the paper's Tables 2–3:1

Regime Share of days Character (from the paper)
State 0, low volatility 50.83% Stable expansion. SPY has the highest mean return and lowest dispersion.
State 1, transitional 42.98% Muted returns, a bit more volatility, no asset clearly dominates.
State 2, high volatility 6.18% Crisis. SPY has a strongly negative mean, while TLT and GLD hold up.

Two details are worth noticing. All three regimes are very persistent (daily "stay" probabilities of 0.94, 0.91 and 0.87). And the model essentially never jumps straight from calm to crisis: it passes through the transitional regime first.

Step 4a: Rule-based rotation

Two simple rules map each regime to holdings (paper's Table 4):1

Regime Top-1 rule 60/40 rule
State 0, low vol 100% SPY 60% SPY / 40% GLD
State 1, transitional 100% GLD 60% GLD / 40% TLT
State 2, high vol 100% TLT 60% TLT / 40% GLD

Trades are executed with a one-day lag. The regime is decided at day t, and the position earns day t+1's return. This avoids look-ahead bias.

Step 4b: The reinforcement-learning policy

The policy it learned on the training data is tiny and easy to read (paper's Table 5):1

Regime RL holds
State 0, low vol 100% SPY
State 1, transitional 100% SPY
State 2, high vol 100% GLD

In other words: take equity risk unless the market is in crisis, then hide in gold. TLT gets no allocation at all.

Results

The data are split chronologically: the first 70% is for training, and the last 30% is a strict out-of-sample test. The backtest is daily, with a 1-day lag and zero transaction costs.

Sharpe ratio (higher is better) Max drawdown (shorter is better) RL policy π* 0.83 −23.5% Rotation Top-1 0.79 −21.8% Rotation 60/40 0.82 −29.3% Equal-weight 0.83 −24.0% Buy & hold SPY 0.65 −35.7% Out-of-sample test window (last 30% of 2004–2025), daily, 1-day lag, zero costs. Source: paper Table 7.
Out-of-sample Sharpe ratio and max drawdown

Out-of-sample test window (paper's Table 7):1

Strategy Cumulative return Annualized return Volatility Sharpe Max drawdown
RL policy π* (net) 131.4% 14.3% 17.3% 0.83 −23.5%
Rotation, Top-1 110.4% 12.6% 16.0% 0.79 −21.8%
Rotation, 60/40 86.9% 10.5% 12.8% 0.82 −29.3%
Equal-weight (monthly) 72.5% 9.1% 11.0% 0.83 −24.0%
Buy & hold SPY 118.4% 13.2% 20.5% 0.65 −35.7%

Full sample, rotation strategies only (paper's Table 6): Top-1 had a 0.52 Sharpe and a −28.3% max drawdown, and 60/40 had 0.58 and −29.3%. Buy-and-hold SPY had a 0.46 Sharpe but a −59.6% drawdown. Buy-and-hold SPY still had the highest cumulative return (476.3% vs 407.8% for Top-1).1

Read it with care

How this relates to MCI-style phasing

Paper: 3 volatility states MCI: 8 market-cycle conditions (4H) State 0 · Low vol equities favoured State 1 · Transitional no asset clearly dominates State 2 · High vol equities sharply negative 3MU · Mark Up 4DR/4RR indecision 4RR reaccumulation 4DR distribution 2AR/2RR indecision 2AR accumulation 2RR redistribution 1MD · Mark Down both indecision ranges look alike to a volatility model Rough mapping, our interpretation and not from the paper. Volatility alone cannot tell accumulation from distribution; MCI adds the structural context (what came before the range) that a 3-state HMM leaves out.
Rough mapping between the paper's volatility states and MCI conditions

Same architecture, different lens. Both MCI and this paper use regime gating, which works in two layers: first classify the regime, then switch exposure. The paper switches between ETFs. MCI switches bots on and off in a bot portfolio. The paper is evidence that this separation keeps the decision layer small and interpretable. A 3-row policy table is something you can audit, and the same holds for an MCI condition → bot on/off matrix.

The transitional state is the paper's "indecision" zone. In the transition matrix, calm and crisis only connect through State 1. That echoes MCI's idea of inserting indecision conditions (2AR/2RR after a markdown, 4DR/4RR after a markup) between trending phases instead of flipping straight from up to down.

Where MCI goes further:

Ideas worth stealing for MCI research:

  1. Report persistence. Estimate a transition matrix between MCI conditions (how often 2AR leads to 3MU vs back to 1MD, and average stage duration). It's a compact, shareable way to show that the phases are real and sticky.
  2. Run an HMM as a baseline. Fit a 3-state HMM on 4H returns (for example with hmmlearn; read the look-ahead warning in its deep-dive first) and check how its states overlap with MCI conditions. If MCI adds information beyond volatility, it should separate outcomes inside the HMM's single "transitional" bucket.
  3. Learn the gating table. In the SOE backtester, swap a hand-written "condition → bots on/off" table for a tabular policy learned on training data and tested out-of-sample with a 1-bar lag. It stays interpretable, since it's still one row per condition.
  4. Include costs from day one. Bot start/stop at stage boundaries is where frictions concentrate.

Key terms

Strategy hooks

Buildable ideas a strategy agent can pick up. Each one is a hypothesis to test, not a claim from the paper.

regime switching

Fit a 3-state Gaussian HMM on returns and pause trend bots in the high-volatility state.

Markets
crypto majors, index ETFs
Data
OHLC closes, optional VIX or realized volatility
Gate
run bots only while the filtered (causal) probability of the high-vol state is below a threshold
Test
walk-forward fit, 1-bar execution lag, costs on, compare drawdown and Sharpe against always-on bots
Success
lower max drawdown at similar or better return after costs
4H1Dintermediate
mean reversion

Treat the HMM transitional state as a range regime and enable mean-reversion bots only there.

Markets
crypto majors, FX majors
Data
OHLC
Gate
transitional state is the most likely filtered state for N consecutive bars
Test
compare mean-reversion PnL inside vs outside the transitional state
Success
mean-reversion edge concentrated inside the transitional state
4Hintermediate
ML/AI

Learn a small per-regime allocation table with tabular policy iteration instead of hand-written rules.

Markets
multi-asset ETFs
Data
daily closes for each asset, HMM regime labels
Gate
one row per regime, one action per row
Test
train on the first 70% of history, test on the last 30% with a 1-day lag and costs
Success
beats a monthly equal-weight portfolio on Sharpe out-of-sample
1Dadvanced
tactical allocation

Rotate from equities to gold or treasuries when the crisis regime becomes most likely.

Markets
SPY, GLD, TLT
Data
daily closes, VIX
Gate
crisis state most likely (filtered), with a minimum holding period to limit churn
Test
backtest with costs; count switches per year
Success
drawdown cut versus buy-and-hold with a manageable number of switches
1Dbeginner
Machine-readable YAML
hooks:
  - id: vol-regime-gate-on-bots
    family: regime switching
    idea: Fit a 3-state Gaussian HMM on returns and pause trend bots in the high-volatility state.
    markets: [crypto majors, index ETFs]
    timeframes: [4H, 1D]
    data_needed: [OHLC closes, optional VIX or realized volatility]
    complexity: intermediate
    gate: run bots only while the filtered (causal) probability of the high-vol state is below a threshold
    test: walk-forward fit, 1-bar execution lag, costs on, compare drawdown and Sharpe against always-on bots
    success: lower max drawdown at similar or better return after costs
  - id: transitional-state-as-range-filter
    family: mean reversion
    idea: Treat the HMM transitional state as a range regime and enable mean-reversion bots only there.
    markets: [crypto majors, FX majors]
    timeframes: [4H]
    data_needed: [OHLC]
    complexity: intermediate
    gate: transitional state is the most likely filtered state for N consecutive bars
    test: compare mean-reversion PnL inside vs outside the transitional state
    success: mean-reversion edge concentrated inside the transitional state
  - id: regime-policy-table
    family: ML/AI
    idea: Learn a small per-regime allocation table with tabular policy iteration instead of hand-written rules.
    markets: [multi-asset ETFs]
    timeframes: [1D]
    data_needed: [daily closes for each asset, HMM regime labels]
    complexity: advanced
    gate: one row per regime, one action per row
    test: train on the first 70% of history, test on the last 30% with a 1-day lag and costs
    success: beats a monthly equal-weight portfolio on Sharpe out-of-sample
  - id: crisis-safe-haven-rotation
    family: tactical allocation
    idea: Rotate from equities to gold or treasuries when the crisis regime becomes most likely.
    markets: [SPY, GLD, TLT]
    timeframes: [1D]
    data_needed: [daily closes, VIX]
    complexity: beginner
    gate: crisis state most likely (filtered), with a minimum holding period to limit churn
    test: backtest with costs; count switches per year
    success: drawdown cut versus buy-and-hold with a manageable number of switches

Try it in Trade Holistic

Paste into the Trade Holistic strategy-builder chat
Prompt 1 · Filter
Add a volatility-regime filter to my long strategy on daily SPY: only allow new longs while ATR as a percent of price is below its 100-day average and price is above its 200-day moving average. If ATR percent rises above 1.5 times its average, close the long at the next bar and stay flat until it calms down. Use the previous closed daily bar for every check.
Prompt 2 · Risk
Build a long-only regime rotation test on daily SPY: full size in calm conditions (ATR percent below its 100-day average), half size in transitional conditions (between 1 and 1.5 times the average) and flat in crisis conditions (above 1.5 times). Use a 3 ATR trailing stop, include commission and slippage, and compare it with buy-and-hold on the same dates.
What to look for
Judge it against buy-and-hold on the same dates: the filter earns its place if max drawdown and the worst years (check 2008, 2020 and 2022) shrink clearly while total return gives up less than the drawdown it saves, and it doesn't flip in and out every few days.
Pitfall to avoid
Lookahead and overfitting: the paper's regime labels are fitted on the full history, so only trade on values from closed bars, and don't fine-tune the 1.5x threshold on the same years you judge it on; check that nearby values (1.3x to 1.8x) give similar results.

Repos in this page

GitHub repo

hmmlearn/hmmlearn

Unsupervised Hidden Markov Models in Python with a scikit-learn-style API (BSD-3-Clause, limited maintenance).

Deep-dive ready · Selective fit
GitHub repo

statsmodels/statsmodels

Python statistics library; includes Markov-switching regression and autoregression models for regime analysis.

No deep-dive yet