9
$\begingroup$

I am trying to calibrate a one-factor mean-reverting process in python 3. The process is defined as:

\begin{equation} dX = k(\alpha - X)dt + \sigma dW , \end{equation}

where $\alpha = \mu - \frac{\sigma^2}{2k}$ is the long-run mean log price and $k$ is the speed of adjustment. Under the risk neutral probability $Q$ we write the previous equation as

\begin{equation} dX = k(\alpha^* - X)dt + \sigma dW^*. \end{equation}

Here $\alpha^*= \alpha - \lambda$, where $\lambda$ is the market price of risk. Based on Girsanov's Theorem $dW^*$ is a Brownian Motion under the martingale measure $Q$.

My measurement and transition equations are:

  • The measurement equation relates the time series of observable variables, in my case futures prices for different maturities, to the unobservable state variable, the spot price:

\begin{equation} y_{t} = Z_{t}X_{t} + d_{t} + \epsilon_{t}, \qquad t = 1, ..., NT \end{equation}

where

$y_{t}=\left[\ln F\left(T_{i}\right)\right]$, $i=1,...,N$, $N\times 1$ vector of observables,

$d_{t}=\left[\left(1-e^{-\kappa T_{1}}\right) \alpha^{*}+\frac{\sigma^{2}}{4 \kappa}\left(1-e^{-2 k T_{1}}\right)\right], \quad i=1, \ldots, N, \quad N \times 1$ vector,

$Z_{t}=\left[e^{-\kappa T_{i}}\right], \quad i=1, \ldots, N, \quad N \times 1$ vector,

$\epsilon_{t}, \quad N\times 1$ vector of serially uncorrelated disturbances with $\mathbb{E}(\epsilon_{t}) = 0$ and $Var(\epsilon_{t}) = H$.

  • The transition equation is a discrete-time version of the O-U oil price stochastic process:

\begin{equation} X_{t}=c_{t}+Q_{t} X_{t-1}+\eta_{t}, \quad t=1, \ldots, N T \label{eq:38}, \end{equation}

where

$c_{t}=\kappa \alpha \Delta t$

$Q_{t}=1-\kappa \Delta t$

$\eta_{t}$, serially uncorrelated disturbances with $\mathbb{E}(\eta_{t}) = 0$ and $Var(\eta_{t}) = \sigma^2 \Delta t$.

The aim is to calibrate the model parameters using the time series of different maturities Futures prices via MLE. Any help with the coding part (in python 3) would be much appreciated!

$\endgroup$
  • $\begingroup$ What do you have so far? $\endgroup$ – amdopt Jul 15 at 15:32
  • $\begingroup$ Maths is done, but don't really know where to start with the code. $\endgroup$ – gte Jul 15 at 16:43
4
$\begingroup$

Expanding on the answer by @ir7, here is some pykalman code/psuedocode to help get you started. This can be adjusted in many ways but I have left in some parameters to give you an idea. I left a documentation link at the bottom as well. The functions will setup Kalman Filters that are applied to your data and subsequently that data is fed to a regression that is subsequently called in a backtest function:

import pandas as pd
import numpy as np
from pykalman import KalmanFilter

def your_function_name(x):
    your_filter_name = KalmanFilter(transition_matrices = [1],
                                    observation_matrices = [1],
                                    observation_covariance=1,
                                    transition_covariance=.01,
                                    initial_state_mean = 0,
                                    initial_state_covariance = 1)

    state_means, _ = kf.filter(x.values)
    state_means = pd.Series(state_means.flatten(), index=x.index)
    return state_means


def your_regression_filter(x, y):
    delta = 1e-3
    trans_cov = delta / (1 - delta) * np.eye(2)  #random walk wiggle
    obs_mat = np.expand_dims(np.vstack([[x], [np.ones(len(x))]]).T, axis=1)
    kf = KalmanFilter(n_dim_obs=1,
                      n_dim_state=2,
                      initial_state_mean=[0,0],
                      initial_state_covariance=np.ones((2, 2)),
                      transition_matrices=np.eye(2),
                      observation_matrices=obs_mat,
                      observation_covariance=2,
                      transition_covariance=trans_cov)

    # Use the observations y to get running estimates and errors for the state parameters
    state_means, state_covs = kf.filter(y.values)
    return state_means

With these 2 functions your would define a backtest function in which you would pull state_means by calling:

state_means = your_regression_filter(your_function_name(x), your_function_name(y))

How you use state_means from here depends on you.

For more info: pykalman documentation

| improve this answer | |
$\endgroup$
  • $\begingroup$ That is great amdopt, thank you very much! One last question is, is there a criterion to set my starting parameters (i.e. the ones I need to calibrate)? $\endgroup$ – gte Jul 21 at 8:42
  • 1
    $\begingroup$ @gte I have added some initial parameters to the code for you. For context, the parameters there are from a co-integrated pair trading system. All the parameters can be optimized. The parameter definitions, uses, optimization methods, etc. are well documented in the link that I have already provided in answer. $\endgroup$ – amdopt Jul 21 at 12:54
  • $\begingroup$ thanks for the example @amdopt. How do you get kappa, alpha, sigma from the state_mean though? Also in this case, what's your x and y for input? $\endgroup$ – user50598 Oct 26 at 15:33
2
$\begingroup$

One resource that has Kalman Filter and Smoother, and Expectation-Maximization algorithms for a Linear Gaussian Model is pykalman module. You can check out statsmodels module too.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.