Skip to content

Alex-Rib/Heston-Stochastic-Volatility

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Heston Model and Implied Volatility

Python Finance Tests Lint Status

📊 Description

Implementation of the Heston model for European call pricing by Monte Carlo simulation, and analysis of the impact of the correlation ($\rho$) on the volatility skew.

Features

  • Monte Carlo simulation: generation of price and variance paths using a full-truncation Euler scheme
  • European call pricing: with both the Heston and Black-Scholes models
  • Implied volatility: extraction by numerical inversion of Black-Scholes (Brent's method)
  • Skew analysis: impact of the correlation ($\rho$) on the asymmetry of the volatility skew
  • Feller condition: exposed as a dataclass property and checked in the test suite

Heston Model

The model describes the joint evolution of the asset price $S_t$ and its variance $v_t$ under the risk-neutral measure:

$$dS_t = r S_t dt + \sqrt{v_t}S_t dW_t^S$$ $$dv_t = \kappa( \theta - v_t)dt + \sigma_v \sqrt{v_t}dW_t^v$$ with $d\langle W^S, W^v\rangle_t = \rho , dt$

Parameters:

  • $\kappa$: mean-reversion speed
  • $\theta$: long-run variance
  • $\sigma_v$: volatility of variance
  • $\rho$: correlation between price and variance

Simulation Scheme

The price is simulated in log form ($S_t = e^{\log S_t}$), which guarantees $S_t > 0$ by construction. The variance follows a full-truncation Euler scheme: the state $v_t$ may transiently become negative between two steps, but only its positive part $v_t^+ = \max(v_t, 0)$ enters the drift and the square root in the diffusion. This scheme (Lord, Koekkoek & van Dijk, 2010) exhibits the lowest bias among the standard Euler schemes.

Feller Condition

To guarantee that the variance process $v_t$ stays strictly positive, we check: $$2 \kappa \theta > \sigma_v^2$$

It is exposed through HestonParameters.satisfies_feller and verified in the tests (satisfied case, violated case, and strict boundary).

Results

The script produces a graphical comparison of the volatility skew for:

  • $\rho = -0.9$
  • $\rho = -0.7$
  • $\rho = -0.5$
  • $\rho = 0.0$

Structure

black_scholes.py   # closed-form call price + implied vol inversion (Brent)
model.py           # HestonParameters dataclass + HestonMonteCarlo simulator
plot_smile.py      # plots the skew across the different correlation scenarios
tests/
    test_heston.py

Usage

pip install numpy scipy matplotlib
python plot_smile.py
import numpy as np
from model import HestonParameters, HestonMonteCarlo
from black_scholes import implied_vol

params = HestonParameters(spot=100.0, rate=0.03, kappa=2.0, theta=0.04, sigma_v=0.30, v0=0.04)
sim = HestonMonteCarlo(params, n_paths=300_000, n_steps=100, seed=42)

strikes = np.linspace(80.0, 120.0, 40)
prices = sim.call_prices(strikes, maturity=1.0, rho=-0.7)
iv = [implied_vol(100.0, k, 1.0, 0.03, p) for k, p in zip(strikes, prices)]

Tests

pip install pytest ruff
pytest -q
ruff check .

The suite covers the Feller condition (including the strict boundary), the Black-Scholes / implied vol round-trip, the monotonic decrease of the call price in the strike, the degenerate case $\sigma_v = 0$ (which must match Black-Scholes), and the negative skew induced by $\rho < 0$.

Dependencies

numpy
scipy
matplotlib

👨‍💻 Author

Alexandre R. - Université Paris Cité

About

Heston stochastic volatility model via Monte Carlo. European call pricing with log-Euler discretization and analysis of skew dynamics vs spot-vol correlation

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages