Python HMM Energy Risk Streamlit Plotly

Energy regime change detector

Personal project, 2026 regime-detector.streamlit.app

Problem

Energy markets operate in two fundamentally different states. In calm regimes, volatility is low and returns are roughly normal. In stress regimes, volatility spikes, distributions develop fat tails, and risk models calibrated on recent history dramatically underestimate exposure.

In February 2022, WTI crude's annualized volatility jumped from roughly 31% to 79% in a matter of days. Any VaR model using the prior six months of data was calculating risk against the wrong distribution. The question is simple: can you detect the regime shift fast enough to adjust your parameters before the losses materialize?

Approach

The detector computes rolling log-return volatility on daily energy futures prices (WTI, Brent, Natural Gas, Gasoline, Heating Oil) fetched from Yahoo Finance. A two-state Gaussian Hidden Markov Model is fit to the volatility series. The HMM learns two distributions (calm and stress), the transition probabilities between them, and the posterior probability of being in each state at every time step.

A separate changepoint detection layer (PELT algorithm) identifies structural breaks where the statistical properties of the volatility series change. The dashboard shows a "stress probability" in real time and fires alerts when it crosses a configurable threshold.

The interface is styled as a financial broadsheet. Regime status reads as a headline, key metrics appear in a typeset stat row, and the charts use a clean editorial palette. The model recalibrates on every page load with current market data.

Architecture

Yahoo Finance Daily OHLCV via yfinance Log returns ln(P_t / P_{t-1}) Rolling volatility std(window) x sqrt(252) 2-state Gaussian HMM Calm vs. stress classification PELT changepoints Structural break detection Streamlit dashboard Newspaper-styled regime monitor

The math

Log returns: \( \ln(P_t / P_{t-1}) \). Rolling volatility: standard deviation of log returns over a configurable window, annualized by multiplying by \( \sqrt{252} \) (trading days per year). The HMM treats the volatility series as emissions from a latent two-state Markov chain. It learns the mean (\( \mu \)) and variance (\( \sigma^2 \)) of each state, the transition matrix (\( A \)), and computes the posterior probability of stress at every time step via the forward-backward algorithm.

Tech stack

Python Streamlit Plotly yfinance hmmlearn ruptures pandas NumPy

Status

Live and deployed. Source on GitHub.

← Previous project All projects →