Kalman Filter
Install and import#
npm install fintech-algorithmsimport { runFilter } from "fintech-algorithms/statistical-time-series/state-and-regime-models/kalman-filter";Signature#
runFilter(observations, config)Optimal recursive estimation of a hidden state from noisy observations in a linear Gaussian system. In markets the hidden state is often the thing you actually want — a fair value, a slowly moving beta — and the observation is a noisy proxy for it.
Parameters#
| Name | Type | Notes |
|---|---|---|
observations | number[] | Noisy observations in chronological order. |
config | { a: number; h: number; q: number; r: number; initial_mean: number; initial_variance: number } | a is the state transition and h the observation mapping. q and r are the process and observation noise variances — their **ratio** is what determines how quickly the filter trusts new data, so scaling both changes nothing. |
Returns#
{ index, predicted_mean, predicted_variance, innovation, kalman_gain, filtered_mean, filtered_variance }[]
Every intermediate per step, including the Kalman gain and the innovation. A filter that behaves oddly is diagnosed from the gain path, not from the output.
Errors#
- When r is not positive, or q or the initial variance is negative — throws
Complexity: time O(n),
space O(n).
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.1740371542, 0.7180296431, 0.0364260071]{
"a": 0.96,
"h": 1,
"q": 0.08,
"r": 0.64,
"initial_mean": 0,
"initial_variance": 2
}Call#
runFilter(observations, config)Returns#
object with 1 field: 2
{
"2": {
"index": 2,
"predicted_mean": 0.376086443860437,
"predicted_variance": 0.3451182399024169,
"predicted_observation": 0.376086443860437,
"innovation": -0.339660436760437,
"innovation_variance": 0.985118239902417,
"kalman_gain": 0.350331793609469,
"filtered_mean": 0.25709259383197747,
"filtered_variance": 0.22421234791006017
}
}Diagrams#
Calculation flow#
Kalman Filter 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 New Approach to Linear Filtering and Prediction Problems — R. E. Kalman
- An Introduction to the Kalman Filter — Greg Welch and Gary Bishop
- Bayesian Filtering and Smoothing — Simo Särkkä and Lennart Svensson
- Time Series Analysis by State Space Methods — statsmodels developers