Hidden Markov Regime Model
A moving-average crossover or a fixed volatility cutoff labels a regime using one rule an author picked in advance, and that rule is wrong exactly as often as the pick was. A hidden Markov model asks the data directly: given the observed returns, what mean, standard deviation and transition probabilities for three latent states best explain what was actually seen, and which single sequence of states was most likely to have produced it. Training is Baum-Welch expectation-maximisation, implemented with the scaled forward-backward algorithm from Rabiner's 1989 tutorial. Raw (unscaled) forward probabilities underflow silently to zero within a few hundred observations - the recursion keeps multiplying numbers below one, and nothing raises an error when the result reaches the smallest representable double, it just quietly becomes an unusable log(0). Scaling each time step by its own normaliser and summing -log(scale) at the end recovers the exact log-likelihood without that failure mode, however long the observation window is. Decoding uses the Viterbi algorithm in log-space, which finds the single most likely state path for the whole sequence rather than the state that looks most likely bar by bar in isolation - the two are not the same thing, and the whole-path version is what avoids a decoded sequence that flickers between states on noise. States are unlabelled by construction: Baum-Welch has no notion of "bull" before it has seen data, it only finds three internally consistent Gaussian clusters and a transition structure between them. HmmLabelStates orders the three fitted states by mean return - highest becomes HMM_REGIME_BULL, lowest becomes HMM_REGIME_BEAR, the remaining state becomes HMM_REGIME_CHOP - and HmmClassifyState looks up that mapping, so the regime label always reflects what the current fit actually learned rather than an assumption baked in before training ran. The state count is fixed at three (the HMM_STATES constant), not left general. MQL4 only allows the leftmost dimension of a 2D array to be dynamic, so every forward/backward/Viterbi lattice in this library is declared with a fixed HMM_STATES second dimension - a variable state count would need a ragged-array workaround for no real benefit, since three regimes is the entire point of a bull/bear/chop classifier. Notes and limitations - Baum-Welch is a local optimiser: it converges to A local maximum of the likelihood, not provably the global one. A poor initial guess can land on a degenerate fit (e.g. two states with nearly identical means). The demo's initial means/stdevs spread the three states apart on purpose; do the same in your own code rather than initialising all three states identically. - Three states means three regimes, always - this is a bull/chop/bear classifier, not a general N-state HMM. If you need more states, the HMM_STATES constant and every fixed-size array in the file must be changed together and recompiled. - Training cost is O(count) per Baum-Welch iteration with a fixed constant from the three states, so a few hundred bars trains in well under a second; a few thousand is still practical but not instant on every tick. Retrain on a timer or on new bar, not inside a tight OnTick loop. - This library assigns regime labels only. It places no trades, sizes no positions and issues no buy/sell signal on its own - treat the decoded regime as one input to a wider decision process.
Script · MT5 · v1.0 · Free
About Hidden Markov Regime Model
Hidden Markov Regime Model is a script for MetaTrader 5. It has 3 settings, such as Segment length, Train iterations and Live price bars. MQL source code included.
Files in the download: HiddenMarkovRegime.mq5.mqh, HiddenMarkovRegime.txt, HiddenMarkovRegimeDemo.ex5, HiddenMarkovRegimeDemo.mq5.
Settings
| Setting | Default | What it does |
|---|---|---|
| Segment length | 150 | Bars per synthetic regime segment (bull/chop/bear/bull...) |
| Train iterations | 60 | Max Baum-Welch iterations |
| Live price bars | 400 | Bars of live returns to decode in the final test |
How to install
- Download the ZIP from your PolyMaria library and unzip it.
- In MetaTrader 5 open File → Open Data Folder, then go to MQL5 → Scripts.
- Copy the .mq5 file(s) there. Put any .mqh files in MQL5 → Include.
- Open the .mq5 file in MetaEditor and press Compile (F7) if MetaTrader does not show it.
- Drag the script onto a chart to run it once.
Tags: MT5 Script · MQL5 Source Code