Why a static OLS beta falls short: estimating a time-varying hedge ratio with a state-space model and building a cointegration strategy.
The state-space model#
We model the hedge ratio as a latent state:
where is observation noise and is state noise.
Python implementation#
import numpy as np
def sharpe(r, rf=0.0, ann=252):
ex = r - rf
return np.sqrt(ann) * ex.mean() / ex.std()
# Kalman-filtered dynamic hedge ratio
for t in range(1, n):
P_p = P[t-1] + Q
K = P_p * x[t] / (x[t]**2 * P_p + R)
b[t] = b[t-1] + K * (y[t] - x[t]*b[t-1])
P[t] = (1 - K * x[t]) * P_p
Full article in progress — backtest results and parameter selection to follow.