Skip to content
All library documents

Diagnosing Local Volatility PDE Errors from Time-to-Expiry Indexing

Article Quant Q&A · Author: ffbzona

Summary

The document describes a local volatility pricing implementation that derives volatility from an SSVI implied volatility surface using Dupire's formula and finite differences. The author checks the implementation by repricing the vanilla options used to calibrate the surface, expecting to recover their implied volatilities, but reports matching at-the-money-forward options while overpricing wing options.

The accepted diagnosis is a time-indexing error in the backward PDE solver: when computing value at a time step, the solver samples local volatility at that time rather than at the corresponding remaining time to expiry. This illustrates how a reversed time coordinate can produce misleading strike-dependent pricing discrepancies even when the volatility surface construction appears smooth. The document offers a targeted debugging clue, but no code correction, numerical verification, or broader comparison of alternative causes.

Key ideas

  • The implementation obtains local volatility from an SSVI surface through Dupire's formula and finite-difference derivatives.
  • Repricing calibration options is used as a consistency check for the local volatility model.
  • A backward PDE solver must map its time coordinate to the correct remaining time to expiry when sampling volatility.
  • The reported indexing mistake is a diagnosis, with no documented corrected run or quantitative validation.

Tags

Full text
# Local Volatility Model Error


# Local Volatility Model Error












I am implementing my local volatility pricer using the finite difference method in MATLAB. I parametrise the implied volatility surface using the SSVI parametrisation (Gatheral & Jacquier), which allows me to obtain a pretty smooth local volatility surface:

I use Dupire's formula in terms of total implied variance $w(k,T)$, where $k=\log(K/F_{0,T})$ and `interpSsviStineman` is responsible for interpolating the ATMF total variance curve and return the implied total variance level for any arbitrary $k$ and $T$:

```
delta_k = 0.0001;
delta_t = 1e-6;
w_k_t = interpSsviStineman(k, t_, ssvi_param_);
w_k_tm = interpSsviStineman(k, t_-delta_t, ssvi_param_);
w_k_tp = interpSsviStineman(k, t_+delta_t, ssvi_param_);
dwdt = (w_k_tp-w_k_tm)/(2*delta_t);
w_km_t = interpSsviStineman(k-delta_k, t_, ssvi_param_);
w_kp_t = interpSsviStineman(k+delta_k, t_, ssvi_param_);
dwdk = (w_kp_t-w_km_t)/(2*delta_k);
d2wdk2 = (w_kp_t+w_km_t-2*w_k_t)/(delta_k^2);
[kg, ~] = ndgrid(k, t_);
local_var = dwdt./(1-kg./w_k_t.*dwdk+1/4*(-1/4-1./w_k_t+...
    kg.^2./w_k_t.^2).*(dwdk).^2 + 1/2*d2wdk2);
local_vol = sqrt(local_var);
```

To validate my implementation I am repricing the vanilla options that I used to calibrate the volatility surface in the first place. If my implementation were to be correct, I would expect to be able to back out the same implied volatilities used to generate the local volatility surface. This is not the case and I seem to be able to match only the prices of AMTF options while my implementation is overpricing the options in the wings:

I would be grateful for any suggestion that can point me to the mistake.

Cheers!

## Answer by ffbzona (score 1, accepted)

https://quant.stackexchange.com/a/57564

The bug I had in my PDE solver was that for approximating the option value at time $t$ in the backwards algorithm, I was sampling the local volatility for the time to expiry $t$ instead of $T-t$.

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.