C++Heston ModelCharacteristic FunctionsFourier PricingEfficient MC

Heston Stochastic Volatility: Theory and C++ Implementation

Module 7 of 835 min readLevel: Hard

Setup

Why Stochastic Volatility?

The Black-Scholes model assumes constant volatility. The market implied volatility surface σ(T,K)\sigma^*(T,K) is demonstrably not flat — it exhibits the volatility smile (a U-shape) and a downward skew for equity index options. These shapes cannot be reproduced by any constant-volatility model.

Two model families address this:

  1. Local volatility (Dupire): σ=σ(t,St)\sigma = \sigma(t, S_t). Fits the surface exactly but produces a term structure of skew that flattens too fast — the model forward smile is too flat relative to observed dynamics.

  2. Stochastic volatility: the volatility itself is a random process with its own SDE. The correlation between the asset and vol processes generates skew that persists across maturities.

The Heston (1993) model is the industry benchmark stochastic vol model. Under the risk-neutral measure:

dSt=rStdt+VtStdWtSdS_t = r S_t\,dt + \sqrt{V_t}\, S_t\,dW_t^S dVt=κ(θVt)dt+ξVtdWtVdV_t = \kappa(\theta - V_t)\,dt + \xi\sqrt{V_t}\,dW_t^V dWS,WVt=ρdtd\langle W^S, W^V \rangle_t = \rho\,dt

Parameters:

  • V0V_0: initial variance (not volatility — note V0\sqrt{V_0} is the initial vol)
  • κ>0\kappa > 0: mean-reversion speed
  • θ>0\theta > 0: long-run variance
  • ξ>0\xi > 0: volatility of variance (vol-of-vol)
  • ρ(1,1)\rho \in (-1, 1): correlation between spot and vol shocks; negative for equity (larger moves down are associated with vol spikes)

Conventions:

  • rr: continuously compounded risk-free rate, annualised.
  • TT: time to expiry in years.
  • Volatility parameters in decimal (not percent).

Theory

1. The Feller Condition

The CIR variance process dVt=κ(θVt)dt+ξVtdWtVdV_t = \kappa(\theta - V_t)\,dt + \xi\sqrt{V_t}\,dW_t^V can hit zero. Whether it stays at zero or bounces off depends on the Feller condition:

2κθ>ξ2Vt>0 almost surely2\kappa\theta > \xi^2 \quad \Longrightarrow \quad V_t > 0 \text{ almost surely}

When the Feller condition is violated (2κθξ22\kappa\theta \leq \xi^2), the process can reach zero and the square root is undefined during simulation. This is not merely numerical — it reflects model instability. On a derivatives desk, parameters are routinely calibrated to surfaces that violate Feller; the simulation scheme must handle this gracefully.

2. Characteristic Function Pricing (Lewis Formula)

The Heston model has a known characteristic function for ln(ST/S0)\ln(S_T/S_0):

ϕ(u;T)=EQ ⁣[eiuln(ST/S0)]=exp ⁣(iu(rq)T+A(u,T)+B(u,T)V0)\phi(u; T) = \mathbb{E}^{\mathbb{Q}}\!\left[e^{iu\ln(S_T/S_0)}\right] = \exp\!\left(iu(r - q)T + A(u, T) + B(u, T) V_0\right)

where (using the Albrecher et al. 2007 numerically stable formulation):

d=(ρξiuκ)2+ξ2(iu+u2)d = \sqrt{(\rho\xi iu - \kappa)^2 + \xi^2(iu + u^2)} g=κρξiudκρξiu+dg = \frac{\kappa - \rho\xi iu - d}{\kappa - \rho\xi iu + d} B(u,T)=κρξiudξ21edT1gedTB(u,T) = \frac{\kappa - \rho\xi iu - d}{\xi^2} \cdot \frac{1 - e^{-dT}}{1 - g e^{-dT}} A(u,T)=κθξ2[(κρξiud)T2ln ⁣1gedT1g]A(u,T) = \frac{\kappa\theta}{\xi^2}\left[(\kappa - \rho\xi iu - d)T - 2\ln\!\frac{1 - ge^{-dT}}{1-g}\right]

The Lewis (2001) formula prices a European call using a single real-valued integral:

C(S0,K,T)=S0S0KerT/2π0Re ⁣[eiuln(S0/K)ϕ(ui/2;T)u2+1/4]duC(S_0, K, T) = S_0 - \frac{\sqrt{S_0 K}\, e^{-rT/2}}{\pi} \int_0^\infty \text{Re}\!\left[\frac{e^{iu\ln(S_0/K)} \phi(u - i/2; T)}{u^2 + 1/4}\right] du

The integrand is smooth and rapidly decaying; standard Gauss-Legendre quadrature on [0,Umax][0, U_{\max}] with Umax200U_{\max} \approx 200 and n200n \approx 200 points gives machine precision.

The stable branch selection (Albrecher 2007 vs. the original Heston 1993 formulation) matters critically: the original formulation has a branch-cut discontinuity in the complex logarithm that causes pricing errors for long maturities or extreme parameters. Always use the Albrecher formulation.

3. Monte Carlo Simulation

For path-dependent products (barriers, Asians) that the Fourier method cannot price analytically, Monte Carlo is required. The variance process must be discretised carefully.

Full truncation Euler (Lord et al. 2010): Vt+Δt=Vt+κ(θVt+)Δt+ξVt+ΔtZ1V_{t+\Delta t} = V_t + \kappa(\theta - V_t^+)\Delta t + \xi\sqrt{V_t^+\,\Delta t}\,Z_1 where V+=max(V,0)V^+ = \max(V, 0) and Z1N(0,1)Z_1 \sim \mathcal{N}(0,1).

The asset step uses the current (potentially zero-floored) variance: St+Δt=Stexp ⁣[(r12Vt+)Δt+Vt+ΔtZ2]S_{t+\Delta t} = S_t \exp\!\left[\left(r - \tfrac{1}{2}V_t^+\right)\Delta t + \sqrt{V_t^+\,\Delta t}\,Z_2\right]

where Z2=ρZ1+1ρ2Z3Z_2 = \rho Z_1 + \sqrt{1-\rho^2}\, Z_3 with Z3N(0,1)Z_3 \sim \mathcal{N}(0,1) independent of Z1Z_1.

The log-Euler scheme for SS avoids negative asset prices without any flooring. The correlation between Z1Z_1 and Z2Z_2 is exactly ρ\rho.

Variance reduction — control variate: use the Black-Scholes price with current spot vol V0\sqrt{V_0} as a control. This reduces standard error by 80-95% near at-the-money.


Implementation

HestonModel.h

#pragma once
#include <complex>

// Heston model parameters
struct HestonParams {
    double V0;       // Initial variance (vol = sqrt(V0))
    double kappa;    // Mean reversion speed
    double theta;    // Long-run variance
    double xi;       // Vol of variance (vol-of-vol)
    double rho;      // Spot-vol correlation

    // Returns true if the Feller condition 2*kappa*theta > xi^2 is satisfied
    bool feller_satisfied() const {
        return 2.0 * kappa * theta > xi * xi;
    }
};

// Computes European call/put price via Lewis (2001) formula
// using the Albrecher et al. (2007) numerically stable characteristic function.
double heston_call_price(double S0, double K, double r, double T,
                         const HestonParams& p);

double heston_put_price(double S0, double K, double r, double T,
                        const HestonParams& p);

The full lesson requires Premium

The complete derivation, the C++ / Python implementation, the validation tables, the quiz, and the interview-angle notes are part of Premium. Start a Premium plan to unlock every module in this track.