Variance Swaps
Finance
A variance swap is a forward contract on realized variance. At maturity, the buyer of variance receives times a notional, where is the realized variance of the underlying's log-returns over the life of the contract, and is the strike fixed at trade inception. Pure exposure to variance, no path of vol assumption, no spot risk. The clean math behind these things — and the central result of the page — is that the fair strike can be replicated EXACTLY by a static portfolio of vanilla options, model-free, with no volatility model required.
What's realized variance?
Take the log-returns of the underlying over the life of the contract, sampled at equally-spaced points:
In the continuous limit , the sum becomes the integrated quadratic variation of divided by . Under any continuous semimartingale , that integral is — the time-average of the instantaneous variance. A variance swap pays off on this quantity directly: it's pure vol, with no spot-direction component, which makes it the cleanest instrument for trading volatility itself.
The static replication theorem
Here is the beautiful part. Under risk-neutral pricing with continuous paths (no jumps) and deterministic rates, the FAIR variance strike — the value of at which the swap is worth zero today — is given by:
where is the forward price, and are today's prices of European puts and calls struck at with the same maturity. The integration is "OTM-only" — puts for strikes below the forward, calls above — and each option is weighted by , which gives the most weight to options near the money.
The remarkable thing isn't the formula. It's that the formula is exact and model-free. You don't need to assume Black-Scholes. You don't need to assume Heston. You don't need to assume anything about the volatility process at all — only that the underlying is a positive martingale with continuous paths. The fair variance is pinned down entirely by the option price surface, because variance is a static function of that surface. Demeterfi, Derman, Kamal, and Zou published this in 1999 and the variance-swap market was open for business within a year.
Where the formula comes from (sketch)
The key identity is the Carr-Madan log contract. For any twice-differentiable payoff ,
Specialize to . Then , the payoffs and are put and call payoffs, and the equality says: holding a short position in a log contract on is the same as holding the -weighted portfolio of OTM puts and calls. Take risk-neutral expectations of both sides, use the relation (which follows from Itô's lemma on under continuous dynamics), and the formula for falls out. The whole derivation is two pages.
Numerical verification
Two sanity checks under flat Black-Scholes vol. First, plug a flat into the replication integral. The fair variance should come out as exactly . Second, simulate the GBM directly and compute the mean realized variance across paths. It should also be . The two have to agree by construction — they're computing the same risk-neutral expectation two different ways.
The script below does both, plus a third experiment where the vol surface has a realistic skew/smile. The verified output:
Flat vol replication: K_var = 0.040000 sigma^2 = 0.040000
MC realized variance: mean = 0.039998 SE = 0.000008
Smile vol replication: K_var = 0.047777 ATM vol^2 = 0.040000
skew premium = 19.4%
implied 'variance vol' = sqrt(K_var) = 0.2186 Lines 1 and 2 agree with to four decimals. Line 3 is the interesting case: a vol surface with realistic downside skew (, with vol rising as moneyness moves away from the forward). The fair variance is 0.0478, which is 19.4% higher than the naive guess of "ATM vol squared." The reason: the OTM puts on the left side of the smile carry extra vol, and the replication weight gives those OTM puts substantial weight — most of all near the strikes just below the forward, where the skew is fattest.
This is one of the canonical observations in the variance-swap business. A variance swap is systematically MORE expensive than ATM-vol-squared whenever there's a downside skew, which is almost always for equity indices. The "variance premium" is the persistent gap between fair variance (set by the option-price replication) and realized variance (set by what actually happens), and it's been positive on average for the S&P 500 for decades. People who SELL variance swaps collect that premium on average; people who BUY variance swaps overpay on average. Selling variance is a famous crowded trade because it works for years and then blows up in a single bad month.
The full code
"""
Variance swap pricing via static replication.
The key theorem (Demeterfi-Derman-Kamal-Zou 1999, Carr-Madan):
the fair variance strike of a variance swap can be replicated EXACTLY
by a continuous strip of OTM European options, weighted by 1/K^2.
This is model-free for any continuous positive martingale - no
volatility model required, just the option price surface.
K_var = (2 e^{rT} / T) [ \int_0^F P(K)/K^2 dK
+ \int_F^infinity C(K)/K^2 dK ]
"""
import numpy as np
from scipy.stats import norm
S0 = 100.0
r = 0.05
T = 1.0
SIGMA = 0.20
def bs_call(S, K, r, sigma, T):
d1 = (np.log(S/K) + (r + 0.5*sigma**2)*T) / (sigma*np.sqrt(T))
d2 = d1 - sigma*np.sqrt(T)
return S*norm.cdf(d1) - K*np.exp(-r*T)*norm.cdf(d2)
def bs_put(S, K, r, sigma, T):
d1 = (np.log(S/K) + (r + 0.5*sigma**2)*T) / (sigma*np.sqrt(T))
d2 = d1 - sigma*np.sqrt(T)
return K*np.exp(-r*T)*norm.cdf(-d2) - S*norm.cdf(-d1)
def fair_variance(S0, r, T, vol_fn, K_min=1e-3, K_max=300.0, n_strikes=4000):
"""Demeterfi-Derman-Kamal-Zou fair variance strike via OTM strip."""
F = S0 * np.exp(r * T)
K_grid = np.linspace(K_min, K_max, n_strikes)
option_pv = np.zeros_like(K_grid)
for i, K in enumerate(K_grid):
sigma_K = vol_fn(K)
if K < F:
option_pv[i] = bs_put(S0, K, r, sigma_K, T)
else:
option_pv[i] = bs_call(S0, K, r, sigma_K, T)
integrand = option_pv / K_grid**2
return (2.0 * np.exp(r * T) / T) * np.trapz(integrand, K_grid)
# ---- 1. Flat vol: replication should give exactly sigma^2 ------------------
Kv_flat = fair_variance(S0, r, T, vol_fn=lambda K: SIGMA)
print(f"Flat vol replication: K_var = {Kv_flat:.6f} sigma^2 = {SIGMA**2:.6f}")
# ---- 2. Monte Carlo realized variance, same flat vol -----------------------
rng = np.random.default_rng(0)
n_paths, n_steps = 200_000, 252
dt = T / n_steps
Z = rng.standard_normal((n_paths, n_steps))
log_returns = (r - 0.5*SIGMA**2)*dt + SIGMA*np.sqrt(dt)*Z
realized_var = np.sum(log_returns**2, axis=1) / T
print(f"MC realized variance: mean = {realized_var.mean():.6f} SE = {realized_var.std()/np.sqrt(n_paths):.6f}")
# ---- 3. With a skew/smile, the variance strike rises ABOVE the ATM vol^2 ---
F = S0 * np.exp(r*T)
def smile_vol(K):
x = np.log(K / F)
sig = 0.20 - 0.10*x + 0.10*x*x # base - skew*x + curve*x^2
return float(np.clip(sig, 0.05, 0.60))
Kv_smile = fair_variance(S0, r, T, vol_fn=smile_vol)
atm = smile_vol(F)
print(f"Smile vol replication: K_var = {Kv_smile:.6f} ATM vol^2 = {atm**2:.6f}")
print(f" skew premium = {(Kv_smile/atm**2 - 1)*100:.1f}%")
print(f" implied 'variance vol' = sqrt(K_var) = {np.sqrt(Kv_smile):.4f}") Practical notes
- Discrete vs continuous sampling. The replication theorem assumes continuous monitoring. Real variance swaps sample daily; the discretization introduces a small "jump bias" in the realized variance estimate. Standard fix: pre-adjust the strike for the expected discretization correction, or just price using the discretely-sampled estimator under the same MC.
- Jumps break the theorem. The replication relies on the underlying being a continuous martingale. If can jump, picks up a jump contribution that the option strip doesn't replicate. Variance swaps under a model with jumps (Merton, Bates) are MORE expensive than the smooth replication says — the jump variance is real but unhedged. The 2008 jump-down in equity indices wrecked variance-swap sellers for exactly this reason.
- Truncation of the strike grid. The integrals run from 0 to , but the option market only quotes a finite range. Truncating at and introduces error proportional to how much OTM premium you're missing. For 1-year ATM contracts on liquid indices the tails are small enough that the error is bounded; for short-dated or single-name swaps the tail truncation matters.
- Volatility swaps are harder. A volatility swap pays , the square root of realized variance minus a strike. The square root is non-linear, so the clean static replication doesn't carry over. Volatility swaps are MODEL-DEPENDENT — you have to assume something about the distribution of to price them. The standard approach is to price by Monte Carlo under Heston or another stochastic-vol model.
- Why anyone trades these. Variance swaps give clean exposure to volatility without spot-direction risk. Vol traders use them to take views on realized vs implied vol. Risk managers use them to hedge tail-event-sensitive books. The clean static replication means a dealer can hedge a variance swap with a fixed portfolio of vanillas — no dynamic delta hedging required for the variance leg.
Related on this site
Volatility surfaces is where the option-price surface comes from in practice. Heston model is the standard stochastic-vol model used when the swap is volatility (not variance), or when jumps require a richer dynamics. Exotic options covers path-dependent payoffs that, unlike variance swaps, do NOT have a model-free replication. Black-Scholes is the pricing model used for the option strip in this page's numerics, but the replication theorem itself doesn't depend on Black-Scholes being right.