edgekit

Simulation & Monte Carlo

When an expectation has no closed form — a path-dependent option, a drawdown distribution, a posterior — you estimate it by sampling. Monte Carlo turns every integral into an average, and the entire subject reduces to two questions: how do I draw from the distribution I need? and how do I shrink the variance of the average? This chapter derives the estimator and its error law, builds the classic sampling algorithms (inverse transform, acceptance–rejection, Box–Muller, Cholesky), and ends with importance sampling — the tool that makes rare-event probabilities computable.

Intuition — integration by gambling

Any expectation is an integral, and any integral over a probability density is an expectation. If you can draw samples from the density, the law of large numbers (chapter 7) guarantees the sample average of converges to , and the CLT tells you exactly how fast. The magic is what the error rate does not depend on: the dimension of the integral. A 100-dimensional basket-option price converges at the same rate as a one-dimensional one — which is why Monte Carlo owns high-dimensional finance while quadrature grids die of the curse of dimensionality.

The Monte Carlo estimator and its error#

Suppose you want and can simulate iid copies of . The Monte Carlo estimator is the plain average

Proof — the standard error and the 1/√n law

By independence, variances add: where . So the root-mean-square error is

and by the CLT, for large , giving the reportable interval with the sample standard deviation of the . Nothing in the derivation mentioned the dimension of — only the variance of the scalar matters. The price of the square root: one more decimal digit of accuracy costs the samples. Every variance-reduction technique below exists to shrink instead of growing .

Worked example — estimating . Throw uniform points on the unit square; has mean , a Bernoulli with variance . The estimator therefore has standard error . With darts: se — you get reliably, but the fourth digit is already a coin flip. To pin down (se ) you would need darts. Monte Carlo is a blunt instrument for precision — and a scalpel for dimension.

Quant lens — the backtest is a Monte Carlo estimate
A backtest average of trade returns is with P&L per trade — same estimator, same error bar, except the market hands you one sample path and you cannot rerun it. Simulation restores the ability to rerun: resample the trades (bootstrap) or simulate the price process (simulating markets) and the distribution of Sharpe, drawdown, and ruin becomes an ordinary Monte Carlo computation. That is the entire logic of the applied Monte Carlo chapter.

Inverse transform sampling#

Every sampler starts from uniforms — that is what a random number generator emits. The inverse transform method converts them into any distribution with a computable quantile function: if and is a CDF with generalised inverse , then has CDF .

Proof — via the probability integral transform

For any , the event is exactly : if then is in the set whose infimum defines , so ; conversely implies by right-continuity and monotonicity of . Hence

since . This is the same probability integral transform proved in order statistics — there it turned data into uniforms (p-values); here it runs in reverse, turning uniforms into data.

Worked example — exponential. For , solve to get , and since , the one-liner is . Concretely with : ; . The method also covers discrete distributions (step through cumulative probabilities until they exceed ) — which is the honest answer to the classic exercise “simulate from an arbitrary CDF.”

A CDF curve with uniform draws on the vertical axis mapped through the inverse CDF to samples on the horizontal axis, next to the resulting histogram matching the target density
Inverse transform sampling: uniform draws on the vertical axis are pushed through the quantile function F^{-1} to the horizontal axis. Dense regions of the target density correspond to steep stretches of F, so equal slices of u land more points there — the histogram of the mapped samples reproduces the target.

Acceptance–rejection#

When is unavailable but the density is computable, sample from an easy proposal density dominating : choose with for all , then repeat: draw and , and accept if .

Proof sketch — accepted draws have density f, and efficiency is 1/M

The joint chance of proposing near and accepting is . Integrating over , the overall acceptance probability is . By Bayes, the density of given acceptance is

Exactly the target — and the number of proposals per accepted sample is geometric with mean . So the whole game is finding a proposal that hugs tightly: close to 1 means almost nothing is wasted. Worked numbers: to sample , , from a uniform proposal : the max of is , so and you accept of proposals — three draws for every two samples. In high dimensions typically blows up exponentially, which is why rejection is a low-dimensional tool.

Box–Muller and Cholesky: manufacturing normals#

The normal CDF has no closed-form inverse, so normals get their own trick. Box–Muller: from two independent uniforms ,

are independent standard normals.

Proof sketch — Box–Muller via polar coordinates

Write a standard normal pair in polar form, . The joint density is rotationally symmetric, so independently of , and the squared radius satisfies

(the chi-square with 2 df from the distribution zoo). Both ingredients are inverse-transform-easy: and . Substituting back gives the formulas. Note the trap this exposes: to get a uniform point on a circle, take — but a uniform point in a disk needs , not , because area grows like .

Correlated normals via Cholesky. Portfolios need normals with a prescribed covariance . Factor (lower-triangular , which exists because covariance matrices are PSD — see joint distributions) and set for iid standard normals . Then , and is normal because linear combinations of normals are normal. In the correlation case the factorisation is worth memorising: solving

Check it: and . With : — the triangle of correlated simulation. This one line is the seed of every correlated-asset simulator, and the regression-line structure it encodes is exactly the bivariate-normal conditional expectation derived in chapter 5.

Importance sampling: buying variance with bias-free money#

The naive estimator fails exactly where finance cares most: rare events. To estimate for , naive sampling waits ~31,600 draws per hit. Importance sampling samples where the action is and reweights. For any proposal density that is positive wherever ,

so the weighted average with likelihood ratio is unbiased — that one-line change of measure is the whole proof. The art is choosing to shrink the variance of ; the theoretical optimum achieves zero variance for one-signed but requires knowing — so in practice you tilt toward it.

Worked example — the tail probability, tilted. Shift the sampling distribution to , centred on the rare region. The weight is , and now roughly half the draws land in instead of one in 31,600. The variance collapses by a factor of several thousand — the simulation below measures a standard error roughly 80 times smaller, i.e. about fewer paths for the same accuracy. This is how desks compute deep-tail VaR, CVA, and far-out-of-the-money option prices (extreme value theory is the model-based complement).

A standard normal density with its far right tail highlighted, a shifted proposal density centred on the tail, and a comparison of estimator error bars showing the importance sampling estimate far tighter than the naive one
Importance sampling for P(Z > 4). The naive sampler (left density) almost never visits the tail; the tilted proposal (shifted density) lands half its draws there, and the likelihood-ratio weights e^{-4y+8} undo the tilt exactly. Same unbiased target, orders of magnitude less variance.
!The wrong-proposal danger — weights with infinite variance
Unbiasedness holds for any valid proposal; efficiency does not. If has thinner tails than , the weight explodes on rare draws: the estimator stays unbiased but its variance can be infinite — the average looks stable for thousands of draws, then one astronomical weight rewrites it. Symptom: a handful of samples carry almost all the total weight (tiny effective sample size). Rule: the proposal must dominate the target in the tails — tilt with fatter or shifted tails, never thinner. This is the simulation-side twin of the fat-tail traps in LLN & CLT.
mc_tail_probability.py
import math
import numpy as np

rng = np.random.default_rng(11)
n = 100_000
truth = 0.5 * math.erfc(4.0 / math.sqrt(2))   # P(Z > 4) = 3.167e-05

# Naive Monte Carlo: indicator of a rare event
z = rng.standard_normal(n)
naive = (z > 4.0).astype(float)

# Importance sampling: draw from N(4, 1), reweight by f/q = exp(-4y + 8)
y = rng.standard_normal(n) + 4.0
weighted = (y > 4.0) * np.exp(-4.0 * y + 8.0)

for name, s in [("naive", naive), ("importance", weighted)]:
    est, se = s.mean(), s.std(ddof=1) / np.sqrt(n)
    print(f"{name:>10}: {est:.3e} +/- {se:.1e}   (truth {truth:.3e})")
# naive     : 3.00e-05 +/- 1.7e-05  -- error the size of the answer
# importance: 3.17e-05 +/- 2.1e-07  -- ~80x smaller se => ~6,500x fewer paths

Variance reduction and the wider toolkit#

Importance sampling is one member of a family, all attacking rather than — the mechanics are developed in numerical methods:

  • Antithetic variates: pair each path driven by with its mirror ; for monotone payoffs the pair’s errors negatively correlate and partly cancel.
  • Control variates: simulate alongside a correlated quantity with knownmean (e.g. price an Asian option using the geometric-average Asian, which has a closed form, as control) and subtract the control’s error: .
  • Stratification: force the samples to cover the space evenly (fixed counts per stratum), removing between-stratum randomness.
  • Quasi-Monte Carlo: replace random draws with low-discrepancy sequences (Sobol); error decays near rather than in moderate dimension — standard in production option pricers.
Quant lens — pricing and Greeks by simulation
A derivatives desk prices by simulating risk-neutral GBM paths (stochastic processes, options & Greeks): discount the average payoff, . Greeks are where method choice bites. The bump-and-reprice estimate is noisy unless both runs reuse the same random numbers (common random numbers — the difference of two independent noisy estimates has their variances added). The pathwise estimator differentiates the payoff along each path, — one run, no bump bias, but it needs an almost-everywhere differentiable payoff (fails for digitals, where the likelihood-ratio method takes over).

Practice problems#

Problem 1 — Simulate from an arbitrary CDF

You have a uniform random generator and a CDF (possibly with jumps and flat stretches). Produce samples with distribution .

Solution. Return . The generalised inverse handles both pathologies: a jump of at (an atom) means a whole interval of maps to , reproducing the point mass ; a flat stretch (a gap in the support) is skipped because the infimum jumps across it. Proof of correctness is the equivalence , so . For a discrete list of probabilities, this is “walk the cumulative sums until they exceed ” — say that in one breath and you have answered both the continuous and discrete versions.

Problem 2 — Estimate P(Z > 4) efficiently

Estimate for standard normal by simulation. Why is the naive approach hopeless, and what do you do instead?

Solution. The truth is . Naive MC averages a Bernoulli() indicator, so its relative standard error is : for 10% relative accuracy you need , i.e. draws — and a 20-sigma event would need more paths than atoms in reasonable computers. Instead sample and average : unbiased by the change-of-measure identity, and now half the draws hit the region. The weight formula is just the ratio of normal densities: . Mentioning that the proposal must dominate the target’s tail — never tilt to a thinner-tailed proposal — is what separates a memorised answer from an understood one.

Problem 3 — Generate a correlated pair

From iid standard normals , construct standard normal with correlation . Then: simulate two asset returns with vols and correlation .

Solution. — the 2×2 Cholesky factor of the correlation matrix. Verify in two lines: , . For returns, scale: . The standard escalation — “now do 3 assets” — wants the general answer: Cholesky-factor and set ; and the trap to flag is that a hand-built “correlation matrix” can fail to be PSD (e.g. three pairwise correlations of are impossible), in which case Cholesky fails — correctly.

Problem 4 — The π-estimator sample-size budget

You estimate by throwing uniform darts at the unit square and counting hits inside the quarter circle. How many darts for a standard error of ?

Solution. The hit indicator is Bernoulli with , so . Setting gives . The instructive follow-up: each extra decimal digit multiplies by 100 (the law), so Monte Carlo is the wrong tool for computing to ten digits but the right tool for a 100-dimensional integral — the error rate never sees the dimension.

Problem 5 — Uniform points on a circle and a sphere

How do you draw a uniform point (a) on the unit circle’s boundary, (b) inside the disk, (c) on the surface of the unit sphere? Where do naive answers go wrong?

Solution. (a) , point . (b) The trap: taking radius over-weights the centre, because the area inside radius grows like . Uniformity needs , so by inverse transform . (c) The trap: uniform latitude/longitude bunches points at the poles. Clean answers: draw iid normal and return — rotational symmetry of the Gaussian (the same fact behind Box–Muller) makes the direction exactly uniform in any dimension. Or rejection: sample the cube, keep points with , normalise — but note the acceptance rate ( in 3D) collapses exponentially with dimension, so the Gaussian trick is the one that scales.

Next: the mathematics is complete — now train it under fire. A playbook for attacking any probability problem on sight, the canonical constants, and a mixed problem gauntlet spanning the whole series: Problem-solving drills.