'Likelihood of pykalman filter yields the same result each time

I'm trying to calibrate a Schwartz Smith two factor model using the Kalman Filter. The idea is to get the parameters that maximize the likelihood.

The math behind the calibration can be checked here: enter image description hereenter image description here

The likelihood output is stuck at 134 even when I'm randomly choosing values for the parameters. Can anyone help me with this ?

def objective_function(kalman_params, args):

    forward_data = args[0]
    dt = args[1]

    number_of_timesteps = forward_data.shape[0]
    observation_dimensions = forward_data.shape[1]
    #print('The observation dimensions are ', observation_dimensions)

    states = np.zeros((number_of_timesteps, 2))
    #print('The states dimension is ', states.shape)
    measurements = forward_data
    measurements['Spot'] = np.log(measurements['Spot'])
    measurements = measurements.values
    #print('The measurements dimension is : ', measurements.shape)

    kappa = kalman_params[0]
    sigma_xi = kalman_params[1]
    sigma_epsilon = kalman_params[2]
    rho = kalman_params[3]
    mu_epsilon_star = kalman_params[4] - kalman_params[5]
    lambda_xi = kalman_params[5]

    initial_state_mean = np.zeros(2)
    initial_state_covariance = np.identity(2)
    #rint('The initial state covariance shape is ', initial_state_covariance.shape)

    cov_1_1 = (sigma_xi**2 / (2 * kappa)) * (1 - np.exp(- 2 * kappa * dt))
    cov_1_2 = (rho * sigma_xi * sigma_epsilon / (kappa)) * (1 - np.exp(- kappa * dt))
    cov_2_1 = cov_1_2
    cov_2_2 = sigma_epsilon**2 * dt

    transition_covariance = np.array([[cov_1_1, cov_1_2] , [cov_2_1, cov_2_2]])
    #print('The transition covariance matrix shape is ', transition_covariance.shape)

    observation_covariance = np.identity(observation_dimensions)
    #print('The observation covariance matrix shape is ', observation_covariance.shape)

    A_matrix = []
    C_matrix = []
    forward_contracts = []

    for t in forward_data.index:

        A_temp = [0]
        C_temp = [[1,1]]

        for forward in forward_data.columns:

            if forward == 'Spot':

                continue

            if 'months' in forward:

                maturity = int(forward.replace(' months', ''))/12

            else:

                maturity = int(forward.replace(' month', ''))/12

            ti = t / 267
            forward_contract = ForwardContract(ti, maturity, forward_data['Spot'].loc[t], None, forward_data[forward].loc[t])
            forward_contracts.append(forward_contract)

            instant_ti = forward_contract.t
            maturity_T = forward_contract.T

            A_temp.append(A(instant_ti, maturity_T, sigma_epsilon, sigma_xi, mu_epsilon_star, kappa, lambda_xi, rho))
            C_temp.append([np.exp(-kappa * (maturity_T - instant_ti)), 1])

        A_matrix.append(A_temp)
        C_matrix.append(C_temp)

    A_matrix = np.array(A_matrix)
    #print(A_matrix)

    displacement = [[0, mu_epsilon_star] for i in range(number_of_timesteps - 1)]
    transition_displacement = np.array(displacement)
    #print('The transition offset shape is ', transition_displacement.shape)

    observation_displacement = A_matrix
    #print('The observation offset shape is ', A_matrix.shape)

    transition = [[[np.exp(-kappa * dt), 0], [0, 1]] for i in range(number_of_timesteps - 1)]
    transition_matrix = np.array(transition)
    #print('The transition matrix shape is ', transition_matrix.shape)
    #print(transition_matrix)

    observation_matrix = np.array(C_matrix)
    #print('The observation matrix shape is ', observation_matrix.shape)
    print(observation_matrix)

    variables = ['transition_matrices', 'observation_matrices', 'transition_offsets', 'observation_offsets', 'transition_covariance', 'observation_covariance']

    kalman_fliter = KalmanFilter(transition_matrices = transition_matrix,
                                observation_matrices = observation_matrix,
                                transition_covariance = transition_covariance,
                                observation_covariance = observation_covariance)
                                #transition_offsets = transition_displacement,
                                #observation_offsets = observation_displacement,
                                #initial_state_mean = initial_state_mean,
                                #initial_state_covariance = initial_state_covariance,
                                #em_vars = variables,
                                #n_dim_state = states.shape[1],
                                #n_dim_obs = observation_dimensions)

    #fitted = kalman_fliter.em(measurements, n_iter = 100, em_vars = variables).smooth(measurements)
    #hidden = np.exp(fitted[0][:,1] + fitted[0][:,0])

    #error = abs(forward_data['Spot'] - hidden).mean()
    lk = kalman_fliter.loglikelihood(measurements)
    print(lk)

    return -lk
    #return error
def A(T, t, sigma_epsilon, sigma_xi, mu_epsilon_star, kappa, lambda_xi, rho):
    return (mu_epsilon_star + sigma_epsilon**2 / 2) * (T - t) - (1 - np.exp(-kappa * (T - t))) * lambda_xi / kappa + sigma_xi**2 * (1 - np.exp(-2 * kappa * (T - t))) / (4 * kappa) + rho * sigma_xi * sigma_epsilon * (1 - np.exp(- kappa * (T - t))) / kappa


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source