Skip to content

Local Volatility: Dupire's Formula and the Forward Variance

How the unique local volatility function is recovered from the option price surface: the Dupire formula, the butterfly-denominator trap, Andreasen-Huge calibration, and where the model will mislead you.

6 of 12 ~13 min

In 1994, Dupire and Derman-Kani independently discovered the same thing: given a complete implied volatility surface, there exists a unique function σ(S,t)\sigma(S, t) such that the model dSt=rSt dt+σ(St,t)St dWt\text{d}S_t = r S_t \, dt + \sigma(S_t, t) S_t \, dW_t prices every European option exactly in line with the market. Volatility is no longer a constant, and not a separate random state either — it is a deterministic function of spot and time, and that function can be computed directly from market quotes.

That is worth pausing on. The implied volatility smile started life as evidence that the Black-Scholes assumptions fail; here it turns into an input, and the entire smile — term structure included — is absorbed exactly by a one-factor diffusion. There is a price for this, which we will get to. First, how the machine is built.

The Forward PDE

Start from the Black-Scholes PDE and let the diffusion coefficient depend on SS and tt:

∂V∂t+12σ2(S,t)S2∂2V∂S2+rS∂V∂S−rV=0\frac{\partial V}{\partial t} + \frac{1}{2}\sigma^2(S, t) S^2 \frac{\partial^2 V}{\partial S^2} + r S \frac{\partial V}{\partial S} - r V = 0

This is a backward equation: fix one contract (K,T)(K, T) and solve over the state (S,t)(S, t). But the market data have exactly the opposite shape — there is one spot S0S_0 and hundreds of strikes and tenors. What we observe is a sheet of prices V(S0,K,T)V(S_0, K, T) over (K,T)(K, T) space; what we want to recover is σ(S,t)\sigma(S, t). With the backward equation, every (K,T)(K, T) needs its own solve, and the inverse problem stays out of reach.

Dupire’s key move is to flip the direction: treat the call price as a function of (K,T)(K, T). Let C(K,T)C(K, T) be the undiscounted call price (what you pay at time 00 for a European call of strike KK and expiry TT, everything else held fixed). Then CC satisfies a forward equation:

∂C∂T=12σloc2(K,T)K2∂2C∂K2+rK∂C∂K\frac{\partial C}{\partial T} = \frac{1}{2}\sigma^2_{\text{loc}}(K, T) K^2 \frac{\partial^2 C}{\partial K^2} + r K \frac{\partial C}{\partial K}

Structurally, this is the forward Kolmogorov / Fokker-Planck equation of the local-vol process, with call prices in place of the density: compared to the backward PDE, the time direction is reversed and KK sits where SS used to. Once the direction is flipped, the whole market surface becomes the solution of a single equation — one solve covers every (K,T)(K, T), and the inverse problem opens up.

The starting condition of the forward equation is the payoff itself:

C(K,T)=max⁡(S−K,0) as T→T0C(K, T) = \max(S - K, 0) \text{ as } T \to T_0

(T0T_0 is today; more precisely, C(K,0)=(S0−K)+C(K, 0) = (S_0 - K)^+ at T=0T = 0, and the forward equation marches out to later maturities from there.) With the right σloc\sigma_{\text{loc}}, the solution C(K,T)C(K, T) reproduces the entire market surface.

The Dupire Formula

Since the market has already handed us C(K,T)C(K, T), the only unknown left in the forward equation is σloc2\sigma^2_{\text{loc}}. Solve for it:

σloc2(K,T)=∂C∂T+rK∂C∂K12K2∂2C∂K2\sigma^2_{\text{loc}}(K, T) = \frac{\frac{\partial C}{\partial T} + r K \frac{\partial C}{\partial K}}{\frac{1}{2} K^2 \frac{\partial^2 C}{\partial K^2}}

This is Dupire’s formula. The right-hand side contains only derivatives of the market surface, no model parameters — first derivatives in the numerator, a second derivative in the denominator, plug in and you have the local volatility.

Each derivative corresponds to a tradeable option package, which is not a coincidence but no-arbitrage in concrete form. ∂C/∂T\partial C/\partial T is a calendar spread: same strike, adjacent maturities. −∂C/∂K-\partial C/\partial K is the price of an infinitely tight call spread — a digital option. And ∂2C/∂K2\partial^2 C/\partial K^2 is the limit price of an infinitely tight butterfly, which is proportional to the risk-neutral density at KK; it must be non-negative, or the surface contains a butterfly arbitrage.

Market data are discrete, so the derivatives become finite differences:

∂C∂K≈C(K+h)−C(K−h)2h\frac{\partial C}{\partial K} \approx \frac{C(K + h) - C(K - h)}{2h} ∂2C∂K2≈C(K+h)−2C(K)+C(K−h)h2\frac{\partial^2 C}{\partial K^2} \approx \frac{C(K + h) - 2C(K) + C(K - h)}{h^2} ∂C∂T≈C(T+Δ)−C(T)Δ\frac{\partial C}{\partial T} \approx \frac{C(T + \Delta) - C(T)}{\Delta}

The denominator is literally the value of a butterfly. When it is small or negative, the numerics collapse — this is the method’s weak point, and it deserves an explicit calculation.

How Fragile the Denominator Is: A Worked Example

Take ATM SPX with S=4500S = 4500, r=0.05r = 0.05, dividend yield 1.8%, σ=0.20\sigma = 0.20, T=0.25T = 0.25, strikes spaced 45 points apart (1%). The central difference for the second derivative:

∂2C∂K2∣K0≈C(K0+h)−2C(K0)+C(K0−h)h2\frac{\partial^2 C}{\partial K^2}\bigg|_{K_0} \approx \frac{C(K_0 + h) - 2C(K_0) + C(K_0 - h)}{h^2}

Black-Scholes gives the three prices (ignoring skew):

C(4455)≈232.1,C(4500)≈207.7,C(4545)≈185.0C(4455) \approx 232.1, \quad C(4500) \approx 207.7, \quad C(4545) \approx 185.0

Numerator: 232.1−415.4+185.0≈1.8232.1 - 415.4 + 185.0 \approx 1.8. Denominator: 452=202545^2 = 2025. Result: 1.8/2025≈0.00091.8/2025 \approx 0.0009 — which is indeed the risk-neutral density at that point, matching the analytical value.

Notice what just happened: three prices around 200 cancelled down to 1.8. Now add a dose of reality. Suppose each option trades on a 1-index-point bid-ask spread, so the mid is uncertain by about ±0.5\pm 0.5 points. The numerator is a (1,−2,1)(1, -2, 1) combination; with independent errors its standard deviation is about 6×0.5≈1.2\sqrt{6} \times 0.5 \approx 1.2 — against a true value of 1.8. Quote noise is the same order as the signal, so a density estimated by raw differencing can be off by tens of percent, and it gets squared into σloc2\sigma^2_{\text{loc}} afterwards.

This is why nobody differentiates raw quotes in production. Fit a smooth function through the data first (cubic splines, kernel smoothing, or Andreasen-Huge below), then differentiate analytically.

Calibration: From Quotes to Surface

The pipeline is short; every step has a catch:

  1. Pre-process market data. Convert bid-ask to mid, interpolate missing strikes, smooth across maturities. IVs, straddle prices, and butterfly prices each have their own interpolation conventions; mixing them introduces spurious arbitrage.
  2. Compute derivatives. Use the central differences above, or spline-fit first and differentiate analytically — the second derivative in KK is the noisiest, for the reason just computed.
  3. Evaluate Dupire’s formula point by point, obtaining σloc2\sigma_{\text{loc}}^2 at each (K,T)(K, T).
  4. Check positivity. σloc2\sigma_{\text{loc}}^2 must be non-negative everywhere; a negative value means the smoothed surface itself admits arbitrage.
  5. Extrapolate. Quotes are sparse in the deep OTM wings and local vol can blow up towards low strikes; the standard fix is to clamp to the boundary value outside some range.

A demonstration-grade implementation:

import numpy as np

def local_vol_dupire(C, K_grid, T_grid, r):
    K, T = np.meshgrid(K_grid, T_grid, indexing='ij')
    Kp, Km = K + 1e-6, K - 1e-6
    dC_dK  = (np.interp(Kp, K_grid, C) - np.interp(Km, K_grid, C)) / 2e-6
    d2C_dK2 = (np.interp(Kp, K_grid, C) - 2*C + np.interp(Km, K_grid, C)) / 1e-12
    Tp = T + 1e-6
    dC_dT = (np.interp(Tp, T_grid.ravel(), C.ravel()) - C) / 1e-6  # simple forward diff
    sigma2 = (dC_dT + r * K * dC_dK) / (0.5 * K**2 * d2C_dK2)
    sigma2 = np.maximum(sigma2, 0.0)
    return np.sqrt(sigma2)

This shows the formula’s structure; do not point it at real quotes — the noise arithmetic above is the reason. Production implementations use arbitrage-free interpolation, and the reference method is Andreasen-Huge.

Andreasen-Huge: Calibration Without Differentiation

Andreasen and Huge (2011) sidestep explicit differentiation entirely: instead of starting from the continuous formula, they solve a fully discrete Dupire equation on a grid aligned with the market quotes (one column per quoted strike, one row per quoted expiry):

Ci,j+1=Ci,j+ΔT⋅[12σi,j2Ki2⋅δ2C/δK2+rKi⋅δC/δK]C_{i,j+1} = C_{i,j} + \Delta T \cdot \left[\frac{1}{2}\sigma^2_{i,j} K_i^2 \cdot \delta^2 C / \delta K^2 + r K_i \cdot \delta C / \delta K\right]

and back out σi,j2\sigma^2_{i,j} at each grid point. The second derivative never has to be formed on its own — it only appears inside the discrete scheme, whose structure enforces an arbitrage-free, positive output surface. This is far more stable than numerical differentiation, and production-grade local vol in commercial systems is essentially always from this family.

While we are here, one theoretical point worth settling: why does every smooth arbitrage-free surface determine a unique local vol function? Because the forward equation has a unique solution. The smile, read as state prices of the terminal distribution, encodes the cumulative effect of the diffusion along the path; the forward equation inverts that accumulation, and what comes out is the Markovian diffusion. Local vol models are not assumed into existence — they are reconstructed from market data.

Once You Have the Surface

With σloc(S,t)\sigma_{\text{loc}}(S, t) in hand, pricing any European payoff reduces to a PDE with known coefficients:

∂V∂t+12σloc2(S,t)S2∂2V∂S2+rS∂V∂S−rV=0\frac{\partial V}{\partial t} + \frac{1}{2}\sigma^2_{\text{loc}}(S, t) S^2 \frac{\partial^2 V}{\partial S^2} + r S \frac{\partial V}{\partial S} - r V = 0

Finite differences, finite elements, or trees with time-varying vol all work. Path-dependent payoffs are handled by simulating the SDE directly:

dSt=rSt dt+σloc(St,t)St dWtdS_t = r S_t \, dt + \sigma_{\text{loc}}(S_t, t) S_t \, dW_t

The smile and its term structure enter every path automatically — that is the selling point of “one-factor local vol”: one factor, the whole surface, consistently.

A production pipeline looks like: pre-process quotes; solve for σloc\sigma_{\text{loc}} with Andreasen-Huge on a grid covering all quotes (say 60 strikes × 30 tenors); clamp the extrapolation for S<0.5FS < 0.5F, S>1.5FS > 1.5F, and very short or very long tenors; build a bilinear or bicubic 2D interpolator; then run Monte Carlo with Euler or Milstein stepping, refining the time step near S=0S = 0:

dSt=rStdt+σloc(St,t)StdWtdS_t = r S_t dt + \sigma_{\text{loc}}(S_t, t) S_t dW_t

The last step is always validation: reprice a reference set of European options and compare against the input surface. They should agree to numerical precision. If they don’t, the pipeline has a bug — it is not a modeling question.

What a Concrete Surface Looks Like

Take SPX with S=4500S = 4500, r=0.05r = 0.05, dividend yield 1.8%. ATM implied vols: 16% at 30 days, 17% at 90 days, 18% at 1 year. Skew slightly negative: the 30-day 25-delta put trades at 19.5%, the 25-delta call at 17%. The calibrated local vol surface comes out roughly as:

  • ATM local vol at S=4500S = 4500, T=0.25T = 0.25 ≈ 17% — note it sits above the 30-day ATM implied of 16%: local vol is a forward instantaneous quantity, and with an upward-sloping term structure it runs ahead of the implied.
  • At S=4500S = 4500, T=1.0T = 1.0 ≈ 18.5%, again slightly above the 1-year implied of 18%.
  • At S=4000S = 4000, T=0.25T = 0.25 ≈ 24%: the left wing is lifted by the high IVs of deep OTM puts, and it is steeper than the implied skew itself — implied vol is a path-average of local vol, so for the average to reach 19.5% the local values down there must be higher.
  • At S=5000S = 5000, T=0.25T = 0.25 ≈ 14%, the right wing mirroring below the implieds.

By construction, these values reproduce every market quote exactly. The failure modes are recognizable too: σloc2\sigma^2_{\text{loc}} going negative in some corner (the surface has arbitrage), the wings blowing up towards S→0S \to 0 (extrapolation not clamped), wild values where ∂2C/∂K2→0\partial^2 C/\partial K^2 \to 0 deep out of the money (wing quotes too sparse). And one piece of discipline: pricing a 10-year option off a surface calibrated to 1-year data does not work — recalibrate. The theory is clean; the production system lives on error handling.

What It Gets Wrong

By construction, local vol is “exactly right” only for European options. As soon as a product depends on how the smile will move, the model starts giving wrong answers. On equity indices there are three well-known biases, and they are really three projections of the same fact:

The forward smile is too flat. In a local vol model calibrated to a typical negatively skewed surface, the smile of a forward-starting option flattens as the start date moves out; empirically, forward smiles stay about as steep as today’s spot smile (Bergomi, 2008). This is the famous forward-smile problem in pricing cliquets and forward-starting options — their exposure to forward skew and forward convexity is systematically mispriced, with errors that can reach double-digit percentages, in a direction that depends on which side of the structure dominates.

Spot-vol correlation is pinned at −1-1. In local vol, σ\sigma is a deterministic function of SS, so the instantaneous correlation has absolute value 1; with a negative skew that means SS down, vol up, correlation −1-1. Empirically the correlation is negative but imperfect — Heston-style calibrations typically land around −0.7-0.7. A deterministic link and a stochastic one are different phenomena, and hedge ratios differ accordingly.

There is no independent volatility risk. The root of the previous two: the model simply has no second source of randomness. Vol cannot move while SS stands still — in reality it does.

These three points are precisely why stochastic vol models (Heston, SABR) and forward-variance models (Bergomi) exist. The next article starts from exactly this move: giving volatility a random driver of its own.

The Forward Variance

One quantity connects local vol to the variance-swap family of instruments. Define the forward variance as the derivative of expected accumulated variance with respect to maturity:

ξ(T)=∂∂T E[∫0Tσloc2(Su,u) du]=E[σloc2(ST,T)]\xi(T) = \frac{\partial}{\partial T}\, \mathbb{E}\left[\int_0^T \sigma^2_{\text{loc}}(S_u, u) \, du\right] = \mathbb{E}\left[\sigma^2_{\text{loc}}(S_T, T)\right]

It is the model’s today-forecast of instantaneous variance around time TT. Accumulated, it gives the fair variance-swap strike:

E[∫0Tσloc2(Su,u) du]=∫0Tξ(u) du=T⋅Kvar(T)\mathbb{E}\left[\int_0^T \sigma^2_{\text{loc}}(S_u, u) \, du\right] = \int_0^T \xi(u)\, du = T \cdot K_{\text{var}}(T)

And KvarK_{\text{var}} has a representation that does not depend on any model. By the Carr-Madan formula (derived in full in the variance-swap article), the fair strike integrates directly out of option prices:

Kvar=2T∫0S0P(K)−(S0−K)+K2dK+2T∫S0∞C(K)−(K−S0)+K2dKK_{\text{var}} = \frac{2}{T} \int_0^{S_0} \frac{P(K) - (S_0 - K)^+}{K^2} dK + \frac{2}{T} \int_{S_0}^{\infty} \frac{C(K) - (K - S_0)^+}{K^2} dK

There is a consistency here worth remembering: as long as paths are continuous (no jumps), the variance-swap strike is determined by the vanilla surface alone — so a local vol model that fits the surface exactly automatically reproduces the model-free KvarK_{\text{var}}. That is not a coincidence; it is the direct consequence of “the surface determines the terminal distribution, and the terminal distribution prices the log-contract.” The disagreements live elsewhere: with jumps, the replication formula itself breaks; and more importantly, products sensitive to how the forward variance moves — vol swaps, VIX options — get the wrong dynamics from local vol, because the forward variance curve is deterministic in the model while in the market it fluctuates on its own. Static quantities right, dynamic quantities wrong: that pattern runs through everything local vol does.

How to Use It

Knowing the flaws, why does every desk still run local vol daily? Because it offers three things no other model does. First, it is the only model that fits every quoted European option exactly — stochastic vol models have a handful of parameters against hundreds of strikes, so exact fit is mathematically out of reach. Second, the mark-to-market error on the calibration set is zero (within bid-ask), so the book is self-consistent. Third, delta- and gamma-hedging against the surface has a credible reference point.

So the right way to use it is as the calibrated, deterministic reference: price the daily European flow with it; for exotics, produce a baseline price first and then measure what “smile dynamics” is worth with a stochastic vol model on top; and when the local vol price disagrees with where the market trades, that gap is information — either an opportunity or a problem with your surface. In recent years many teams have taken to treating the implied vol surface itself as a state quantity: local vol, stochastic vol, SABR, and the forward-variance curve are different representations of the same set of market beliefs, each illuminating a different aspect. When a book shows mark-to-market P&L the trader cannot explain, the answer is usually that the surface itself moved and your model only knows how to recalibrate, not how to describe that move. The fix is a model with smile dynamics, not another refit of the surface.

Local vol describes what the market believes now; stochastic vol describes how that belief changes. You need both.


Reading list. Hull, Options, Futures, and Other Derivatives, 10th ed. (2018), chapters on volatility smiles and local volatility. Wilmott, Paul Wilmott on Quantitative Finance, 2nd ed. (2007), for the forward PDE and the Dupire derivation in detail. Dupire, “Pricing with a Smile,” Risk (1994). Gatheral, The Volatility Surface (2006). Andreasen & Huge, “Volatility Interpolation,” Risk (2011), for arbitrage-free local vol calibration.