Finite Difference Methods for Option Pricing › Pricing American Options

Michael BrenndoerferDecember 4, 20256 min read
Quantitative FinanceAll chapters
Part 6 of 15Numerical Methods for Derivative Pricing
Chapter 36Finite Difference Methods for Option Pricing › Pricing American Options
Reading section 8 of 14 · Pricing American Options · 6 minSection 8 of 14 · 6 min

Book contents

Section 8 of 14 · 6 min read

Finite Difference Methods for Option Pricing › Pricing American OptionsOne section · Sections in this chapter8 / 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

American options are a major application for finite difference methods because they can be exercised at any time. The analytical Black-Scholes formula doesn't apply to American options, making numerical methods essential.

The Early Exercise Constraint

For an American option, at each point in time we must check whether early exercise is optimal. The key insight is that no rational holder would keep an option whose continuation value (the value if held) falls below its intrinsic value (the value if exercised immediately). The option value cannot fall below its intrinsic value:

V(S,t)≥max⁡(S−K,0)(American call)V(S,t)≥max⁡(K−S,0)(American put)\begin{aligned} V(S, t) &\geq \max(S - K, 0) && \text{(American call)} \\ V(S, t) &\geq \max(K - S, 0) && \text{(American put)} \end{aligned}

where:

  • V(S,t)V(S,t): American option value
  • SS: current stock price
  • KK: strike price

In finite difference terms, after each backward time step, we apply:

Vjn=max⁡(Vjn,payoff(Sj))V_j^n = \max(V_j^n, \text{payoff}(S_j))

where:

  • VjnV_j^n: option continuation value computed by the FD scheme
  • payoff(Sj)\text{payoff}(S_j): immediate exercise value (e.g., K−SjK-S_j for a put)
  • max⁡\max: operator selecting the higher of holding or exercising

This simple modification converts our European option pricer into an American option pricer. This step implements the dynamic programming principle: at each state, we compare the value of waiting (continuation value) against the value of acting now (exercise value) and rationally choose the maximum. The finite difference framework handles this naturally because we solve backward in time, determining the optimal decision at each grid point given knowledge of future values.

Implementation

In[25]:
Code
def crank_nicolson_american_put(S_max, K, T, r, sigma, M, N):
    """
    Price an American put option using Crank-Nicolson with early exercise.
    """
    dS = S_max / M
    dt = T / N

    S = np.linspace(0, S_max, M + 1)

    # Terminal condition
    V = np.maximum(K - S, 0)
    payoff = V.copy()  # Store payoff for early exercise comparison

    # Coefficients
    j = np.arange(1, M)
    alpha = 0.25 * dt * (sigma**2 * j**2 - r * j)
    beta = 0.5 * dt * (sigma**2 * j**2 + r)
    gamma = 0.25 * dt * (sigma**2 * j**2 + r * j)

    a_left = -alpha[1:]
    b_left = 1 + beta
    c_left = -gamma[:-1]

    # Track early exercise boundary
    exercise_boundary = []

    for n in range(N - 1, -1, -1):
        d = alpha * V[0 : M - 1] + (1 - beta) * V[1:M] + gamma * V[2 : M + 1]

        boundary_0 = K * np.exp(-r * (N - n) * dt)
        boundary_M = 0

        d[0] += alpha[0] * boundary_0
        d[-1] += gamma[-1] * boundary_M

        V[1:M] = thomas_algorithm(a_left, b_left, c_left, d)
        V[0] = boundary_0
        V[M] = boundary_M

        # Apply early exercise constraint
        V = np.maximum(V, payoff)

        # Find exercise boundary (highest S where early exercise is optimal)
        exercise_idx = np.where(
            (payoff > 0) & np.isclose(V, payoff, rtol=0, atol=1e-10)
        )[0]
        if len(exercise_idx) > 0:
            exercise_boundary.append((n * dt, S[exercise_idx[-1]]))

    return S, V, exercise_boundary
In[26]:
Code
# Price American put
S_grid, V_american, boundary = crank_nicolson_american_put(
    S_max, K, T, r, sigma, M, 500
)

# Also price European put for comparison
S_grid, V_european = crank_nicolson_european_put(S_max, K, T, r, sigma, M, 500)

idx = np.argmin(np.abs(S_grid - S_0))
price_american_put = V_american[idx]
price_european_put = V_european[idx]
early_exercise_premium = price_american_put - price_european_put
Out[27]:
Console
American put price at S = 100: $6.0780
European put price at S = 100: $5.5636
Early exercise premium: $0.5144

The early exercise premium represents the additional value an American put holder gains from the flexibility to exercise early. This premium is positive for puts on non-dividend-paying stocks because the put holder can capture the strike price immediately rather than waiting and earning interest on the proceeds.

Out[28]:
Visualization
Line plot comparing American and European put values across stock prices with the early exercise premium shown as shaded region.
Comparison of American and European put option values. The American put is always worth at least as much as the European put due to the early exercise feature. The difference (shaded region) represents the early exercise premium, which is most significant for in-the-money options.

Visualizing the Early Exercise Boundary

Out[29]:
Visualization
Plot showing the early exercise boundary as a curve separating the exercise and continuation regions.
Early exercise boundary for an American put option. The shaded region shows where immediate exercise is optimal. Below this boundary, the option holder should exercise; above it, they should continue holding the option.

The early exercise boundary shows the critical stock price below which immediate exercise is optimal. As time to expiration decreases, this boundary rises toward the strike price because the time value of waiting diminishes.