Regime-Shift Market Detection using Hidden Markov Models
This project implements a quantitative trading framework using Hidden Markov Models (HMMs) to detect hidden market regimes and dynamically allocate portfolio exposure based on changing market conditions.
The system uses macro and asset-based indicators such as SPY returns, volatility, VIX changes, Gold (GLD), and Treasury Bonds (TLT) to identify latent market states and evaluate strategy performance against benchmark portfolios.
The notebook includes:
- Hidden Markov Model regime detection
- Walk-forward validation
- Dynamic allocation strategy
- Benchmark backtesting
- Equity curve visualization
- Performance tear sheet analytics
1. Hidden Markov Model (HMM)
A Gaussian Hidden Markov Model was selected because financial markets exhibit hidden latent states that cannot be directly observed.
HMMs are well-suited for:
- Regime detection
- Sequential time-series modeling
- Probabilistic state transitions
- Financial market state inference
The model identifies hidden regimes such as:
- Bull Market
- Bear Market
- High Volatility / Crisis Regimes
The transition probability matrix (model.transmat_) is analyzed to understand:
- Regime persistence
- Transition likelihoods
- Market state dynamics
The following features were selected to capture market structure and macro behavior:
| Feature | Purpose |
|---|---|
| SPY Returns | Market direction |
| Rolling Volatility | Risk regime detection |
| VIX Change | Fear and uncertainty indicator |
| GLD Returns | Flight-to-safety behavior |
| TLT Returns | Bond market reaction |
Rolling volatility uses a 20-day rolling window.
RobustScaler was used instead of StandardScaler because financial data contains:
- Outliers
- Fat tails
- Extreme volatility spikes
Robust scaling improves model stability during crisis periods.
Portfolio exposure changes depending on detected regimes.
| Regime | Allocation Logic |
|---|---|
| Bull | Higher SPY exposure |
| Bear | Defensive positioning |
| Crisis / Neutral | Increased bond and gold allocation |
This improves:
- Risk-adjusted returns
- Drawdown protection
- Portfolio stability
To reduce overfitting and improve robustness, the project implements walk-forward validation using rolling training and testing windows.
Workflow:
- Train HMM on rolling historical windows
- Predict unseen future regimes
- Refit periodically
- Aggregate out-of-sample predictions
This improves:
- Generalization
- Robustness
- Realistic evaluation
The strategy is evaluated against:
- Buy & Hold SPY
- Traditional 60/40 Portfolio
Performance metrics include:
- CAGR
- Volatility
- Sharpe Ratio
- Sortino Ratio
- Maximum Drawdown
- Calmar Ratio
- Win Rate
- Profit Factor
- Alpha
- Beta
- Information Ratio
- Portfolio Turnover
regime-shift/
│
├── notebook/
│ └── regime-strategy.ipynb
│
├── data/
├── README.md
└── requirements.txt
git clone https://github.com/your-username/regime-shift.git
cd regime-shiftpip install -r requirements.txtjupyter notebooknotebook/regime-strategy.ipynb
Run all notebook cells sequentially.
Verify financial data downloads correctly:
data.head()- SPY
- GLD
- TLT
- ^VIX columns
Check feature creation:
features.head()- SPY_returns
- SPY_volatility
- VIX_change
- GLD_returns
- TLT_returns
Run model training:
model.fit(X_scaled)- No convergence errors
- Hidden states generated successfully
Check regime assignments:
regime_data[["Regime"]].head()- Integer regime labels
- Multiple regime states detected
Verify rolling out-of-sample regime predictions:
walk_forward_df.head()- Predicted regime labels
- Rolling out-of-sample predictions
- Multiple validation windows
Verify strategy outputs:
portfolio_returns.head()- Non-empty return series
- Dynamic allocation changes
Run evaluation metrics:
comparison- CAGR
- Volatility
- Sharpe Ratio
- Sortino Ratio
- Max Drawdown
- Calmar Ratio
- Turnover
- Alpha/Beta
- Information Ratio
Recommended:
- Python 3.10+
- Jupyter Notebook
The HMM model uses:
random_state = 42to ensure reproducibility.
Market data is downloaded using:
yfinance- SPY
- GLD
- TLT
- ^VIX
- 2015 – Present
To reproduce results:
- Install exact dependencies
- Use same notebook execution order
- Keep identical random seed
- Use same date range
- Execute all cells sequentially
The strategy achieved:
- Higher Sharpe Ratio than Buy & Hold SPY
- Lower volatility
- Lower maximum drawdown
- Better downside protection
- Improved risk-adjusted returns
| Metric | Regime Strategy | SPY |
|---|---|---|
| Sharpe Ratio | Higher | Lower |
| Volatility | Lower | Higher |
| Max Drawdown | Lower | Higher |
Potential upgrades:
- Regime probability weighting
- Transaction cost modeling
- Multi-asset optimization
- Deep learning regime models
- Macro-economic indicators
- Reinforcement learning allocation systems
- Python
- pandas
- numpy
- matplotlib
- scikit-learn
- hmmlearn
- yfinance
This project is for educational and research purposes only and should not be considered financial advice.