Skip to content
All library documents

Adaptive Kalman Filter Tuning for Cointegrated Mean-Reversion Portfolios

Article Quant Q&A · Author: Amanda G.

Summary

The document examines whether a random-walk state transition is suitable when a Kalman filter estimates dynamic weights for a cointegrated portfolio. It proposes a diagonal transition matrix in which the component associated with the stationary portfolio follows a coefficient below one, while the remaining components retain unit transitions. It also gives an estimate for that coefficient and describes adaptive tuning of the filter’s state and noise parameters.

The accepted response details initialization choices for the state vector, measurement noise, process noise, and state covariance, along with prediction equations. Reported evidence includes unit-root test p-values for several transition settings and the author’s account of improved stationarity and backtest behavior after repeated tuning. These are examples from a traded ETF triplet, not a controlled or broadly validated result; tuning to stationarity or historical performance can overfit, and implementation assumptions should be independently checked.

Key ideas

  • The proposed transition matrix lets one state component mean-revert while other components follow unit transitions.
  • The document estimates the mean-reversion coefficient from consecutive state observations.
  • Adaptive tuning updates noise covariances and initialization quantities across repeated filter passes.
  • The response provides separate initialization and prediction procedures for state and covariance estimates.
  • Reported stationarity and backtest improvements come from one ETF portfolio example and do not establish general performance.

Tags

Full text
# Does Chan use the wrong state transition model in his Kalman filter code?


# Does Chan use the wrong state transition model in his Kalman filter code?












In his book, Algorithmic Trading: Winning Strategies and Their Rationale, Ernie Chan shows how to use a Kalman filter to improve the returns of a cointegrated portfolio. Recall that the state equation is: $$\beta_t=\alpha\cdot\beta_{t-1}+\omega_{t-1}$$ Here, $\alpha$ is the state transition matrix, $\beta_t$ is the state vector, and $\omega_t$ is the process noise vector.

In his Kalman filter code, Chan sets the state transition matrix, $\alpha$, to the identity matrix. However, I would argue that this is wrong. Recall that the state vector is used in the measurement equation: $$y_t=\beta_t\cdot x_t + \epsilon_t$$

For k cointegrating time series, the observation vector, $x_t$, the state vector, $\beta_t$, and the observable, $y_t$, are: $$x_t=(1,\;x_{2,t},\;x_{3,t},\;...\;,\;x_{k,t})$$ $$\beta_t=(\beta_{1,t},\;\beta_{2,t},\;\beta_{3,t},\;...\;,\;\beta_{k,t})$$ $$y_t = x_{1,t}$$

The state vector is related to the static weights ($w_1,w_2,...,w_k$) obtained from the Johansen procedure because these weights give a stationary time series, $y_{\text{port}}$: $$y_{\text{port}}=w_1\cdot x_1\:+\:w_2\cdot x_2\:+\:w_3\cdot x_3\:+\:...\:+\:w_k\cdot x_k$$ Solving for $y=x_1$, we get: $$x_1=(y_{\text{port}}\:-\:w_2\cdot x_2\:-\:w_3\cdot x_3\:-\:...\:-\:w_k\cdot x_k)\,/\,w_1$$ Therefore, from the measurement equation, the initial state vector at time $t$ must be: $$\beta_t=(y_{\text{port},t}/w_1,\;-w_2/w_1,\;-w_3/w_1,\;...\;,\;-w_k/w_1)$$ The first column of matrix $\beta$ is $y_{\text{port}}/w_1$, which is stationary because $y_{\text{port}}$ is stationary. Therefore, the state estimate for this component of $\beta$ at time $t$ is: $$\beta_{1,t}=\alpha_{11}\cdot\beta_{1,t-1}$$ where $\alpha_{11}$ must be less than 1 for the stationary case. This analysis indicates that the correct state transition matrix is not the identity matrix, but rather: $$\alpha=\left[ \begin{array}{cccc} \alpha_{11} & 0 & 0 & ... & 0\\ 0 & 1 & 0 & ... & 0\\ 0 & 0 & 1 & ... & 0\\ \vdots & \vdots & \vdots & \ddots & \vdots\\ 0 & 0 & 0 & ... & 1 \end{array} \right]$$ In other words, the state transition matrix is the identity matrix, except for the (1,1) element, which must be less than 1 (for stationarity).

How do we calculate $\alpha_{11}$? Right-multiply both sides of the state equation by $\beta_{t-1}^T$, take the expectation value, and solve for $\alpha_{11}$:

$$\alpha_{11}=\frac{\sum_{t=2}^n\beta_{1,t}\cdot\beta_{1,t-1}^T}{\sum_{t=2}^n \beta_{1,t-1}\cdot\beta_{1,t-1}^T}$$

I’m currently trading with a cointegrated triplet of ETFs that give a stationary portfolio, $y_{\text{port}}$. When I apply a unit root test (which measures stationarity) to $y_{\text{port}}$, I get the following p-values using a state transition matrix in the Kalman filter with different values for the (1,1) element of the state transition matrix, $\alpha$:

\begin{array}{|c|c|} \hline \alpha_{11} & p\\ \hline 1 & 0.00086\\ \hline 0.93 & 0.00058\\ \hline 0.007 & 3\times10^{-13}\\ \hline \end{array}

Smaller values of p suggest greater likelihood of stationarity. All of these p-values indicate stationarity, but the modified transition matrix ($\alpha_{11}=0.93$) gives better results than the identity matrix ($\alpha_{11}=1$). In the last example ($\alpha_{11}=0.007$), I iterated the Kalman filter calculation 1000 times, each time recalculating $\alpha_{11}$, as well as the process noise covariance matrix, the observation noise variance, the initial state vector, and the initial state covariance matrix, with each iteration (a procedure known as "adaptive tuning" of the Kalman filter). This gave very high stationarity for the $y_{\text{port}}$ array. (This is also reflected in higher returns in backtesting of the trading algorithm.)

I haven't seen this analysis in the literature on Kalman filter in financial time series. Can anyone find fault with it?

## Answer by Amanda G. (score 12, accepted)

https://quant.stackexchange.com/a/41257

In addition to getting the right transition model for the Kalman filter, the main obstacle to optimizing filter performance is to implement an optimal initialization. I use an iterative approach to initialize or "tune" the Kalman filter, known as adaptive tuning. I do this because I've found alternative methods of initializing the Kalman filter (such as the autocovariance least squares method mentioned by Chan) to give mediocre results. In my experience, adaptive tuning can produce a highly stationary portfolio suitable for mean-reversion trading.

There are four quantities that have to be initialized:

- The initial state vector, $\beta(0)$

- The $k\times k$ initial state covariance matrix, $\text{cov}(\beta(0))$

- The measurement noise variance, $\nu_e$

- the $k\times k$ state noise covariance matrix, $\nu_\omega$

Furthermore, one has to make a reasonable initial choice for these quantities on the first pass through the filter. Subsequent passes through the filter may use a different calculation (for reasons that I hope will become clear).

## Noise (Co)variance Initialization

For the initial value of the measurement noise variance, $\nu_e(0)$, I use the variance of the first component of $\beta_1$ (the other components are constant):

$$\nu_e(0)=\text{var}(\beta_{1,1})=\text{var}(y_\text{port}/w_1)$$

However, any reasonable initial value will probably work, if you're using the adaptive tuning approach.

For subsequent passes through the Kalman filter, I solve the measurement equation for the measurement noise, $\epsilon_t$, and take the expectation value of its square to get the measurement noise variance, $\nu_e$:

$$\epsilon_t=y_t-\beta_t\cdot x_t$$ $$\nu_e=E\left[\epsilon_t \cdot \epsilon_t^T\right]=\frac{\sum_{t=1}^{n}\epsilon_t\cdot\epsilon_t^T}{n}$$

For the initial value of the state noise covariance, I first calculate the state transition matrix, $\alpha$, using the formula shown in my original post, to calculate $\alpha_{1,1}$. Then I post-multiply the state equation by its transpose (outer product), and take expectations:

$$E\left[\beta_t\otimes\beta_t^T\right]=E\left[(\alpha\cdot\beta_{t-1}+\omega_{t-1})\otimes(\alpha\cdot\beta_{t-1}+\omega_{t-1})^T\right]$$

This can be solved for the initial state noise covariance matrix, $\nu_\omega(0)$:

$$\nu_\omega(0)=E\left[\omega_t\otimes\omega_t^T\right]=\Gamma-\alpha\cdot\Gamma\cdot\alpha^T$$

where $\Gamma$ is:

$$\Gamma=\frac{\sum_{t=1}^n\beta_t\otimes\beta_t^T}{n}$$

$\nu_\omega(0)$ should be diagonalized (off-diagonal elements set to zero). Then only the (1,1) component of $\nu_\omega(0)$ will be non-zero.

For subsequent passes of the Kalman filter, I solve the state equation for the process noise vector, $\omega_t$, and take the expectation of the outer product of the process noise vector with itself to get the state noise covariance matrix, $\nu_\omega$:

$$\omega_t=\beta_{t+1}-\alpha\cdot\beta_t$$ $$\nu_\omega=E\left[\omega_t\otimes\omega_t^T\right]=\frac{\sum_{t=1}^{n-1}(\beta_{t+1}-\alpha\cdot\beta_t)\otimes(\beta_{t+1}-\alpha\cdot\beta_t)^T}{n-1}$$

However, I'm not quite done. $\beta_1$ is stationary, so I have to replace the (1,1) component of $\nu_\omega$ with the stationary solution that I used in my original post:

$$\nu_{\omega,1,1}=(1-\alpha_{1,1}^2)\Gamma_{1,1}$$

Finally, $\nu_\omega$ should be diagonalized.

## State and State Covariance Initialization

To get the initial state, start with the initial state vector I calculated in my original post:

$$\beta_t=(y_{\text{port},t}/w_1,\;-w_2/w_1,\;-w_3/w_1,\;...\;,\;-w_k/w_1)$$

The $\beta_{t,1}$ component is stationary, and so the expectation value of this component is zero. (See the derivation in Kalman Filter Initialization - The Stationary Case.) Therefore, the initial state vector, $\beta(0)$, is:

$$\beta(0)=(0,\;-w_2/w_1,\;-w_3/w_1,\;...\;,\;-w_k/w_1)$$

This initialization for $\beta_1$ should be used at the start of each iteration of the Kalman filter.

The state covariance initialization is much trickier. For the first pass through the Kalman filter, I calculate the initial state covariance matrix, $\text{cov}(\beta(0))$, using the Inverse of Information Matrix calculation of Gemson (eq. 3.4, section 3.8.2):

$$\text{cov}(\beta(0))=\nu_e\left[\frac{\sum_{t=1}^n(\alpha^T\cdot x_t^T)\otimes(x_t\cdot\alpha)}{n}\right]^{-1}$$

However, any reasonable $k\times k$ matrix will probably work, provided that it is diagonalized, and all diagonal elements are $>0$. (Any zero diagonal element will cause the corresponding Kalman filter gain element to be zero, preventing the state and state covariance updates from updating.)

For subsequent passes of the Kalman filter, we can calculate the initial state covariance, $\text{cov}(\beta(0))$, from the state matrix, $\beta$, using the traditional definition of covariance$^*$:

$$\text{cov}(\beta(0))=E\left[(\beta-E[\beta])(\beta-E[\beta])\right]=\frac{\sum_{t=1}^n(\beta_t-\beta_m)\otimes(\beta_t-\beta_m)^T}{n-1}$$ $$\beta_m=(\text{mean}(\beta_1),\;\text{mean}(\beta_2),\;...\;,\;\text{mean}(\beta_k))$$

$^*$Edit 8/18/18: $n$ in denominator of $\text{cov}\beta(0)$ changed to $n-1$ for unbiased covariance calculation.

This works well, but what I've found is that I can get a more stationary portfolio (and so, a higher average-yearly-return/maximum-drawdown ratio in my backtesting), $y_\text{port}$, by using a different expression for $\beta_m$ in my $\text{cov}(\beta(0))$ calculation:

$$\beta_m=\left(\text{mean}(y_{\text{port},t}/w_1),\;-w_2/w_1,\;-w_3/w_1,\;...\;,\;-w_k/w_1\right)$$

In other words, for the expectation value of $E(\beta)$, I use the mean of the initial state vector, $\beta_t$, that I calculated in my original post. Why does this seem to work better? I think it's because the initial state vector is calculated from the Johansen weights, which is the optimal cointegration weighting (for static weights), and so is the "true" expectation value. In any case, I go with what works best. Use your own judgement in this.

## Implementation Notes

If you use the state transition matrix, $\alpha$, derived in my opening post, you need to use the correct state prediction and state covariance prediction equations in your Kalman filter. The state prediction equation should be: $$\beta_t=\alpha\cdot\beta_{t-1}$$ and the state covariance prediction equation should be: $$\text{cov}(\beta_t)=\alpha\cdot \text{cov}(\beta_{t-1})\cdot \alpha^T\;+\;\nu_\omega$$ where $\nu_\omega$ is the $k \times k$ state noise covariance matrix.

Also, all of the $k\times k$ matrices, $\alpha$, $\text{cov}(\beta(0))$, $\nu_\omega$, $\Gamma$, should be diagonalized -- all off-diagonal elements set to zero.

Currently, I'm using about 2000 iterations of the Kalman filter for my triplet ETF portfolio to settle into fixed values for all of the quantities. This takes about 1 minute, but I only do this once a week, and use the dynamic weights I've obtained from this procedure for trading during the week. The advantage is that I'm obtaining a highly stationary portfolio, $y_{\text{port}}$.

To show effect of the Kalman filter, here is the weighted portfolio using the static Johansen weights (prior to the Kalman filter):

Here is the same portfolio, except using the dynamic portfolio weights from the Kalman filter:

That's much more stationary!

I will continue to check in at least once a day, for a while, and try to answer any questions that may come up. I appreciate any feedback.

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.