This project implements and benchmarks several methods for pricing American options, centred on the Longstaff-Schwartz Least-Squares Monte Carlo (LSM) algorithm. It covers GBM and Heston stochastic-volatility path simulation, a Crank-Nicolson finite-difference benchmark, antithetic and control-variate variance reduction, and a full convergence analysis of the LSM estimator.
- Longstaff-Schwartz LSM with weighted Laguerre polynomial basis (Longstaff & Schwartz 2001)
- GBM paths — exact log-normal discretisation, no Euler error
- Heston stochastic volatility — full-truncation Euler scheme (Lord, Koekkoek & Van Dijk 2010)
- Crank-Nicolson finite difference — tridiagonal PDE solver, O(n) per step, used as benchmark
- Antithetic variates — mirrored normal increments; empirically ~3x variance reduction for ATM puts
- European-put control variate — optimal BS-European adjustment; empirically ~2–3x variance reduction
| Method | Price | Uncertainty |
|---|---|---|
| LSM (100k paths) | 6.0429 | ±0.0225 (1 SE) |
| Crank-Nicolson | 6.0880 | — |
The two methods agree to within 0.05, well within two standard errors of the LSM estimate.
| Method | Empirical VRF |
|---|---|
| Antithetic variates | ~3x |
| Control variate | ~2x |
VRF = (plain variance) / (reduced variance) — how many times fewer paths achieve the same precision.
LSM price error decays as 1/√n with respect to path count, consistent with standard Monte Carlo theory. The price stabilises at ~20 time steps; higher polynomial degrees (>3) show no improvement over the paper's default.
american-option-pricing/
├── src/
│ ├── models/
│ │ ├── gbm.py # GBM path simulator (exact log-Euler)
│ │ └── heston.py # Heston path simulator (full-truncation Euler)
│ ├── pricing/
│ │ ├── longstaff_schwartz.py # LSM backward-induction pricer
│ │ ├── finite_difference.py # Crank-Nicolson PDE solver
│ │ └── payoffs.py # American put/call payoff factories
│ ├── variance_reduction/
│ │ ├── antithetic.py # Antithetic variates wrapper for LSM
│ │ └── control_variate.py # European-put control variate for LSM
│ └── analysis/
│ ├── convergence.py # Convergence experiment functions
│ └── plots.py # Figure functions
├── tests/
│ ├── test_gbm.py
│ ├── test_lsm.py
│ ├── test_benchmarks.py
│ └── test_variance_reduction.py
├── config/
│ └── params.yaml # Shared model parameters
└── requirements.txt
Install dependencies:
pip install -r requirements.txtRun all tests:
pytest tests/Launch notebooks:
jupyter notebook notebooks/Quick code snippet:
from src.models.gbm import simulate_paths
from src.pricing.longstaff_schwartz import lsm_price
from src.pricing.payoffs import american_put_payoff
paths = simulate_paths(S0=100, r=0.05, sigma=0.2, T=1, n_steps=50, n_paths=100_000, seed=42)
result = lsm_price(paths, american_put_payoff(K=100), r=0.05, dt=1/50)
print(result["price"], result["se"])- LSM low bias — backward-induction regression underestimates the continuation value, producing a slightly low price estimate. See Broadie & Glasserman (2004) for the upper-bound dual.
- No Heston closed-form benchmark — the Heston American option has no analytic price; the GBM comparison in notebook 03 is a consistency check, not a validation.
- Uniform S grid in Crank-Nicolson — a log-S grid would give better accuracy near the strike with fewer nodes.
- LSM exercise boundary — the boundary extracted from regression is an approximation; the true critical S* requires solving C(S*) = h(S*) from the regression coefficients.
- Longstaff, F. A. & Schwartz, E. S. (2001). Valuing American Options by Simulation: A Simple Least-Squares Approach. Review of Financial Studies, 14(1), 113–147.
- Broadie, M. & Glasserman, P. (2004). A Stochastic Mesh Method for Pricing High-Dimensional American Options. Journal of Computational Finance, 7(4), 35–72.