Heston Model with Jumps#
THe models complements the standard Heston stochastic volatility model, with the addition of a double exponential Compound Poisson process. The Compound Poisson process adds a jump component to the Heston diffusion SDEs which control the volatility smile and skew for shorter maturities.
(59)#\[\begin{align}
y_t &= x_{\tau_t} + d j_t\\
\tau_t &= \int_0^t \nu_s ds \\
d x_t &= d w_t \\
d \nu_t &= \kappa\left(\theta - \nu_t\right) dt + \sigma\sqrt{\nu_t} d z_t \\
{\mathbb E}\left[d w_t d z_t\right] &= \rho dt
\end{align}\]
where \(j_t\) is a double exponential Compound Poisson process which adds three additional parameter to the model
the jump intensity, which measures the expected number of jumps in a year
the jump percentage (fraction) contribution to the total variance
the jump asymmetry is defined as a parameter greater than 0; 1 means jump are symmetric
The jump process is independent of the other Brownian motions.
from quantflow.sp.heston import HestonJ
pr = HestonJ.create(
vol=0.6,
kappa=2,
sigma=0.8,
rho=-0.2,
jump_intensity=50,
jump_fraction=0.2,
jump_asymmetry=1.2
)
pr
HestonJ(variance_process=CIR(rate=0.288, kappa=2.0, sigma=0.8, theta=0.288, sample_algo=<SamplingAlgorithm.implicit: 'implicit'>), rho=-0.2, jumps_up=CompoundPoissonProcess[Exponential](intensity=50.0, jumps=Exponential(decay=48.511803323813844)), jumps_down=CompoundPoissonProcess[Exponential](intensity=50.0, jumps=Exponential(decay=58.214163988576615)))
from quantflow.utils import plot
plot.plot_marginal_pdf(pr.marginal(0.1), 128, normal=True, analytical=False)
from quantflow.options.pricer import OptionPricer
from quantflow.sp.heston import Heston
pricer = OptionPricer(pr)
pricer
OptionPricer(model=HestonJ(variance_process=CIR(rate=0.288, kappa=2.0, sigma=0.8, theta=0.288, sample_algo=<SamplingAlgorithm.implicit: 'implicit'>), rho=-0.2, jumps_up=CompoundPoissonProcess[Exponential](intensity=50.0, jumps=Exponential(decay=48.511803323813844)), jumps_down=CompoundPoissonProcess[Exponential](intensity=50.0, jumps=Exponential(decay=58.214163988576615))), n=128, max_moneyness_ttm=1.5)
fig = None
for ttm in (0.05, 0.1, 0.2, 0.4, 0.6, 1):
fig = pricer.maturity(ttm).plot(fig=fig, name=f"t={ttm}")
fig.update_layout(title="Implied black vols", height=500)