Why Monte Carlo?
Monte Carlo simulation is the Swiss Army knife of quantitative finance. When analytical solutions don’t exist, we simulate: generate thousands of possible future price paths, price the derivative on each path, then average and discount.
The method is named after the Monaco casino — a nod to randomness. But there’s nothing gambling about it when done correctly.
Simulating Asset Prices with GBM
The geometric Brownian motion (GBM) model is the starting point:
St+Δt=Stexp((μ−σ22)Δt+σΔt Z) S_{t+\Delta t} = S_t \exp\left(\left(\mu – \frac{\sigma^2}{2}\right)\Delta t + \sigma \sqrt{\Delta t} \, Z\right)
Where:
-
StS_t
is the current stock price -
μ\mu
is the drift (expected return) -
σ\sigma
is the volatility -
Z∼N(0,1)Z \sim N(0,1)
is a standard normal random variable
This comes from discretizing the GBM stochastic differential equation:
dS=μS dt+σS dWt dS = \mu S \, dt + \sigma S \, dW_t
Python: Building a Monte Carlo Pricer
import numpy as np
def monte_carlo_call(S0, K, T, r, sigma, n_sims=100000, n_steps=252):
"""Price a European call option via Monte Carlo."""
dt = T / n_steps
Z = np.random.standard_normal((n_sims, n_steps))
drift = (r - 0.5 * sigma**2) * dt
diffusion = sigma * np.sqrt(dt) * Z
terminal_prices = S0 * np.exp(np.sum(drift + diffusion, axis=1))
payoffs = np.maximum(terminal_prices - K, 0)
call_price = np.exp(-r * T) * np.mean(payoffs)
std_error = np.exp(-r * T) * np.std(payoffs) / np.sqrt(n_sims)
return call_price, std_error
# Example: 1-year ATM call
price, se = monte_carlo_call(S0=100, K=100, T=1.0, r=0.05, sigma=0.20)
print(f"Price: {price:.4f}, 95% CI: [{price-1.96*se:.4f}, {price+1.96*se:.4f}]")
Enter fullscreen mode Exit fullscreen mode
Variance Reduction
Raw Monte Carlo converges at
O(1/N)O(1/\sqrt{N})
— to halve the error, you need 4x simulations. Variance reduction helps:
Antithetic Variates
For every path
ZZ
, also simulate
−Z-Z
. This halves variance at zero extra cost:
Z_anti = -Z # Flip the sign
Z_all = np.vstack([Z, Z_anti])
Enter fullscreen mode Exit fullscreen mode
Control Variates
Use Black-Scholes (which has a closed form) as a control to reduce variance of your Monte Carlo estimate.
Multi-Asset Simulations
For basket options or portfolio derivatives, use Cholesky decomposition to generate correlated paths:
L = np.linalg.cholesky(corr_matrix)
Z = np.random.standard_normal((n_sims, n_steps, n_assets))
corr_Z = Z @ L.T # Correlated random draws
Enter fullscreen mode Exit fullscreen mode
Interview Essentials
Q: Why not just use Black-Scholes?
Black-Scholes only works for vanilla European options. Most real derivatives — path-dependent, American, basket — don’t have analytic solutions. Monte Carlo handles all of them.
Q: How do you price American options with Monte Carlo?
Use the Longstaff-Schwartz least-squares method. At each exercise date, regress future payoffs on current state variables to estimate continuation value.
Q: What are the convergence properties?
Standard error decreases as
1/N1/\sqrt{N}
. To get one more decimal digit, you need 100x more simulations. This is why variance reduction matters.
Summary
Technique Best For Complexity Raw MC Vanilla European Low Antithetic Variates Any path Low Control Variates Known analytic benchmark Medium Importance Sampling Deep OTM options High Quasi-MC (Sobol) Low-dimensional MediumMonte Carlo is not the fastest, but it’s the most flexible. When in doubt, simulate.
Ready to go deeper? Check out Desk2Quant for hands-on practice with derivatives pricing, portfolio optimization, and quant interview prep.
답글 남기기