State-Space Models for Trading

Market data is an imperfect measurement of an evolving economic state. A quoted price contains a latent efficient price, bid-ask bounce, asynchronous trading, and occasional bad prints. A factor return mixes persistent premium, temporary flow, and sampling noise. State-space models make that distinction explicit: a hidden state evolves through time and observations reveal it noisily.

This is more than smoothing. The model supplies a likelihood, uncertainty estimates, missing-observation handling, and a disciplined route from a forecast to a position size. The Kalman filter is the linear-Gaussian workhorse, but the modeling choices around it determine whether it is useful in trading.

The two equations

In the basic discrete model, a latent vector xt follows a transition equation and the observed vector yt follows a measurement equation:

x_t = A_t x_(t-1) + B_t u_t + w_t,    w_t ~ N(0, Q_t)
y_t = H_t x_t + v_t,                  v_t ~ N(0, R_t)

A controls persistence, Q is state innovation variance, H maps states to observations, and R is measurement noise. A local linear trend for log price can use state [level, slope]; a dynamic hedge ratio can use [alpha, beta]; a multivariate model can treat factor exposures as states.

Trading questionHidden stateObservationUseful output
Is a move informational?efficient log pricetrades or midquotesfiltered return
Is a spread reverting?intercept and hedge ratiotwo asset pricesresidual z-score
Has a factor changed?time-varying betaasset and factor returnsexposure forecast
Is volatility elevated?latent variancesquared returnsrisk scale

The filtered estimate uses observations through time t; the smoothed estimate uses future data too. Only the filter may drive a historical live-trading backtest. Using a smoother to generate signals is a subtle, common form of look-ahead bias.

Kalman recursion and uncertainty

Given prior mean m^-t and covariance P^-t, prediction and update are:

m^-_t = A_t m_(t-1)
P^-_t = A_t P_(t-1) A_t' + Q_t
K_t = P^-_t H_t' (H_t P^-_t H_t' + R_t)^-1
m_t = m^-_t + K_t (y_t - H_t m^-_t)

The innovation yt - Ht m^-_t is as important as the state. Standardized innovations should be approximately uncorrelated and unit variance if the model is adequate. Clusters of large innovations flag a volatility shift, stale measurement variance, a corporate action, or a broken feed.

Avoid explicitly inverting the innovation covariance in production. Cholesky solves are more stable, and the Joseph covariance update preserves positive semidefiniteness. At intraday frequency, numerical hygiene matters more than an elegant symbolic formula.

A dynamic pairs model in Python

For two related log prices, let yt = alphat + betat xt + noise, with a random walk for [alpha, beta]. The following sketch highlights the clock discipline:

import numpy as np

state = np.array([0.0, 1.0])
P = np.diag([1.0, 0.1])
Q = np.diag([1e-6, 1e-5])       # beta turnover prior
R = 2e-4                        # residual measurement variance

for x, y in synchronized_log_prices:
    P = P + Q                   # predict: random-walk state
    H = np.array([[1.0, x]])
    innovation = y - H @ state
    S = H @ P @ H.T + R
    K = (P @ H.T / S).ravel()
    state = state + K * innovation.item()
    P = (np.eye(2) - np.outer(K, H.ravel())) @ P
    z = innovation.item() / np.sqrt(S.item())

The z score is not a trade by itself. Require synchronized, tradable prices; account for hedge-ratio estimation turnover; and use a rolling or filtered volatility estimate. A beta that adapts quickly reduces residual variance but can convert a genuine convergence trade into parameter churn.

Estimation is the real model

Maximum likelihood estimates Q, R, and transition parameters by running the filter and summing innovation log likelihoods. Expect weak identification: increasing both Q and R can make similar in-sample fits while implying very different responsiveness. Put economically motivated bounds on half-lives and update rates, validate in chronological folds, and inspect parameter stability.

SymptomLikely causeResponse
State tracks every tickQ too large or R too smallincrease measurement noise
State never adaptsQ too smallpermit faster transitions
Innovation autocorrelationomitted dynamicsadd slope, seasonality, or lags
Fat innovation tailsGaussian misspecificationrobust filter or jump flag

For returns, conditional heteroskedasticity makes constant R unrealistic. Couple the measurement variance to a volatility forecast, or use a stochastic-volatility state. GARCH volatility modeling is often a defensible variance layer when a full nonlinear filter is unnecessary.

From state estimate to trading decision

The posterior covariance prevents false precision. For a forecasted excess return mu with predictive variance sigma2, a constrained position might scale with mu / sigma2, clipped for leverage and liquidity. Widen entry bands when posterior uncertainty is high; a residual of two standard deviations means less when beta is poorly identified.

Backtest with as-of data, realistic rebalance timing, and transaction costs. Re-estimating hyperparameters on the entire sample leaks future regimes even if each filtering update is chronological. Treat model diagnostics, forecast calibration, and trading P&L as separate reports.

Key takeaways

  • State-space models distinguish a changing latent process from noisy market observations.
  • Use filtered, never smoothed, states for executable historical signals.
  • Q and R govern responsiveness and are economically consequential, not cosmetic settings.
  • Size trades with posterior uncertainty and validate innovations as well as P&L.
#state space models #kalman filter #quantitative trading #time series