Longstaff Schwartz Method
February 22, 2025
American options can be exercised before expiration, making their pricing more complex due to the
need for an optimal strategy for determining the point of early exercise. The Longstaff-Schwartz
Method (LSM) efficiently addresses this challenge by combining Monte Carlo simulations with
regression techniques to estimate the continuation value.
1 The Pricing Problem
The value of an American option at time t, denoted Vt , is given by:
Vt = max(It , Ct ),
where:
• It is the intrinsic value (the immediate payoff):
(
max(St − K, 0) (call option)
It =
max(K − St , 0) (put option)
• Ct is the continuation value (the expected discounted future payoff):
Ct = E Vt+1 e−r∆t | Ft .
Here, E denotes the expectation under the risk-neutral measure, r is the risk-free rate, and
∆t is the time step.
2 Stock Price Dynamics
The stock price St is assumed to follow a Geometric Brownian Motion (GBM):
dSt = µSt dt + σSt dWt ,
where:
• µ is the drift rate,
• σ is the volatility,
• dWt is the increment of a Wiener process.
The discrete approximation of St is given by:
σ2 √
St+∆t = St exp µ − ∆t + σ ∆t Z ,
2
where Z ∼ N (0, 1) is a standard normal random variable.
1
3 Estimating the Continuation Value
To approximate Ct , the Longstaff-Schwartz method uses least squares regression. The steps are
as follows:
3.1 Basis Functions
The continuation value is approximated using a set of basis functions ϕi (St ):
k
X
Ct ≈ βi ϕi (St ),
i=1
where βi are regression coefficients, and k is the number of basis functions. The basis functions
are typically chosen to be Laguerre polynomials, which are orthogonal polynomials that work well
for approximating functions in the context of option pricing. The first few Laguerre polynomials
are:
ϕ0 (St ) = 1,
ϕ1 (St ) = 1 − St ,
1
ϕ2 (St ) = (2 − 4St + St2 ),
2
1
ϕ3 (St ) = (6 − 18St + 9St2 − St3 ).
6
3.2 Regression Equation
For the in-the-money paths (where It > 0):
• Let X be the vector of in-the-money stock prices.
• Let Y be the vector of discounted future cash flows:
Y = Vt+1 e−r∆t .
• The regression model is:
Y ≈ Φ(X)β,
where Φ(X) is the matrix of basis functions evaluated at X.
The coefficients β are computed using the least squares formula:
β = (Φ⊤ Φ)−1 Φ⊤ Y.
4 Backward Induction
The Longstaff-Schwartz method applies backward induction to determine the optimal stopping
rule:
1. At maturity (t = T ), the option value is simply the intrinsic value:
VT = IT .
2. At each earlier step (t = T − ∆t, . . . , 0):
2
(a) Use regression to estimate the continuation value Ct .
(b) Compare It and Ct . The holder exercises if:
It ≥ Ct .
(c) Update the cash flows: (
It if It ≥ Ct ,
Vt =
Vt+1 e−r∆t otherwise.
Finally, the option price is the discounted average of all cash flows at t = 0:
M
1 X (i)
V0 = V .
M i=1 0
3
5 Python Implementation
1 """
2 Implementation of the Longstaff-Schwartz Method for pricing American options.
3 Uses Monte Carlo simulations and least-squares regression for optimal exercise
4 decision.
5
6 Author: Harsh Parikh
7 """
8
9 import numpy as np
10 import statsmodels.api as sm
11
12
13 def basis_function(k, X):
14 """
15 Generate Laguerre polynomial basis functions.
16
17 Input
18 -----
19 X (np.array): Input vector
20 k (int): The number of Laguerre polynomials
21
22 Returns
23 -------
24 tuple:
25 Tuple of basis function arrays
26 """
27 if not isinstance(X, np.ndarray):
28 raise TypeError("The type of the vector X should be np.ndarray")
29
30 if k > 4:
31 raise ValueError("The value of k should be less than or equal to 4")
32
33 # Laguerre polynomial basis functions
34 basis_funcs = [
35 [np.ones(X.size), (1 - X)],
36 [np.ones(X.size), (1 - X), 1 / 2 * (2 - 4 * X + X**2)],
37 [
38 np.ones(X.size),
39 (1 - X),
40 1 / 2 * (2 - 4 * X + X**2),
41 1 / 6 * (6 - 18 * X + 9 * X**2 - X**3),
42 ],
43 [
44 np.ones(X.size),
45 (1 - X),
46 1 / 2 * (2 - 4 * X + X**2),
47 1 / 6 * (6 - 18 * X + 9 * X**2 - X**3),
48 1 / 24 * (24 - 96 * X + 72 * X**2 - 16 * X**3 + X**4),
49 ],
50 ]
51
52 return tuple(basis_funcs[k - 1])
4
53
54
55 def longstaff_schwartz(
56 spot, strike, sigma, T, r, N=1000, M=10000, isCall=True, k=3, seed=42
57 ):
58 r"""
59 Implement the Longstaff Schwartz pricing engine for American options.
60
61 The engine assumes the underlying follows a Geometric Brownian Motion (GBM)
62 with constant values of $\mu$ and $\sigma$.
63
64 The dynamics of the GBM are given as:
65
66 $$dS_t = S_t (\mu \, dt + \sigma \, dW_t)$$
67
68 where:
69 - $\mu$: Drift
70 - $\sigma$: Volatility
71 - $dW$: Wiener process.
72
73 Input Parameters
74 ----------------
75 spot : float
76 The current spot price
77 strike : float
78 The predetermined strike price
79 sigma : float
80 The current volatility
81 T : float
82 Time to maturity
83 r : float
84 Risk-free rate
85 N : int, optional
86 Number of time steps (default 500)
87 M : int, optional
88 Number of Monte-Carlo paths (default 10000)
89 isCall : bool, optional
90 ‘True‘ for call option and ‘False‘ for put (default True)
91 k : int, optional
92 Number of Laguerre polynomials (default 3)
93 seed : int, optional
94 Random seed for reproducibility (default 42)
95
96 Returns
97 -------
98 float:
99 The price of the corresponding American option.
100 """
101 # Initialising a random seed for reproducability.
102 np.random.seed(seed)
103
104 # Discretising the time grid
105 dt = T / N
106
5
107 # Initialising the stock paths.
108 stock_paths = np.zeros((M, N + 1)) # M paths, N+1 time steps
109
110 stock_paths[:, 0] = spot # Initial spot price at t=0
111
112 # Initialising the drift and diffusion terms
113 drift = (r - 0.5 * sigma**2) * dt
114
115 dZ = np.random.normal(0, 1.0, size=(M, N)) * np.sqrt(dt) # Brownian increments
116
117 diffusion = sigma * dZ
118
119 # Generating vectorised form of stock paths.
120 stock_paths[:, 1:] = spot * np.cumprod(np.exp(drift + diffusion), axis=1)
121
122 # Calculating the option payoff based on the option type.
123 option_prices = (
124 np.maximum(stock_paths - strike, 0.0)
125 if isCall
126 else np.maximum(strike - stock_paths, 0.0)
127 )
128
129 # Initialising the cash flows with the terminal payoff
130 cash_flows = option_prices[:, -1]
131
132 # Interating backwards
133
134 for t in range(N - 1, 0, -1):
135
136 # Storing the in-the-money paths
137 in_the_money = option_prices[:, t] > 0
138
139 if not np.any(in_the_money):
140 # Discounting the cash flows part
141 cash_flows *= np.exp(-r * dt)
142 continue
143
144 # Current stock prices for in-the-money paths
145 X = stock_paths[in_the_money, t]
146
147 # Discounted future cash flows
148 Y = cash_flows[in_the_money] * np.exp(-r * dt)
149
150 # Calculating the basis function
151 basis = np.column_stack(basis_function(k, X / spot))
152
153 # Least squares regression to estimate continuation value using OLS
154 model = sm.OLS(Y, basis).fit()
155
156 # Getting the continuation values
157 continuation_value = model.predict(basis)
158
159 # Intrinsic value at current time step
160 intrinsic_value = option_prices[in_the_money, t]
6
161
162 # Determining optimal exercise
163 exercise = intrinsic_value > continuation_value
164
165 # Updating the cash flows
166 cash_flows[in_the_money] = np.where(
167 exercise, intrinsic_value, cash_flows[in_the_money] * np.exp(-r * dt)
168 )
169
170 # Final option price calculation
171 option_price = np.mean(cash_flows) * np.exp(-r * dt)
172 return option_price
7
References
[1] J. Larsson and O. Norberg. Valuation of american options using the longstaff-schwartz method,
2015. Bachelor’s thesis.
[2] F. A. Longstaff and E. S. Schwartz. Valuing american options by simulation: A simple least-
squares approach. The Review of Financial Studies, 14(1):113–147, 2001.