0

Currently I am using pykalman KalmanFilter in a following manner to calculate spread in between 2 timeseries of closing prices:

def KalmanFilterRegression(x,y):
  delta = 1e-3
  trans_cov = delta / (1 - delta) * np.eye(2) # How much random walk wiggles
  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, # y is 1-dimensional, (alpha, beta) is 2-dimensional
    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)
  return state_means

state_means = KalmanFilterRegression([numpy array prices 1], [numpy array prices 2])
      
hr = - state_means[:, 0]
spread = [numpy array prices 1] + ([numpy array prices 2]* hr)

In order to optimize the execution I wanted to try using kalmantv (https://github.com/mlysy/kalmantv), but I struggle on how to constitute the input for KalmanTV.filter. What I currently have is

import numpy as np
from kalmantv.cython import KalmanTV

x = [np.array prices 1]
y = [np.array prices 2]

n_meas = 1 # Set the size of the measurement ✅
n_state = 2 # Set the size of the state ✅

# Initialize mean and variance at time n-1.            # pykalman native var name
mu_state_past = np.random.rand(n_state)                # initial_state_mean = np.array([0,0]) ✅
var_state_past = np.random.rand(n_state, n_state)      # initial_state_covariance = np.asfortranarray(np.ones((2, 2))) ✅
var_state_past = var_state_past.dot(var_state_past.T)  # ensure symmetric positive definiteness
var_state_past = np.asfortranarray(var_state_past)     # convert to Fortran order

# Parameters to the Kalman Filter
mu_state = np.random.rand(n_state)               # lambda_n - transition_offset 
wgt_state = np.random.rand(n_state, n_state).T   # transition_matrix = np.eye(2) ✅
var_state = np.random.rand(n_state, n_state)     # transition covariance = np.asfortranarray(1e-3 / (1 - 1e-3) * np.eye(2)) ✅
var_state = var_state.dot(var_state.T).T
x_meas = np.random.rand(n_meas)                  # observation = y ✅
mu_meas = np.random.rand(n_meas)                 # d_n - observation_offset 
wgt_meas = np.random.rand(n_state, n_meas).T     # observation_matrix = np.expand_dims(np.vstack([[x], [np.ones(len(x))]]).T, axis=1) ✅
var_meas = np.random.rand(n_meas, n_meas)        # observation_covariance = 2 (not sure if int will be accepted) ✅
var_meas = var_meas.dot(var_meas.T).T

# Initialize the KalmanTV class
ktv = KalmanTV(n_meas, n_state)

# Allocate memory for storing the output
mu_state_pred = np.empty(n_state)                         # E[x_n | y_{0:n-1}] - predicted_state_mean ✅
var_state_pred = np.empty((n_state, n_state), order='F')  # var(x_n | y_{0:n-1}) - predicted_state_covariance ✅
mu_state_filt = np.empty(n_state)                         # E[x_n | y_{0:n}] - fitlered_state_mean ✅
var_state_filt = np.empty((n_state, n_state), order='F')  # var(x_n | y_{0:n}) - filtered_state_covariance ✅

# Run the filtering algorithm
ktv.filter(mu_state_pred, var_state_pred,
           mu_state_filt, var_state_filt,
           mu_state_past, var_state_past,
           mu_state, wgt_state, var_state,
           x_meas, mu_meas, wgt_meas, var_meas)

# I assume the target output equivalent to state_means will be mu_state_filt

I would highly appreciate help with defining variables observation_offset and transition_offset (& additional check on observation_covariance). I would also be grateful for general feedback on the transition and reassigning the variables. Thanks!

mscbr
  • 1
  • 1

0 Answers0