Integral Calculus and Differential Equations › Numerical Integration Methods
Quantitative FinanceAll chapters Integral Calculus and Differential Equations › Numerical Integration MethodsOne section · Sections in this chapter10 / 14 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Many complex, path-dependent, or high-dimensional pricing and risk problems require numerical integration or simulation because a convenient closed form is unavailable. The appropriate method depends on the payoff, state dimension, model dynamics, and accuracy target.
Quadrature Methods
Numerical integration approximates definite integrals using weighted sums of function values.
where:
- : integration bounds
- : the function being integrated
- : number of evaluation points
- : nodes (evaluation points) within
- : weights determining the contribution of each function value
The idea is to sample the function at carefully chosen points and combine these samples with appropriate weights. Different methods choose different nodes and weights :
- The displayed composite trapezoidal rule uses equally spaced nodes and piecewise-linear interpolation; supplied coordinates also allow nonuniform nodes.
- Simpson's rule uses quadratic interpolation over pairs of subintervals.
- Gaussian quadrature chooses nodes and weights so that an -node rule integrates polynomials through degree exactly under its specified weight function.
import numpy as np
from scipy import integrate
# Compare integration methods on the same truncated lognormal expectation
def option_density(s, S0=100, r=0.05, sigma=0.2, T=1):
"""Log-normal density for stock price under GBM."""
if s <= 0:
return 0
mu = np.log(S0) + (r - 0.5 * sigma**2) * T
var = sigma**2 * T
return np.exp(-((np.log(s) - mu) ** 2) / (2 * var)) / (s * np.sqrt(2 * np.pi * var))
# All numerical methods integrate over [0, upper_bound]. The analytic benchmark
# is the untruncated GBM expectation, so reported errors also include the tiny
# omitted tail beyond the upper bound.
S0, r, T = 100, 0.05, 1
upper_bound = 500.0
analytical_expected = S0 * np.exp(r * T)
def expectation_integrand(s):
return s * option_density(s)
n_grid = 4001
grid = np.linspace(0, upper_bound, n_grid)
grid_values = np.array([expectation_integrand(s) for s in grid])
trapezoid_estimate = np.trapezoid(grid_values, grid)
simpson_estimate = integrate.simpson(grid_values, x=grid)
n_gauss = 64
gauss_nodes, gauss_weights = np.polynomial.legendre.leggauss(n_gauss)
mapped_nodes = 0.5 * upper_bound * (gauss_nodes + 1)
gauss_estimate = (
0.5
* upper_bound
* np.sum(gauss_weights * np.array([expectation_integrand(s) for s in mapped_nodes]))
)
adaptive_estimate, adaptive_error, adaptive_info = integrate.quad(
expectation_integrand, 0, upper_bound, full_output=True
)
quadrature_results = [
("Trapezoid", trapezoid_estimate, n_grid),
("Simpson", simpson_estimate, n_grid),
("Gauss-Legendre", gauss_estimate, n_gauss),
("Adaptive quad", adaptive_estimate, adaptive_info["neval"]),
]Expected stock price integrated on [0, 500] Analytic untruncated benchmark: $105.12710964 Method Estimate Abs. error Evaluations -------------------------------------------------------------- Trapezoid $105.12710964 $ 6.395e-13 4001 Simpson $105.12710964 $ 6.537e-13 4001 Gauss-Legendre $105.12710964 $ 6.963e-13 64 Adaptive quad $105.12710964 $ 6.679e-13 147 Adaptive quad error estimate on the truncated integral: 2.66e-07
Monte Carlo Integration
For high-dimensional integrals involving multiple assets or path-dependent options, Monte Carlo integration is often a practical and scalable approach.
where:
- : the function being integrated (e.g., option payoff)
- : probability density function
- : number of random samples
- : independent random samples drawn from distribution
- : sample average approximating the expected value
Under the Law of Large Numbers conditions, the sample average converges to the expected value. Drawing from represents each region according to its probability mass. Accuracy depends on the variance of , not density alone; for rare but influential tail payoffs, a different sampling density can reduce variance only with the corresponding likelihood-ratio weights and coverage wherever the original weighted payoff is nonzero. Changing the sampling density alone changes the target expectation.
import numpy as np
# Monte Carlo integration for expected call payoff
S0, K, r, sigma, T = 100, 100, 0.05, 0.2, 1
n_simulations = 100000
# Generate log-normal terminal prices
Z = np.random.standard_normal(n_simulations)
ST = S0 * np.exp((r - 0.5 * sigma**2) * T + sigma * np.sqrt(T) * Z)
# Calculate call payoffs and present value
payoffs = np.maximum(ST - K, 0)
mc_price = np.exp(-r * T) * np.mean(payoffs)
mc_std_error = np.exp(-r * T) * np.std(payoffs, ddof=1) / np.sqrt(n_simulations)European Call Option Pricing: Parameters: S0=$100, K=$100, r=5.0%, sigma=20.0%, T=1 year Monte Carlo (100,000 simulations): Price: $10.4739 Std Error: $0.0466 Black-Scholes Analytical: Price: $10.4506 Difference: $0.0233

For independent samples with finite payoff variance, the Monte Carlo sample mean has standard error and, when unbiased, RMSE of the same order. Quadrupling therefore halves those asymptotic measures, not necessarily the realized absolute error in one run. Monte Carlo remains useful for complex and path-dependent payoffs without closed forms.