Lesson 8.1: Monte Carlo, variance reduction and path-dependent options
Learn Monte Carlo pricing: how error shrinks with paths, variance reduction, Asian and barrier options, and Greeks by simulation.
By the end of this lesson you will be able to price an option by simulation under the risk-neutral measure, work out the standard error of the estimate and how many paths a target accuracy needs, cut that error with antithetic and control variates, price Asian and barrier options that depend on the path, see why monitoring frequency changes a barrier price, and estimate a delta by simulation without the noise swamping the answer. You will show that the standard error of a six-month call falls from 0.301 with 1,000 paths to 0.0099 with a million, that a control variate cuts the variance of an arithmetic Asian option estimate by a factor of about 2,700 so that the standard error falls from 0.0175 to 0.00034, that an up-and-out call is worth 3.62 if the barrier is checked once and 2.36 if it is checked 504 times, and that a bump-and-reprice delta is 25 times noisier when the two prices use different random numbers. You should have read Lessons 6.2, 7.2 and 7.3. The mathematics is expectations, standard errors and correlation. This course is education about how markets and research work, not investment advice.
Module 7 gave the theory: the price of a derivative is the discounted expectation of its payoff under the risk-neutral measure. Module 8 turns to the numerical methods that compute that expectation when there is no formula. The first and most flexible is Monte Carlo simulation. It is named after the casino, since it uses random numbers, and it has one great advantage over trees and grids: its cost grows slowly with the complexity of the problem. An option on a basket of twenty shares, or one whose payoff depends on the whole path of the price, is as easy to simulate as a plain call. It also has a disadvantage: it is slow to converge, so a lot of the skill in using it is in making it faster.
The method
To price a derivative with payoff V at time T:
1. Simulate a path of the underlying under the risk-neutral measure, with drift equal to the risk-free rate r (Lesson 7.3). For a share, the exact step of Lesson 7.2 is S{t+Δt} = St exp((r − σ²/2)Δt + σ√Δt Z), with Z a standard normal draw.
2. Compute the payoff V on that path and discount it: e^(−rT) V.
3. Repeat N times and take the average.
The average is an estimate of the price, by the law of large numbers. Its error follows from the central limit theorem: the standard deviation of the estimate, called the standard error, is
SE = s ÷ √N
where s is the standard deviation of the discounted payoff across paths. An approximate 95 per cent confidence interval is the estimate ± 1.96 × SE.
Worked example 1. The six-month at-the-money call of Lesson 6.2: S = K = 100, r = 6 per cent, σ = 20 per cent, T = 0.5, whose exact price is 7.1559. The discounted payoff has a standard deviation of s = 9.94: the payoff is zero on many paths and large on a few, so it is very variable. Using the first N of the same stream of random numbers:
Paths N · Estimate · Standard error · Error against the exact price1,000 · 6.585 · 0.301 · −0.571
10,000 · 7.057 · 0.099 · −0.099
100,000 · 7.092 · 0.031 · −0.064
1,000,000 · 7.140 · 0.0099 · −0.016
Each error is about one or two standard errors, as the theory says. The slow part is the rate: because the error shrinks like 1 ÷ √N, a tenfold increase in paths gains only a factor of 3.2 in accuracy, and to cut the error by a factor of 10 you need 100 times as many paths. To get a price accurate to ±0.01 at 95 per cent confidence, you need N = (1.96 × 9.94 ÷ 0.01)² ≈ 3.8 million paths.
Use your own numbers below to see how many paths a target accuracy needs.
Variance reduction
Since the cost of accuracy is steep, it pays to reduce s, the variability of what you average. The main ideas:
Antithetic variates
For every path built from a set of normal draws Z, also build the path from −Z. The two payoffs are negatively correlated, since one is high when the other is low, so their average has a smaller variance than the average of two independent ones. The cost is almost nothing: the draws are reused.
Control variates
Suppose X is the payoff you want to estimate, and Y is another quantity computed from the same paths whose expected value is known exactly. For a call, take the discounted final share price, whose expectation under the risk-neutral measure is exactly S₀. Then the estimator
X − b × (Y − E[Y]), with b = Cov(X, Y) ÷ Var(Y)
has the same expected value as X, since the correction term has mean zero, but its variance is smaller by the factor (1 − ρ²), where ρ is the correlation between X and Y. The correlation of a call's payoff with the share price is 0.91, which gives a variance reduction of 1 ÷ (1 − 0.83) = 6. The idea is to remove from the estimate the part of its noise that the control explains. The better the control matches the payoff, the greater the gain.
Other methods
Quasi-random numbers. Instead of random draws, use a low-discrepancy sequence, such as a Sobol sequence, that fills the space more evenly. The error can fall nearly as 1 ÷ N for suitable problems.
Stratified sampling and importance sampling. Draw more paths from the region that matters most, such as the tail for an option far out of the money, and correct with weights.
Worked example 2. We estimated the call price with N = 100,000 paths and repeated the whole experiment 200 times, to measure the spread of the estimates directly:
Method · Standard deviation of the estimate · Variance reduction compared with plainPlain Monte Carlo · 0.0318 · 1
Antithetic variates · 0.0166 · 3.7
Control variate (the share price) · 0.0138 · 5.3
Antithetic plus control variate · 0.0046 · 47
All four are accurate on average: their means are 7.156 to 7.157, against the exact 7.1559. But the combination has a standard error of 0.0046 from the same 100,000 paths, which plain Monte Carlo would need about 4.7 million paths to achieve. The savings multiply, because the two ideas remove different parts of the noise.
How good could a control be? See how the correlation drives the gain.
Path-dependent options
The strength of Monte Carlo is that it simulates the whole path, so it can price payoffs that depend on how the price got there. The only change is to step through time, from 0 to T in n steps, and compute the payoff from the full path.
Asian options
An Asian option pays on the average price over a period, not the final price. A call pays max(average − K, 0). Averaging smooths out the noise, so it is cheaper than a European option, and harder to manipulate near expiry. Companies with regular exposure to a commodity or a currency often use them.
There is no formula for the arithmetic average, but there is one for the geometric average, since the product of lognormal prices is lognormal. The geometric Asian price is an ideal control variate: it is nearly perfectly correlated with the arithmetic one, and its price is known exactly.
Worked example 3. An arithmetic Asian call on the share of Lesson 6.2: strike 100, six months, averaged over 126 daily fixings.
Plain Monte Carlo with 100,000 paths: 4.024, with a standard error of 0.0175.
With the geometric Asian as control variate, using its exact value of 3.9005: 4.0055, with a standard error of 0.00034.
The correlation between the two payoffs is 0.9998, so the variance falls by a factor of 1 ÷ (1 − 0.9998²) ≈ 2,700 and the standard error by about 52. The plain estimate was 0.019 too high, which is about one standard error, while the control-variate estimate pins the price down to a third of a hundredth of a rupee. The Asian call is worth 4.01, well below the 7.16 of the European call, because averaging halves the volatility the option feels.
Barrier options
A barrier option is cancelled, or created, if the price touches a level. An up-and-out call pays like an ordinary call unless the price touches a barrier above the current price, in which case it is cancelled. A barrier option is cheaper than the plain option, because some paths that would have paid are knocked out.
The detail that matters is how often the barrier is monitored. In a contract that checks the price only at certain times, such as the daily close, a path can cross the barrier between observations without effect. The continuous-monitoring price, which has a formula, is lower. We priced an up-and-out call with a barrier of 120 on the same share, for different numbers of monitoring dates in six months:
Monitoring dates · Price · Standard error1 (at expiry only) · 3.62 · 0.012
4 · 3.22 · 0.012
26 (weekly) · 2.69 · 0.010
126 (daily) · 2.46 · 0.010
504 · 2.36 · 0.010
The price falls from 3.62 to 2.36 as monitoring gets more frequent, because more crossings are detected. Any pricing model must match the contract's monitoring, and a model that assumes continuous monitoring when the contract uses daily closes will misprice by about 0.1 on this option, around 4 per cent. The mid-point of a Brownian path is also easy to miss in a simulation with few steps, the same effect as the reflection principle of Lesson 7.1: with too few steps, you will find the barrier touched too rarely.
Greeks by simulation
The Greeks matter as much as the price, and simulation can give them in three main ways.
Bump and revalue. Price the option at S₀ + h and at S₀ − h, and take the difference divided by 2h. The important point is to use the same random numbers for both prices ("common random numbers"). The noise is then nearly the same in both and cancels in the difference. With independent random numbers the noise adds up and swamps the small difference. In our test with a million paths, the delta by bumping with common random numbers was 0.6114 ± 0.0005, against the exact 0.6114. With independent random numbers, it was 0.6239 ± 0.0140, 25 times noisier, and wrong by nearly one standard error.
Pathwise method. Differentiate the payoff along each path: for a call, the derivative with respect to S₀ of e^(−rT) max(ST − K, 0) is e^(−rT) × 1{ST > K} × ST ÷ S₀. Averaging that gives the delta directly, 0.6114 ± 0.0006, with no bump size to choose. It needs a payoff that is smooth enough to differentiate.
Likelihood-ratio method. Differentiate the probability density of the paths and not the payoff. It works for discontinuous payoffs, such as a digital option, at the price of larger variance.
American options by simulation
An American option needs an exercise decision at each date, which depends on the future, and that seems to make it unsuited to forward simulation. The Longstaff–Schwartz method of 2001 solves it by working backwards through the simulated paths. At each exercise date, it regresses the discounted future cash flows on a few functions of the current price, using only the paths that are in the money, to estimate the continuation value. It then exercises on the paths where the intrinsic value exceeds that estimate. It is the standard method for American options on many underlyings or with complex dynamics, where trees and grids are impractical.
Practical points
Use the exact step when one exists. For geometric Brownian motion the exact lognormal step has no discretisation error. For models without one, such as stochastic volatility, the Euler scheme has a bias that shrinks with the step size, so check convergence in both the number of paths and the number of steps.
Report the standard error with every price. A Monte Carlo number without it is not a result.
Fix and record the seed for reproducibility, and test with several seeds.
Test the code against a known answer. Price a plain call and compare with Black–Scholes, and a geometric Asian against its formula.
Watch the memory. A simulation with a million paths and hundreds of steps holds billions of numbers: process the paths in batches.
Choose a variance-reduction technique that fits the problem, and check with a repeated experiment that it helps.
Remember what the simulation prices. It is the expectation under the model you chose, so it carries all the model's assumptions (Lesson 8.4).
The code below prices the call, compares the variance-reduction methods, prices the Asian and barrier options in batches and computes the delta in three ways.
python
import numpy as np
from math import exp, log, sqrt
from scipy.stats import norm
S0, K, r, sigma, T = 100.0, 100.0, 0.06, 0.20, 0.5
def bscall(S, K, r, sig, T):
d1 = (log(S / K) + (r + 0.5 sig 2) T) / (sig sqrt(T))
return S norm.cdf(d1) - K exp(-r T) norm.cdf(d1 - sig sqrt(T))
exact = bscall(S0, K, r, sigma, T)
print("exact", round(exact, 4))
1. plain Monte Carlo and its standard error
rng = np.random.defaultrng(1)
Z = rng.standardnormal(4000000)
ST = S0 np.exp((r - 0.5 sigma 2) T + sigma sqrt(T) Z)
pay = np.maximum(ST - K, 0) exp(-r T)
print("standard deviation of the discounted payoff", round(pay.std(), 3))
for N in (1000, 10000, 100000, 1000000):
p = pay[:N]
print(f" N = {N:>7}: estimate {p.mean():.4f} | standard error {p.std() / sqrt(N):.4f} | error {p.mean() - exact:+.4f}")
2. variance reduction: repeat the experiment 200 times with 100,000 paths each
def estimates(seed, N=100000):
z = np.random.defaultrng(seed).standardnormal(N)
f = lambda zz: np.maximum(S0 np.exp((r - 0.5 sigma 2) T + sigma sqrt(T) zz) - K, 0) exp(-r T)
X = f(z)
plain = X.mean()
X2 = f(-z)
antithetic = (0.5 (X + X2)).mean()
Y = exp(-r T) S0 np.exp((r - 0.5 sigma 2) T + sigma sqrt(T) z) # discounted share price, mean S0
b = np.cov(X, Y)[0, 1] / Y.var()
control = (X - b (Y - S0)).mean()
Y2 = exp(-r T) S0 np.exp((r - 0.5 sigma 2) T - sigma sqrt(T) z)
Xa, Ya = 0.5 (X + X2), 0.5 (Y + Y2)
ba = np.cov(Xa, Ya)[0, 1] / Ya.var()
both = (Xa - ba (Ya - S0)).mean()
return plain, antithetic, control, both
res = np.array([estimates(s) for s in range(200)])
print("spread of the estimate (plain, antithetic, control, both):", np.round(res.std(axis=0), 4))
print("variance reduction against plain:", np.round((res.std(axis=0)[0] / res.std(axis=0)) 2, 1))
3. arithmetic Asian call with daily fixings, and the geometric Asian as a control variate
n = 126
dt = T / n
def asian(seed, N=100000, batch=10000):
rng = np.random.defaultrng(seed)
A, G = [], []
for in range(N // batch):
logS = np.log(S0) + np.cumsum((r - 0.5 sigma 2) dt + sigma sqrt(dt) rng.standardnormal((batch, n)), axis=1)
A.append(np.exp(logS).mean(axis=1))
G.append(np.exp(logS.mean(axis=1)))
A, G = np.concatenate(A), np.concatenate(G)
return np.maximum(A - K, 0) exp(-r T), np.maximum(G - K, 0) exp(-r T)
mug = log(S0) + (r - 0.5 sigma 2) dt (n + 1) / 2
varg = sigma 2 dt (n + 1) (2 n + 1) / (6 n)
d1 = (mug - log(K) + varg) / sqrt(varg)
geometric = exp(-r T) (exp(mug + 0.5 varg) norm.cdf(d1) - K norm.cdf(d1 - sqrt(varg)))
payA, payG = asian(2)
b = np.cov(payA, payG)[0, 1] / payG.var()
adj = payA - b (payG - geometric)
print("geometric Asian (exact)", round(geometric, 4), "| arithmetic plain", round(payA.mean(), 4), "SE", round(payA.std() / sqrt(len(payA)), 5),
"| with control", round(adj.mean(), 4), "SE", round(adj.std() / sqrt(len(adj)), 5), "| correlation", round(np.corrcoef(payA, payG)[0, 1], 4))
4. up-and-out call, barrier 120, by monitoring frequency
def upandout(seed, steps, N=200000, B=120.0, batch=10000):
rng = np.random.defaultrng(seed)
dt = T / steps
pays = []
for in range(N // batch):
S = np.exp(np.log(S0) + np.cumsum((r - 0.5 sigma 2) dt + sigma sqrt(dt) rng.standardnormal((batch, steps)), axis=1))
pays.append(np.maximum(S[:, -1] - K, 0) (S.max(axis=1) < B) exp(-r T))
pays = np.concatenate(pays)
return pays.mean(), pays.std() / sqrt(len(pays))
for steps in (1, 4, 26, 126, 504):
price, se = upandout(3, steps)
print(f" monitoring dates {steps:>3}: price {price:.3f} (standard error {se:.3f})")
5. delta three ways, with a million paths
rng = np.random.defaultrng(9)
Z = rng.standardnormal(1000000)
growth = np.exp((r - 0.5 sigma 2) T + sigma sqrt(T) Z)
pathwise = exp(-r T) (S0 growth > K) growth
priceof = lambda s0, z: np.maximum(s0 np.exp((r - 0.5 sigma 2) T + sigma sqrt(T) z) - K, 0) exp(-r T)
h = 0.5
common = (priceof(S0 + h, Z) - priceof(S0 - h, Z)) / (2 h)
Z2 = np.random.defaultrng(10).standardnormal(1000000)
independent = (priceof(S0 + h, Z) - priceof(S0 - h, Z2)) / (2 h)
exactdelta = norm.cdf((log(S0 / K) + (r + 0.5 sigma 2) T) / (sigma sqrt(T)))
print("delta: exact", round(exactdelta, 4), "| pathwise", round(pathwise.mean(), 4), "+/-", round(pathwise.std() / 1000, 4),
"| bump with common random numbers", round(common.mean(), 4), "+/-", round(common.std() / 1000, 4),
"| bump with independent random numbers", round(independent.mean(), 4), "+/-", round(independent.std() / 1000, 4))
Common mistakes
Quoting a price without its standard error. A simulation is an estimate, and the error is part of the answer.
Expecting fast convergence. The error falls as 1 ÷ √N, so tenfold accuracy needs a hundredfold more paths.
Simulating under the real-world measure. For pricing, the drift must be r, not μ (Lesson 7.3).
Using a bump with independent random numbers. The noise is of the order of the signal, and the Greek is useless.
Choosing a bump size without checking. Too large a bump adds bias, and too small a bump adds noise.
Ignoring the monitoring frequency of a barrier. A model with continuous monitoring misprices a contract that checks daily.
Using too few time steps for a path-dependent payoff or a model without an exact step. There is a discretisation bias that more paths cannot fix.
Using a control variate that is poorly correlated. It adds complexity and gains little.
Not testing against a known answer. A bug in the simulator is easy to miss otherwise.
Running out of memory. Process paths in batches.
Key takeaways
Monte Carlo prices a derivative by simulating paths under the risk-neutral measure, discounting each payoff and averaging. The standard error is s ÷ √N, so ten times the accuracy needs a hundred times the paths.
For the six-month call the standard error is 0.301 with 1,000 paths and 0.0099 with a million. About 3.8 million paths give ±0.01 at 95 per cent confidence.
Antithetic variates (reusing −Z) and control variates (a quantity with a known mean) reduce the variance, the latter by a factor 1 ÷ (1 − ρ²). Together they cut the call's variance by about 47 times.
Monte Carlo handles path-dependent payoffs. An arithmetic Asian call is worth 4.01, far below the 7.16 European call. Using the geometric Asian as a control (correlation 0.9998) cut the standard error from 0.0175 to 0.00034.
A barrier price depends on the monitoring frequency: the up-and-out call falls from 3.62 with one check to 2.36 with 504 checks.
Greeks can be computed by bumping with common random numbers (0.6114 ± 0.0005), by the pathwise method, or by likelihood ratios. Independent random numbers made the bump delta 25 times noisier.
The Longstaff–Schwartz regression method prices American options by simulation.
Report the standard error, use exact steps where possible, check discretisation, fix the seed and test against known prices.
Check yourself
1. A Monte Carlo price has a standard error of 0.20 with 10,000 paths. How many paths give a standard error of 0.02?
The error falls as 1 ÷ √N, so a tenfold reduction needs 100 times the paths: 1,000,000.
2. A control variate has a correlation of 0.95 with the payoff. By what factor does the variance fall, and the standard error?
The variance falls by 1 ÷ (1 − 0.9025) = 10.3, and the standard error by √10.3 = 3.2.
3. Why do antithetic paths reduce variance for a call?
The payoff of a call rises with Z, so the payoffs from Z and −Z are negatively correlated. The average of two negatively correlated numbers has a smaller variance than the average of two independent ones.
4. A simulation prices a daily-monitored down-and-out put using a continuous-monitoring formula. Is the formula price above or below the daily-monitored price?
Continuous monitoring catches more crossings and knocks out more paths, so a knock-out option is cheaper under continuous monitoring. The formula price is below the daily-monitored price.
5. You compute a delta by bumping the spot up and down by 0.5 and repricing with new random numbers each time. The result is noisy. What is the fix?
Use the same random numbers for the up and the down bumps, so that the noise cancels in the difference.
Try this
Set aside forty-five minutes. You need Python and the code of this lesson.
1. Run the code. Check the standard errors, the variance-reduction table, the Asian prices and the monitoring table.
2. Change the number of paths from 100,000 to 400,000 and confirm that the standard error halves.
3. Price an arithmetic Asian put with the same method. Does the geometric Asian put make a good control?
4. Add a lower barrier of 80, giving a double knock-out call. How does the price change with the monitoring frequency?
5. Compute the delta of the Asian call by bumping with common random numbers. Compare it with the delta of the European call.
6. Use the paths simulator to find the number of paths needed for ±0.005 on your payoff.
7. Write a short note: how you would price a basket option on five shares, which variance-reduction method you would try first and how you would test the code.
A good result is a price with a stated standard error, a variance-reduction table whose gain you can explain and a Greek whose noise you have controlled. The next lesson turns to the other main numerical method, finite differences, which solves the pricing equation on a grid.
Read more
Paul Glasserman's Monte Carlo Methods in Financial Engineering is the standard text and covers variance reduction, Greeks and American options in depth. Francis Longstaff and Eduardo Schwartz's 2001 paper "Valuing American Options by Simulation: A Simple Least-Squares Approach" in the Review of Financial Studies introduced the regression method. Phelim Boyle's 1977 paper "Options: A Monte Carlo Approach" in the Journal of Financial Economics was the first use of simulation for option pricing. Mark Broadie and Paul Glasserman's papers on estimating security price derivatives with simulation develop the pathwise and likelihood-ratio methods, and Peter Jäckel's Monte Carlo Methods in Finance is a practitioner's guide to low-discrepancy sequences and implementation.
Tags: Quant Trader Monte Carlo Variance reduction Asian options Barrier options