Hidden Markov Model
Install and import#
npm install fintech-algorithmsimport { runFilter } from "fintech-algorithms/statistical-time-series/state-and-regime-models/hidden-markov-model";Signature#
runFilter(observations, config)Infers a discrete hidden regime from observations. Where the Kalman filter tracks a continuous state, this asks which of a small number of *regimes* the market is in — and returns a probability rather than a label.
Parameters#
| Name | Type | Notes |
|---|---|---|
observations | number[] | Observations in chronological order. |
config | { transition: number[][]; means: number[]; stds: number[]; initial: number[] } | transition holds the regime switching probabilities, each row summing to 1. means and stds are the emission parameters per regime. Regime **order is arbitrary** — label switching means 'regime 0' has no intrinsic meaning across fits. |
Returns#
{ …per-step filtered probabilities }[]
Filtered regime probabilities per observation. Probabilities, not a hard classification: a 55/45 split is a genuinely uncertain moment and rounding it to a label discards that.
Errors#
- When a transition row does not sum to 1, or a standard deviation is not positive — throws
Complexity: time O(n × states²),
space O(n × states).
Worked example#
verified This is the worked example published in the article, replayed by the test suite on every run. The output cannot drift.
Input#
[-0.9183368993, -0.5364890278, -0.550167602]{
"transition": [
[0.94, 0.06],
[0.12, 0.88]
],
"means": [-0.15, 0.25],
"stds": [0.55, 1.45],
"initial": [0.8, 0.2]
}Call#
runFilter(observations, config)Returns#
object with 1 field: 2
{
"2": {
"index": 2,
"predicted_state_0": 0.8612154040743613,
"predicted_state_1": 0.13878459592563866,
"posterior_state_0": 0.9359801579550974,
"posterior_state_1": 0.0640198420449025,
"most_likely_state": 0,
"log_predictive_density": -0.6690356366768324
}
}Diagrams#
Calculation flow#
Hidden Markov Model Causal Update Flow
flowchart LR
A["Filtered state at t-1"] --> B["Predict state at t"]
B --> C["Read observation available at t"]
C --> D["Compute evidence or innovation"]
D --> E["Normalize or gain-weight update"]
E --> F["Filtered state at t"]
F --> G["Publish diagnostics"]
F --> A
How it works#
This page states the contract — how to call it correctly. The article explains the concept: why it works, and where it breaks.
References#
- A Tutorial on Hidden Markov Models and Selected Applications in Speech Recognition — Lawrence R. Rabiner
- Strictly Proper Scoring Rules, Prediction, and Estimation — Tilmann Gneiting and Adrian E. Raftery