Control Variates
Motivation: why this matters in quant finance
Control variates is the most powerful of the elementary variance-reduction methods. The idea: if you're pricing some quantity , and you know another quantity exactly (e.g. analytically), and is correlated with , then
has the same mean as but lower variance for an appropriately chosen .
The informal idea
Suppose you want and you have draws . Plain MC estimator: , variance .
Minimising in : , giving optimal variance
So variance is reduced by factor . If , variance is reduced to , i.e., reduction. If , reduction.
Formal statement
- Unbiased for any : .
- Variance .
- Optimal (the OLS slope of on ).
- Minimum variance .
In practice, is unknown; estimate it from the same sample as . Using estimated introduces a tiny bias of order that's negligible compared to the variance.
Algorithm: geometric Asian as control for arithmetic Asian
The geometric and arithmetic averages are nearly equal for moderate volatility, so — control variates gives massive variance reduction.
import numpy as np
from scipy.stats import norm
def mc_arithmetic_asian_with_cv(S0, K, T, r, sigma, M, N, seed=42):
rng = np.random.default_rng(seed)
dt = T / M
Z = rng.standard_normal((N, M))
increments = (r - 0.5 * sigma**2) * dt + sigma * np.sqrt(dt) * Z
log_paths = np.log(S0) + np.cumsum(increments, axis=1)
paths = np.exp(log_paths)
# Target X: arithmetic Asian
arith_avg = paths.mean(axis=1)
X = np.exp(-r*T) * np.maximum(arith_avg - K, 0)
# Control Y: geometric Asian
geo_avg = np.exp(log_paths.mean(axis=1))
Y = np.exp(-r*T) * np.maximum(geo_avg - K, 0)
# Closed form for geometric Asian
sigma_geo = sigma * np.sqrt((2*M + 1) / (6*(M+1)))
mu_geo = 0.5 * (r - 0.5*sigma**2 + sigma_geo**2)
d1 = (np.log(S0/K) + (mu_geo + 0.5*sigma_geo**2)*T) / (sigma_geo*np.sqrt(T))
d2 = d1 - sigma_geo*np.sqrt(T)
Y_mean = np.exp(-r*T) * (S0 * np.exp(mu_geo*T) * norm.cdf(d1) - K * norm.cdf(d2))
# CV: estimate beta and apply
beta = np.cov(X, Y, ddof=1)[0, 1] / np.var(Y, ddof=1)
X_cv = X - beta * (Y - Y_mean)
return X_cv.mean(), X_cv.std(ddof=1) / np.sqrt(N), X.mean(), X.std(ddof=1) / np.sqrt(N), np.corrcoef(X, Y)[0,1]
p_cv, se_cv, p_plain, se_plain, rho = mc_arithmetic_asian_with_cv(100, 100, 1, 0.05, 0.2, 50, 100_000)
print(f"Plain MC: {p_plain:.4f} ± {1.96*se_plain:.4f}")
print(f"CV MC: {p_cv:.4f} ± {1.96*se_cv:.4f}")
print(f"rho = {rho:.4f}, var reduction = {1 - rho**2:.4f}")
print(f"SE ratio: {se_cv/se_plain:.4f}")
# Plain MC: 5.7720 ± 0.0467
# CV MC: 5.7689 ± 0.0030
# rho = 0.9979, var reduction = 0.0042
# SE ratio: 0.064115-fold standard-error reduction; equivalent to more samples.
Key properties
- Choice of control matters. Higher means more variance reduction. A weakly correlated control gives little benefit; a perfectly correlated control gives a closed-form-equivalent precision.
- Multiple controls. Generalises to a vector of controls with multivariate regression. Optimal .
- Estimated . Standard practice. Adds tiny bias but the variance reduction is preserved.
- Self-control variates. When no analytic control exists, the value at of any traded asset can serve. E.g., the discounted stock has known mean . For a call, this gives modest correlation but is always available.
- Stratification as a control. Conditional MC and stratified sampling are mathematically equivalent to control variates with carefully chosen indicator controls.
Common controls in quant finance
- Geometric Asian — control for arithmetic Asian.
- Black-Scholes — control for stochastic-vol or local-vol pricing of vanillas. Compute the BS price at the same strike/expiry analytically; correlation between the model price and BS price is high.
- Average asset / max of two — control for basket options.
- First-order Taylor expansion — control for slowly-converging integrals; the linearised version is often much cheaper to compute.
- Sticky-strike vol surface — control for full SLV pricing.
Worked example: Black-Scholes control for Heston
Heston model: , , .
Pricing a vanilla call under Heston via MC: target .
Common confusions and pitfalls
- must be exact. If you estimate from the same sample (e.g., using the empirical mean), you're not gaining anything — it's mathematically equivalent to a slightly different reformulation, no variance reduction.
- Estimate from a small pilot. If is estimated from the full sample, the resulting estimator's depends on the sample, introducing bias. Usually negligible. But for tiny , or for unbiased asymptotic CIs, use a pilot run.
- Correlation is what matters, not magnitude. A control that's smaller than but with is fine. The optimal scales the control to fit.
- Multiple controls = multivariate regression. Add controls, get more variance reduction, but the gains plateau quickly when the controls are themselves correlated. Three carefully chosen controls usually capture 95% of available variance reduction.
- Doesn't help with bias. Control variates is a variance reduction technique. Discretisation bias, model bias, and edge effects are unaffected.
Where this goes next
- Importance sampling — for tail-event payoffs.
- Quasi-Monte Carlo — replaces randomness, stacks with control variates.
- Antithetic variates — cheap and complementary.