I'm trying to build Bates model in Python!
$$dS_{t} = \mu S_{t} dt + \sqrt{V_{t}}S_{t}dW_{t}^{1} + J_{t}dQ_{t}$$ $$dV_{t} = \kappa(\theta - V{t})dt + \eta \sqrt{V_{t}}dW_{t}^{2}$$ $$dW_{t}^{1}dW_{t}^{2} = \rho dt$$
Where $dW_{t}^{1}$ and $dW_{t}^{2}$ - normally distributed processes, $dQ_{t}$ - Poisson distribution
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
sns.set(palette='viridis')
%matplotlib inline
%config InlineBackend.figure_format='retina'
S0 = 62083
r = 0.085
T = 62 / 252
dt = 1 / 252
def MC(S0):
rho = -0.344558
kappa = -0.855167
eta = 0.510156
theta = 0.643609
v0 = 0.099067
a = 0.2
b = 0.2
Lamda = 0.25
Nsim = 100
Nsteps = 62
mu = 0.1
np.random.seed(5)
dw_1 = np.random.normal(loc = 0, scale = np.sqrt(dt), size = (Nsim, Nsteps))
dz_1 = np.random.normal(loc = 0, scale = np.sqrt(dt), size = (Nsim, Nsteps))
dw_2 = dw_1 * rho + np.sqrt(1 - rho ** 2) * dz_1
Poisson = np.random.poisson(Lamda * dt, [Nsim, Nsteps])
St = np.zeros([Nsim, Nsteps+1])
vol = np.zeros([Nsim, Nsteps+1])
St[:, 0] = S0
vol[:, 0] = v0
for i in range(Nsteps):
vol[:, i + 1] = np.abs(vol[:, i] + kappa * (theta - vol[:, i]) * \
dt + eta * (np.sqrt(vol[:, i]) * dw_2[:, i]))
St[:, i + 1] = St[:, i] * np.exp((mu - 0.5 * \
vol[:, i]) * dt + np.sqrt(vol[:, i] * dt) \
* dw_1[:, i] + a * Poisson[:, i] \
+ np.sqrt(b ** 2) * np.sqrt(Poisson[:,i]))
return St
There should be a mistake in discretisation of price path (St):
St[:, i + 1] = St[:, i] * np.exp((mu - 0.5 * \
vol[:, i]) * dt + np.sqrt(vol[:, i] * dt) \
* dw_1[:, i] + a * Poisson[:, i] \
+ np.sqrt(b ** 2) * np.sqrt(Poisson[:,i]))
I think so, as I get to strange path simulations:
plt.plot(MC(S0).T)
plt.show()
I know the problem is with discretisation of price path (St), not with parameters values as I tested another one. However, I don't know the right way to fix it. Could somebody help me to fix it, please?