Skip to content

Multi-Period Binomial Model

Introduction

This section extends the one-period binomial model to multiple time periods. The multi-period framework enables:

  • Realistic option pricing: Options with arbitrary maturities
  • Dynamic delta hedging: Rebalancing the hedge as the stock evolves
  • Path to continuous time: Foundation for Black–Scholes convergence

The key insight is that multi-period pricing reduces to repeated application of one-period pricing via backward induction.

Prerequisites

Learning Objectives

By the end of this section, you will be able to:

  1. Construct a multi-period binomial tree
  2. Price European options via backward induction
  3. Implement dynamic delta hedging through the tree
  4. Understand the self-financing property

The Multi-Period Tree

Time Structure

Fix a maturity \(T\) and divide it into \(N\) equal periods:

\[ \Delta t = \frac{T}{N} \]

Time points: \(t_n = n \cdot \Delta t\) for \(n = 0, 1, \ldots, N\).

Node Indexing

Each node is indexed by \((n, j)\) where:

  • \(n = 0, 1, \ldots, N\) is the time index
  • \(j = 0, 1, \ldots, n\) is the state index (number of up moves)

Stock Prices

At node \((n, j)\), the stock price is:

\[ \boxed{S_{n,j} = S_0 \cdot u^j \cdot d^{n-j}} \]

The Recombining Property

With \(u = e^{\sigma\sqrt{\Delta t}}\) and \(d = e^{-\sigma\sqrt{\Delta t}} = 1/u\):

\[ ud = 1 \]

An up-then-down path reaches the same price as a down-then-up path. The tree recombines, giving only \(n+1\) nodes at time \(n\) (not \(2^n\)).

Tree Visualization (N = 3)

binomial_tree_n3
Figure 1: Three-period recombining binomial tree with log-scale node spacing. Node \((n, j)\) has price \(S_{n,j} = u^j d^{n-j} S_0\). The tree is mirror-symmetric around \(S_0\) under the CRR parametrization \(d = 1/u\), where up and down moves are equal in magnitude in log space: \(\log u = -\log d = \sigma\sqrt{\Delta t}\).

Computational Advantage

Tree Type Nodes at Time \(n\) Total Nodes
Recombining \(n + 1\) \(O(N^2)\)
Non-recombining \(2^n\) \(O(2^N)\)

Backward Induction for European Options

The Algorithm

Step 1: Terminal condition (\(n = N\))

Set option values equal to payoffs:

\[ V_{N,j} = H(S_{N,j}) \]

Step 2: Backward recursion (\(n = N-1, N-2, \ldots, 0\))

At each node \((n, j)\), the option value is the discounted risk-neutral expectation:

\[ \boxed{V_{n,j} = e^{-r\Delta t}\left[qV_{n+1,j+1} + (1-q)V_{n+1,j}\right]} \]

where \(q = \frac{e^{r\Delta t} - d}{u - d}\).

Step 3: Output

The option price is \(V_{0,0}\).

Why Backward Induction Works

At each node, we apply the one-period pricing formula. The option at node \((n,j)\) is a one-period claim with:

  • Up-state payoff: \(V_{n+1,j+1}\)
  • Down-state payoff: \(V_{n+1,j}\)

By risk-neutral pricing:

\[ V_{n,j} = e^{-r\Delta t}\mathbb{E}^{\mathbb{Q}}[V_{n+1} \mid \text{at node } (n,j)] \]

Dynamic Delta Hedging

The Hedging Strategy

At each node \((n, j)\), we construct a locally replicating portfolio:

  • Hold \(\Delta_{n,j}\) shares of stock
  • Hold \(B_{n,j}\) units of bond (cash)

The portfolio replicates the option over the next period.

Computing Delta at Each Node

From the one-period hedging formula:

\[ \boxed{\Delta_{n,j} = \frac{V_{n+1,j+1} - V_{n+1,j}}{S_{n,j}(u - d)}} \]

This is the local hedge ratio—the number of shares to hold at node \((n,j)\).

Computing the Cash Position

\[ \boxed{B_{n,j} = e^{-r\Delta t}\left(V_{n+1,j+1} - \Delta_{n,j} \cdot uS_{n,j}\right)} \]

Or equivalently:

\[ B_{n,j} = V_{n,j} - \Delta_{n,j} \cdot S_{n,j} \]

The Rebalancing Process

  1. At \(t = 0\): Enter position \((\Delta_{0,0}, B_{0,0})\)
  2. At \(t = \Delta t\): Stock has moved to state \(j\)
  3. Old portfolio value: \(\Delta_{0,0} \cdot S_{1,j} + B_{0,0} \cdot e^{r\Delta t}\)
  4. This equals \(V_{1,j}\) (by construction)
  5. Rebalance to new position \((\Delta_{1,j}, B_{1,j})\)
  6. Repeat at each time step until maturity

Self-Financing Property

The rebalancing requires no external cash. The value of the old portfolio exactly equals the cost of the new portfolio:

\[ \Delta_{n-1,k} \cdot S_{n,j} + B_{n-1,k} \cdot e^{r\Delta t} = V_{n,j} = \Delta_{n,j} \cdot S_{n,j} + B_{n,j} \]

This is the self-financing property—the hedging strategy is implementable without adding or withdrawing funds.


Complete Numerical Example

Parameters

Parameter Value
\(S_0\) \(100\)
\(K\) \(100\)
\(r\) \(5\%\) per year
\(\sigma\) \(20\%\) per year
\(T\) \(1\) year
\(N\) \(3\) periods

Computed Values

\[ \Delta t = \frac{1}{3}, \quad u = e^{0.2\sqrt{1/3}} = 1.1224, \quad d = \frac{1}{u} = 0.8909 \]
\[ e^{r\Delta t} = e^{0.05/3} = 1.0168, \quad q = \frac{1.0168 - 0.8909}{1.1224 - 0.8909} = 0.5439 \]

Stock Price Tree

Node Price
\(S_{0,0}\) \(100.00\)
\(S_{1,1}\) \(112.24\)
\(S_{1,0}\) \(89.09\)
\(S_{2,2}\) \(125.98\)
\(S_{2,1}\) \(100.00\)
\(S_{2,0}\) \(79.37\)
\(S_{3,3}\) \(141.40\)
\(S_{3,2}\) \(112.24\)
\(S_{3,1}\) \(89.09\)
\(S_{3,0}\) \(70.72\)

Option Values (European Call, K = 100)

Terminal payoffs (\(n = 3\)):

\[ V_{3,3} = 41.40, \quad V_{3,2} = 12.24, \quad V_{3,1} = 0, \quad V_{3,0} = 0 \]

At \(n = 2\):

\[\begin{array}{lll} V_{2,2} &=&\displaystyle e^{-0.0167}[0.5439 \times 41.40 + 0.4561 \times 12.24] = 0.9835 \times 28.10 = 27.63\\ V_{2,1} &=&\displaystyle e^{-0.0167}[0.5439 \times 12.24 + 0.4561 \times 0] = 0.9835 \times 6.66 = 6.55\\ V_{2,0} &=&\displaystyle e^{-0.0167}[0.5439 \times 0 + 0.4561 \times 0] = 0 \end{array}\]

At \(n = 1\):

\[\begin{array}{lll} V_{1,1} &=&\displaystyle e^{-0.0167}[0.5439 \times 27.63 + 0.4561 \times 6.55] = 0.9835 \times 18.02 = 17.72\\ V_{1,0} &=&\displaystyle e^{-0.0167}[0.5439 \times 6.55 + 0.4561 \times 0] = 0.9835 \times 3.56 = 3.50 \end{array}\]

At \(n = 0\):

\[ V_{0,0} = e^{-0.0167}[0.5439 \times 17.72 + 0.4561 \times 3.50] = 0.9835 \times 11.23 = 11.04 \]

European Call Price

\[C_0 = 11.04\]

Delta at Each Node

\[\begin{array}{lll} \Delta_{2,2} &=&\displaystyle \frac{41.40 - 12.24}{125.98 \times 0.2315} = \frac{29.16}{29.16} = 1.00\\ \Delta_{2,1} &=&\displaystyle \frac{12.24 - 0}{100 \times 0.2315} = \frac{12.24}{23.15} = 0.529\\ \Delta_{2,0} &=&\displaystyle \frac{0 - 0}{79.37 \times 0.2315} = 0\\ \Delta_{1,1} &=&\displaystyle \frac{27.63 - 6.55}{112.24 \times 0.2315} = \frac{21.08}{25.98} = 0.812\\ \Delta_{1,0} &=&\displaystyle \frac{6.55 - 0}{89.09 \times 0.2315} = \frac{6.55}{20.62} = 0.318\\ \Delta_{0,0} &=&\displaystyle \frac{17.72 - 3.50}{100 \times 0.2315} = \frac{14.22}{23.15} = 0.614 \end{array}\]

Delta Hedging Through the Tree

Initial position (\(t = 0\)):

\[ \text{Hold } \Delta_{0,0} = 0.614 \text{ shares (cost } 61.40\text{)}, \quad \text{Borrow } B_{0,0} = 11.04 - 61.40 = -50.36 \]
\[ \text{Portfolio value} = 11.04 = \text{option price} \checkmark \]

After up move (\(t = \Delta t\), stock at \(112.24\)):

\[\begin{array}{lll} \text{Stock position: }&& 0.614 \times 112.24 = 68.92\\ \text{Cash position: }&& {-50.36} \times e^{0.0167} = -51.20\\ \text{Portfolio value: }&& 68.92 - 51.20 = 17.72 = V_{1,1} \checkmark \end{array}\]

Rebalance: increase to \(\Delta_{1,1} = 0.812\) shares — buy \(0.812 - 0.614 = 0.198\) shares at \(112.24\) (cost \(22.22\)), new cash position: \(-51.20 - 22.22 = -73.42\).

After down move (\(t = \Delta t\), stock at \(89.09\)):

\[\begin{array}{lll} \text{Stock position: }&& 0.614 \times 89.09 = 54.70\\ \text{Cash position: }&& {-50.36} \times e^{0.0167} = -51.20\\ \text{Portfolio value: }&& 54.70 - 51.20 = 3.50 = V_{1,0} \checkmark \end{array}\]

The hedging strategy perfectly replicates the option value at every node.


Properties of Multi-Period Delta

Delta Evolution

As we move through the tree:

  • Stock rises → Call delta increases (approaches 1)
  • Stock falls → Call delta decreases (approaches 0)
  • Near expiration → Delta becomes more extreme (0 or 1)

Gamma: Rate of Change of Delta

The gamma measures how fast delta changes:

\[ \Gamma_{n,j} \approx \frac{\Delta_{n+1,j+1} - \Delta_{n+1,j}}{S_{n+1,j+1} - S_{n+1,j}} \]

High gamma means more frequent rebalancing is needed.

Delta at Maturity

At expiration:

\[ \Delta_{N-1,j} = \frac{V_{N,j+1} - V_{N,j}}{S_{N-1,j}(u-d)} = \begin{cases} 1 & \text{if both nodes in-the-money} \\ \frac{\text{payoff spread}}{\text{price spread}} & \text{if one node ITM} \\ 0 & \text{if both nodes out-of-the-money} \end{cases} \]

Algorithm Summary

European Option Pricing

``` Input: S₀, K, r, σ, T, N, option_type Output: V₀

  1. Δt = T/N, u = exp(σ√Δt), d = 1/u
  2. q = (exp(rΔt) - d) / (u - d)
  3. For j = 0 to N: V[N,j] = payoff(S₀ × uʲ × d^(N-j), K)
  4. For n = N-1 down to 0: For j = 0 to n: V[n,j] = exp(-rΔt) × [q×V[n+1,j+1] + (1-q)×V[n+1,j]]
  5. Return V[0,0] ```

Memory-Efficient Implementation

Only store one time slice:

V = array[N+1] // Initialize terminal payoffs For n = N-1 down to 0: For j = 0 to n: V[j] = exp(-rΔt) × [q×V[j+1] + (1-q)×V[j]] Return V[0]

Complexity: \(O(N^2)\) time, \(O(N)\) space.


Python Implementation: Replicating Portfolio Simulation

The following code simulates dynamic delta hedging of a European call option with daily rebalancing over \(T = 3/13\) years (approximately 3 trading weeks, \(N = 58\) trading days). At each node it prints stock_value, mma_value (money-market account), total_value, and delta, with payoff and replicating portfolio value at maturity.

```python """ Replicating Portfolio Simulation — Multi-Period Binomial Model ============================================================== Simulates dynamic delta hedging of a European call option with daily rebalancing over T = 3/13 years (~3 trading weeks).

Parameters match the textbook's running example (S0=100, K=100, r=5%, sigma=20%) with N chosen so that dt = 1 trading day. """

import numpy as np import matplotlib.pyplot as plt

── Parameters ────────────────────────────────────────────────────────────────

S0 = 100.0 # initial stock price K = 100.0 # strike price r = 0.05 # risk-free rate (annual) sigma = 0.20 # volatility (annual) T = 3 / 12 # maturity in years (≈ 3 months)

TRADING_DAYS_PER_YEAR = 252 N = round(T * TRADING_DAYS_PER_YEAR) # number of time steps (= trading days) dt = T / N # length of one period in years

── CRR Parameters ────────────────────────────────────────────────────────────

u = np.exp(sigma * np.sqrt(dt)) # up factor d = 1.0 / u # down factor (recombining: ud = 1) R = np.exp(r * dt) # money-market account growth per period q = (R - d) / (u - d) # risk-neutral probability of an up move

── Build Stock-Price Tree S[n, j] = S0 · u^j · d^(n-j) ────────────────────

S = np.zeros((N + 1, N + 1)) for n in range(N + 1): for j in range(n + 1): S[n, j] = S0 * (u ** j) * (d ** (n - j))

── Backward Induction for Option Values ─────────────────────────────────────

V = np.zeros((N + 1, N + 1)) for j in range(N + 1): # terminal payoffs V[N, j] = max(S[N, j] - K, 0.0)

for n in range(N - 1, -1, -1): # backward recursion for j in range(n + 1): V[n, j] = np.exp(-r * dt) * (q * V[n + 1, j + 1] + (1 - q) * V[n + 1, j])

── Delta at Each Interior Node Δ[n, j] ─────────────────────────────────────

Delta = np.zeros((N, N + 1)) for n in range(N): for j in range(n + 1): Delta[n, j] = (V[n + 1, j + 1] - V[n + 1, j]) / (S[n, j] * (u - d))

── Path Simulation ───────────────────────────────────────────────────────────

def simulate(path_moves: list[str]) -> list[dict]: """ Simulate the replicating portfolio along a given price path.

Parameters
----------
path_moves : list of 'u' or 'd', length N
    The sequence of up/down moves for the stock.

Returns
-------
List of dicts, one per time step n = 0, 1, …, N.
Each dict contains:
    n                  – time index (trading day)
    stock_price        – S[n, j]
    delta              – shares held (None at maturity)
    stock_value        – delta * S[n, j]  (market value of stock leg)
    mma_value          – cash/bond position value
    total_value        – stock_value + mma_value  (= replicating portfolio)
    option_value       – V[n, j] from tree (None at maturity)
    payoff             – (S - K)^+  (only at maturity, else None)
"""
assert len(path_moves) == N, f"path_moves must have length N={N}"

records = []
j = 0  # state index (number of up moves so far)

# ── t = 0: set up the initial portfolio ───────────────────────────────────
delta = Delta[0, 0]
B     = V[0, 0] - delta * S[0, 0]   # cash leg  (negative → borrowed)

records.append({
    'n':            0,
    'stock_price':  S[0, 0],
    'delta':        delta,
    'stock_value':  delta * S[0, 0],
    'mma_value':    B,
    'total_value':  V[0, 0],
    'option_value': V[0, 0],
    'payoff':       None,
})

# ── t = 1 … N: evolve and rebalance ──────────────────────────────────────
for n in range(1, N + 1):
    if path_moves[n - 1] == 'u':
        j += 1
    # else j unchanged (down move)

    # portfolio value BEFORE rebalancing (self-financing: no cash injection)
    stock_value = delta * S[n, j]
    mma_value   = B * R                  # cash grew at risk-free rate
    total_value = stock_value + mma_value

    at_maturity = (n == N)

    if at_maturity:
        records.append({
            'n':            n,
            'stock_price':  S[n, j],
            'delta':        None,
            'stock_value':  stock_value,
            'mma_value':    mma_value,
            'total_value':  total_value,
            'option_value': None,
            'payoff':       max(S[n, j] - K, 0.0),
        })
    else:
        # rebalance to new delta (self-financing: adjust cash to match)
        delta_new = Delta[n, j]
        B_new     = V[n, j] - delta_new * S[n, j]

        records.append({
            'n':            n,
            'stock_price':  S[n, j],
            'delta':        delta_new,
            'stock_value':  stock_value,
            'mma_value':    mma_value,
            'total_value':  total_value,
            'option_value': V[n, j],
            'payoff':       None,
        })

        delta = delta_new
        B     = B_new

return records

── Printing ──────────────────────────────────────────────────────────────────

def print_results(records: list[dict], title: str) -> None: """Pretty-print node-by-node replication table.""" header = ( f"{'Day':>4} {'Stock':>8} {'Delta':>7} " f"{'Stock Val':>10} {'MMA Val':>10} {'Total Val':>10} " f"{'Option Val':>10} {'Payoff':>8}" ) sep = "─" * len(header)

print(f"\n{'═' * len(header)}")
print(f"  {title}")
print(f"{'═' * len(header)}")
print(f"  S0={S0}  K={K}  r={r:.0%}  σ={sigma:.0%}  "
      f"T={T:.4f} yr  N={N} days")
print(f"  u={u:.6f}  d={d:.6f}  R={R:.6f}  q={q:.6f}")
print(f"  Option price V(0,0) = {V[0, 0]:.4f}")
print(sep)
print(header)
print(sep)

for row in records:
    delta_str  = f"{row['delta']:.4f}"  if row['delta']  is not None else "  N/A "
    optval_str = f"{row['option_value']:.4f}" if row['option_value'] is not None else "  —   "
    payoff_str = f"{row['payoff']:.4f}" if row['payoff'] is not None else "  —   "

    print(
        f"{row['n']:>4}  "
        f"{row['stock_price']:>8.4f}  "
        f"{delta_str:>7}  "
        f"{row['stock_value']:>10.4f}  "
        f"{row['mma_value']:>10.4f}  "
        f"{row['total_value']:>10.4f}  "
        f"{optval_str:>10}  "
        f"{payoff_str:>8}"
    )

print(sep)
final = records[-1]
print(f"  Final replicating portfolio value : {final['total_value']:>10.4f}")
print(f"  Final option payoff               : {final['payoff']:>10.4f}")
print(f"  Replication error                 : {abs(final['total_value'] - final['payoff']):>10.6f}")
print(f"{'═' * len(header)}\n")

── Run Three Illustrative Paths ──────────────────────────────────────────────

1. All-up path (deep in-the-money at maturity)

path_all_up = ['u'] * N res_up = simulate(path_all_up) print_results(res_up, "Path 1 — All Up (stock finishes deep ITM)")

2. All-down path (deep out-of-the-money at maturity)

path_all_down = ['d'] * N res_down = simulate(path_all_down) print_results(res_down, "Path 2 — All Down (stock finishes OTM, payoff = 0)")

3. Alternating up/down path (stock oscillates near S0)

path_alt = (['u', 'd'] * (N // 2 + 1))[:N] res_alt = simulate(path_alt) print_results(res_alt, "Path 3 — Alternating (stock stays near ATM)")

── Delta Evolution Plot ───────────────────────────────────────────────────────

def path_deltas(path_moves: list[str]) -> list[float]: """Extract the delta sequence along a given path (length N, days 0..N-1).""" j = 0 deltas = [Delta[0, 0]] for n in range(1, N): if path_moves[n - 1] == 'u': j += 1 deltas.append(Delta[n, j]) return deltas

def plot_delta_evolution(save_path: str = 'delta_evolution.svg') -> None: """Plot delta along all three illustrative paths and save to file.""" days = np.arange(N) d_up = path_deltas(['u'] * N) d_dn = path_deltas(['d'] * N) d_alt = path_deltas((['u', 'd'] * (N // 2 + 1))[:N])

fig, ax = plt.subplots(figsize=(9, 5))
fig.patch.set_facecolor('#FAFAFA')
ax.set_facecolor('#FAFAFA')

# reference lines
ax.axhline(1.0, color='#BBBBBB', linewidth=0.8, linestyle='--', zorder=1)
ax.axhline(0.5, color='#BBBBBB', linewidth=0.8, linestyle=':',  zorder=1)
ax.axhline(0.0, color='#BBBBBB', linewidth=0.8, linestyle='--', zorder=1)

# three paths
ax.plot(days, d_up,  color='#1A6EBD', linewidth=2.0, label='All Up   (ITM path)',    zorder=3)
ax.plot(days, d_dn,  color='#C0392B', linewidth=2.0, label='All Down (OTM path)',    zorder=3)
ax.plot(days, d_alt, color='#27AE60', linewidth=1.6, label='Alternating (ATM path)', zorder=3, alpha=0.9)

# annotation: delta → 1
sat_up = next(i for i, v in enumerate(d_up) if v >= 0.9999)
ax.axvline(sat_up, color='#1A6EBD', linewidth=0.9, linestyle=':', alpha=0.6)
ax.annotate(f'$\\Delta \\approx 1$ (day {sat_up})',
            xy=(sat_up, 1.0), xytext=(sat_up + 3, 0.88),
            fontsize=9, color='#1A6EBD',
            arrowprops=dict(arrowstyle='->', color='#1A6EBD', lw=0.9))

# annotation: delta → 0
sat_dn = next(i for i, v in enumerate(d_dn) if v <= 0.0001)
ax.axvline(sat_dn, color='#C0392B', linewidth=0.9, linestyle=':', alpha=0.6)
ax.annotate(f'$\\Delta \\approx 0$ (day {sat_dn})',
            xy=(sat_dn, 0.0), xytext=(sat_dn + 3, 0.12),
            fontsize=9, color='#C0392B',
            arrowprops=dict(arrowstyle='->', color='#C0392B', lw=0.9))

# annotation: gamma spike
ax.annotate('Gamma spike\nnear expiry',
            xy=(N - 2, d_alt[-1]), xytext=(N - 18, 0.78),
            fontsize=9, color='#27AE60',
            arrowprops=dict(arrowstyle='->', color='#27AE60', lw=0.9))

# zone labels
ax.text(N * 0.65, 1.05,  'Deep ITM  ($\\Delta = 1$)', fontsize=8.5, color='#777777', ha='center')
ax.text(N * 0.65, -0.035, 'Deep OTM  ($\\Delta = 0$)', fontsize=8.5, color='#777777', ha='center')

ax.set_xlabel('Trading Day  $n$', fontsize=11)
ax.set_ylabel('Delta  $\\Delta_{n,j}$', fontsize=11)
ax.set_title(
    'Delta Evolution Along Three Price Paths\n'
    r'$S_0=100,\ K=100,\ \sigma=20\%,\ r=5\%,\ T=3/13\ \mathrm{yr},\ N=58\ \mathrm{days}$',
    fontsize=11, pad=10,
)
ax.set_xlim(0, N - 1)
ax.set_ylim(-0.05, 1.10)
ax.set_yticks([0.0, 0.25, 0.50, 0.75, 1.0])
ax.legend(loc='center right', fontsize=9.5, framealpha=0.85)
ax.spines[['top', 'right']].set_visible(False)

plt.tight_layout()
plt.savefig(save_path, bbox_inches='tight')
print(f"Delta evolution plot saved to: {save_path}")
plt.show()

plot_delta_evolution(save_path='delta_evolution.svg') ```

Output

Three paths are simulated to illustrate the full range of hedging behavior. Each path uses the same initial portfolio (\(V_{0,0} = 4.3940\), \(\Delta_{0,0} = 0.5665\) shares, \(B_{0,0} = -52.2539\) borrowed). Each row shows the portfolio state before rebalancing, verifying the self-financing condition \(\Delta_{n-1} \cdot S_{n,j} + B_{n-1} \cdot R = V_{n,j}\) at every step.

Path 1 — All Up (stock finishes deep ITM at \(S_T = 207.86\), payoff \(= 107.86\))

As the stock rises, delta climbs from \(0.5665\) toward \(1.0\) (reached by day 22) and the MMA balance stabilizes at \(\approx -100\). By day 22 the position is fully hedged: hold 1 share, borrow the PV of the strike — equivalent to a forward contract.

═════════════════════════════════════════════════════════════════════════════════ Path 1 — All Up (stock finishes deep ITM) ═════════════════════════════════════════════════════════════════════════════════ S0=100.0 K=100.0 r=5% σ=20% T=0.2500 yr N=63 days u=1.012679 d=0.987480 R=1.000198 q=0.504725 Option price V(0,0) = 4.6304 ───────────────────────────────────────────────────────────────────────────────── Day Stock Delta Stock Val MMA Val Total Val Option Val Payoff ───────────────────────────────────────────────────────────────────────────────── 0 100.0000 0.5690 56.8953 -52.2649 4.6304 4.6304 — 1 101.2679 0.6176 57.6166 -52.2753 5.3413 5.3413 — 2 102.5518 0.6652 63.3340 -57.2111 6.1229 6.1229 — 3 103.8520 0.7110 69.0795 -62.1040 6.9755 6.9755 — 4 105.1687 0.7543 74.7735 -66.8751 7.8983 7.8983 — 5 106.5021 0.7946 80.3376 -71.4477 8.8900 8.8900 — 6 107.8523 0.8313 85.6987 -75.7508 9.9479 9.9479 — 7 109.2197 0.8640 90.7924 -79.7236 11.0688 11.0688 — 8 110.6045 0.8927 95.5668 -83.3181 12.2487 12.2487 — 9 112.0068 0.9171 99.9848 -86.5015 13.4833 13.4833 — 10 113.4269 0.9375 104.0261 -89.2581 14.7680 14.7680 — 11 114.8650 0.9541 107.6868 -91.5887 16.0980 16.0980 — 12 116.3213 0.9672 110.9791 -93.5102 17.4689 17.4689 — 13 117.7961 0.9772 113.9289 -95.0525 18.8764 18.8764 — 14 119.2895 0.9847 116.5727 -96.2559 20.3168 20.3168 — 15 120.8019 0.9901 118.9542 -97.1674 21.7868 21.7868 — 16 122.3335 0.9938 121.1204 -97.8366 23.2838 23.2838 — 17 123.8845 0.9963 123.1180 -98.3123 24.8057 24.8057 — 18 125.4552 0.9979 124.9908 -98.6398 26.3510 26.3510 — 19 127.0458 0.9989 126.7770 -98.8584 27.9186 27.9186 — 20 128.6566 0.9994 128.5087 -99.0009 29.5079 29.5079 — 21 130.2877 0.9997 130.2109 -99.0925 31.1184 31.1184 — 22 131.9396 0.9999 131.9021 -99.1519 32.7501 32.7501 — 23 133.6124 0.9999 133.5953 -99.1923 34.4030 34.4030 — 24 135.3064 1.0000 135.2992 -99.2220 36.0773 36.0773 — 25 137.0219 1.0000 137.0191 -99.2461 37.7730 37.7730 — 26 138.7591 1.0000 138.7582 -99.2676 39.4906 39.4906 — 27 140.5184 1.0000 140.5181 -99.2880 41.2301 41.2301 — 28 142.2999 1.0000 142.2999 -99.3079 42.9920 42.9920 — 29 144.1041 1.0000 144.1041 -99.3277 44.7764 44.7764 — 30 145.9311 1.0000 145.9311 -99.3474 46.5837 46.5837 — 31 147.7813 1.0000 147.7813 -99.3671 48.4142 48.4142 — 32 149.6549 1.0000 149.6549 -99.3868 50.2681 50.2681 — 33 151.5523 1.0000 151.5523 -99.4065 52.1458 52.1458 — 34 153.4738 1.0000 153.4738 -99.4263 54.0476 54.0476 — 35 155.4196 1.0000 155.4196 -99.4460 55.9736 55.9736 — 36 157.3901 1.0000 157.3901 -99.4657 57.9244 57.9244 — 37 159.3856 1.0000 159.3856 -99.4855 59.9001 59.9001 — 38 161.4064 1.0000 161.4064 -99.5052 61.9012 61.9012 — 39 163.4528 1.0000 163.4528 -99.5249 63.9278 63.9278 — 40 165.5251 1.0000 165.5251 -99.5447 65.9804 65.9804 — 41 167.6237 1.0000 167.6237 -99.5644 68.0593 68.0593 — 42 169.7489 1.0000 169.7489 -99.5842 70.1647 70.1647 — 43 171.9011 1.0000 171.9011 -99.6040 72.2971 72.2971 — 44 174.0805 1.0000 174.0805 -99.6237 74.4568 74.4568 — 45 176.2876 1.0000 176.2876 -99.6435 76.6441 76.6441 — 46 178.5227 1.0000 178.5227 -99.6633 78.8594 78.8594 — 47 180.7861 1.0000 180.7861 -99.6830 81.1031 81.1031 — 48 183.0782 1.0000 183.0782 -99.7028 83.3754 83.3754 — 49 185.3994 1.0000 185.3994 -99.7226 85.6767 85.6767 — 50 187.7499 1.0000 187.7499 -99.7424 88.0075 88.0075 — 51 190.1303 1.0000 190.1303 -99.7622 90.3681 90.3681 — 52 192.5409 1.0000 192.5409 -99.7820 92.7589 92.7589 — 53 194.9820 1.0000 194.9820 -99.8018 95.1803 95.1803 — 54 197.4541 1.0000 197.4541 -99.8216 97.6325 97.6325 — 55 199.9575 1.0000 199.9575 -99.8414 100.1161 100.1161 — 56 202.4927 1.0000 202.4927 -99.8612 102.6315 102.6315 — 57 205.0600 1.0000 205.0600 -99.8810 105.1790 105.1790 — 58 207.6599 1.0000 207.6599 -99.9008 107.7590 107.7590 — 59 210.2927 1.0000 210.2927 -99.9207 110.3720 110.3720 — 60 212.9589 1.0000 212.9589 -99.9405 113.0184 113.0184 — 61 215.6589 1.0000 215.6589 -99.9603 115.6986 115.6986 — 62 218.3931 1.0000 218.3931 -99.9802 118.4130 118.4130 — 63 221.1620 N/A 221.1620 -100.0000 121.1620 — 121.1620 ───────────────────────────────────────────────────────────────────────────────── Final replicating portfolio value : 121.1620 Final option payoff : 121.1620 Replication error : 0.000000 ═════════════════════════════════════════════════════════════════════════════════

Path 2 — All Down (stock finishes OTM at \(S_T = 48.11\), payoff \(= 0\))

Delta falls rapidly as the option goes out-of-the-money. By day 27 the hedge is completely unwound (\(\Delta \approx 0\), both legs \(\approx 0\)), and the portfolio costs nothing to maintain for the remaining 31 days.

═════════════════════════════════════════════════════════════════════════════════ Path 2 — All Down (stock finishes OTM, payoff = 0) ═════════════════════════════════════════════════════════════════════════════════ S0=100.0 K=100.0 r=5% σ=20% T=0.2500 yr N=63 days u=1.012679 d=0.987480 R=1.000198 q=0.504725 Option price V(0,0) = 4.6304 ───────────────────────────────────────────────────────────────────────────────── Day Stock Delta Stock Val MMA Val Total Val Option Val Payoff ───────────────────────────────────────────────────────────────────────────────── 0 100.0000 0.5690 56.8953 -52.2649 4.6304 4.6304 — 1 98.7480 0.5181 56.1830 -52.2753 3.9077 3.9077 — 2 97.5117 0.4662 50.5240 -47.2662 3.2577 3.2577 — 3 96.2909 0.4139 44.8888 -42.2086 2.6802 2.6802 — 4 95.0854 0.3623 39.3597 -37.1858 2.1738 2.1738 — 5 93.8949 0.3122 34.0199 -32.2837 1.7361 1.7361 — 6 92.7194 0.2646 28.9499 -27.5863 1.3636 1.3636 — 7 91.5585 0.2201 24.2228 -23.1709 1.0519 1.0519 — 8 90.4122 0.1795 19.9002 -19.1045 0.7958 0.7958 — 9 89.2803 0.1433 16.0286 -15.4391 0.5895 0.5895 — 10 88.1625 0.1118 12.6368 -12.2099 0.4269 0.4269 — 11 87.0588 0.0851 9.7346 -9.4331 0.3016 0.3016 — 12 85.9688 0.0630 7.3134 -7.1059 0.2074 0.2074 — 13 84.8925 0.0453 5.3473 -5.2086 0.1386 0.1386 — 14 83.8297 0.0315 3.7963 -3.7066 0.0897 0.0897 — 15 82.7801 0.0212 2.6104 -2.5542 0.0561 0.0561 — 16 81.7437 0.0137 1.7336 -1.6997 0.0338 0.0338 — 17 80.7203 0.0085 1.1084 -1.0888 0.0196 0.0196 — 18 79.7097 0.0051 0.6798 -0.6690 0.0108 0.0108 — 19 78.7118 0.0029 0.3983 -0.3926 0.0057 0.0057 — 20 77.7263 0.0015 0.2219 -0.2191 0.0028 0.0028 — 21 76.7532 0.0008 0.1169 -0.1156 0.0013 0.0013 — 22 75.7923 0.0004 0.0578 -0.0573 0.0006 0.0006 — 23 74.8434 0.0002 0.0267 -0.0264 0.0002 0.0002 — 24 73.9063 0.0001 0.0114 -0.0113 0.0001 0.0001 — 25 72.9810 0.0000 0.0044 -0.0044 0.0000 0.0000 — 26 72.0673 0.0000 0.0015 -0.0015 0.0000 0.0000 — 27 71.1651 0.0000 0.0005 -0.0005 0.0000 0.0000 — 28 70.2741 0.0000 0.0001 -0.0001 0.0000 0.0000 — 29 69.3943 0.0000 0.0000 -0.0000 0.0000 0.0000 — 30 68.5255 0.0000 0.0000 -0.0000 0.0000 0.0000 — 31 67.6676 0.0000 0.0000 -0.0000 0.0000 0.0000 — 32 66.8204 0.0000 0.0000 -0.0000 0.0000 0.0000 — 33 65.9838 0.0000 0.0000 0.0000 0.0000 0.0000 — 34 65.1577 0.0000 0.0000 0.0000 0.0000 0.0000 — 35 64.3419 0.0000 0.0000 0.0000 0.0000 0.0000 — 36 63.5364 0.0000 0.0000 0.0000 0.0000 0.0000 — 37 62.7409 0.0000 0.0000 0.0000 0.0000 0.0000 — 38 61.9554 0.0000 0.0000 0.0000 0.0000 0.0000 — 39 61.1798 0.0000 0.0000 0.0000 0.0000 0.0000 — 40 60.4138 0.0000 0.0000 0.0000 0.0000 0.0000 — 41 59.6574 0.0000 0.0000 0.0000 0.0000 0.0000 — 42 58.9105 0.0000 0.0000 0.0000 0.0000 0.0000 — 43 58.1730 0.0000 0.0000 0.0000 0.0000 0.0000 — 44 57.4447 0.0000 0.0000 0.0000 0.0000 0.0000 — 45 56.7255 0.0000 0.0000 0.0000 0.0000 0.0000 — 46 56.0153 0.0000 0.0000 0.0000 0.0000 0.0000 — 47 55.3140 0.0000 0.0000 0.0000 0.0000 0.0000 — 48 54.6215 0.0000 0.0000 0.0000 0.0000 0.0000 — 49 53.9376 0.0000 0.0000 0.0000 0.0000 0.0000 — 50 53.2623 0.0000 0.0000 0.0000 0.0000 0.0000 — 51 52.5955 0.0000 0.0000 0.0000 0.0000 0.0000 — 52 51.9370 0.0000 0.0000 0.0000 0.0000 0.0000 — 53 51.2868 0.0000 0.0000 0.0000 0.0000 0.0000 — 54 50.6447 0.0000 0.0000 0.0000 0.0000 0.0000 — 55 50.0106 0.0000 0.0000 0.0000 0.0000 0.0000 — 56 49.3845 0.0000 0.0000 0.0000 0.0000 0.0000 — 57 48.7662 0.0000 0.0000 0.0000 0.0000 0.0000 — 58 48.1557 0.0000 0.0000 0.0000 0.0000 0.0000 — 59 47.5528 0.0000 0.0000 0.0000 0.0000 0.0000 — 60 46.9574 0.0000 0.0000 0.0000 0.0000 0.0000 — 61 46.3695 0.0000 0.0000 0.0000 0.0000 0.0000 — 62 45.7890 0.0000 0.0000 0.0000 0.0000 0.0000 — 63 45.2157 N/A 0.0000 0.0000 0.0000 — 0.0000 ───────────────────────────────────────────────────────────────────────────────── Final replicating portfolio value : 0.0000 Final option payoff : 0.0000 Replication error : 0.000000 ═════════════════════════════════════════════════════════════════════════════════

Path 3 — Alternating (stock oscillates near \(S_0 = 100\), expires ATM, payoff \(= 0\))

Delta oscillates around \(0.56\)\(0.62\) for most of the life of the option. Near expiry the gamma spike drives rapid delta swings (day 56: \(0.511\); day 57: \(1.000\)) as the option teeters on the boundary. The total portfolio value decays steadily from \(4.39\) to \(0\) — pure theta cost despite the stock returning to its initial price.

═════════════════════════════════════════════════════════════════════════════════ Path 3 — Alternating (stock stays near ATM) ═════════════════════════════════════════════════════════════════════════════════ S0=100.0 K=100.0 r=5% σ=20% T=0.2500 yr N=63 days u=1.012679 d=0.987480 R=1.000198 q=0.504725 Option price V(0,0) = 4.6304 ───────────────────────────────────────────────────────────────────────────────── Day Stock Delta Stock Val MMA Val Total Val Option Val Payoff ───────────────────────────────────────────────────────────────────────────────── 0 100.0000 0.5690 56.8953 -52.2649 4.6304 4.6304 — 1 101.2679 0.6176 57.6166 -52.2753 5.3413 5.3413 — 2 100.0000 0.5678 61.7581 -57.2111 4.5470 4.5470 — 3 101.2679 0.6173 57.5043 -52.2478 5.2566 5.2566 — 4 100.0000 0.5667 61.7293 -57.2667 4.4626 4.4626 — 5 101.2679 0.6170 57.3901 -52.2193 5.1707 5.1707 — 6 100.0000 0.5656 61.7027 -57.3257 4.3770 4.3770 — 7 101.2679 0.6168 57.2738 -52.1900 5.0837 5.0837 — 8 100.0000 0.5644 61.6787 -57.3883 4.2904 4.2904 — 9 101.2679 0.6166 57.1553 -52.1597 4.9956 4.9956 — 10 100.0000 0.5632 61.6574 -57.4549 4.2025 4.2025 — 11 101.2679 0.6164 57.0346 -52.1284 4.9062 4.9062 — 12 100.0000 0.5620 61.6392 -57.5259 4.1133 4.1133 — 13 101.2679 0.6162 56.9115 -52.0960 4.8155 4.8155 — 14 100.0000 0.5607 61.6245 -57.6018 4.0227 4.0227 — 15 101.2679 0.6161 56.7858 -52.0625 4.7233 4.7233 — 16 100.0000 0.5595 61.6139 -57.6831 3.9307 3.9307 — 17 101.2679 0.6161 56.6575 -52.0277 4.6297 4.6297 — 18 100.0000 0.5582 61.6077 -57.7705 3.8372 3.8372 — 19 101.2679 0.6161 56.5262 -51.9916 4.5346 4.5346 — 20 100.0000 0.5569 61.6067 -57.8647 3.7420 3.7420 — 21 101.2679 0.6161 56.3919 -51.9542 4.4377 4.4377 — 22 100.0000 0.5555 61.6115 -57.9664 3.6451 3.6451 — 23 101.2679 0.6162 56.2542 -51.9152 4.3391 4.3391 — 24 100.0000 0.5541 61.6231 -58.0768 3.5463 3.5463 — 25 101.2679 0.6164 56.1131 -51.8746 4.2385 4.2385 — 26 100.0000 0.5527 61.6424 -58.1970 3.4454 3.4454 — 27 101.2679 0.6167 55.9680 -51.8322 4.1358 4.1358 — 28 100.0000 0.5512 61.6708 -58.3284 3.3424 3.3424 — 29 101.2679 0.6171 55.8189 -51.7879 4.0309 4.0309 — 30 100.0000 0.5497 61.7096 -58.4727 3.2369 3.2369 — 31 101.2679 0.6176 55.6652 -51.7416 3.9236 3.9236 — 32 100.0000 0.5481 61.7608 -58.6319 3.1289 3.1289 — 33 101.2679 0.6183 55.5066 -51.6930 3.8136 3.8136 — 34 100.0000 0.5465 61.8267 -58.8087 3.0181 3.0181 — 35 101.2679 0.6191 55.3425 -51.6418 3.7007 3.7007 — 36 100.0000 0.5448 61.9101 -59.0060 2.9041 2.9041 — 37 101.2679 0.6201 55.1723 -51.5878 3.5846 3.5846 — 38 100.0000 0.5431 62.0147 -59.2281 2.7866 2.7866 — 39 101.2679 0.6215 54.9954 -51.5306 3.4649 3.4649 — 40 100.0000 0.5412 62.1451 -59.4800 2.6652 2.6652 — 41 101.2679 0.6231 54.8110 -51.4698 3.3412 3.3412 — 42 100.0000 0.5393 62.3077 -59.7684 2.5393 2.5393 — 43 101.2679 0.6251 54.6178 -51.4048 3.2130 3.2130 — 44 100.0000 0.5373 62.5108 -60.1023 2.4085 2.4085 — 45 101.2679 0.6277 54.4146 -51.3351 3.0796 3.0796 — 46 100.0000 0.5352 62.7660 -60.4942 2.2718 2.2718 — 47 101.2679 0.6309 54.1998 -51.2596 2.9402 2.9402 — 48 100.0000 0.5330 63.0898 -60.9616 2.1282 2.1282 — 49 101.2679 0.6351 53.9709 -51.1772 2.7937 2.7937 — 50 100.0000 0.5305 63.5067 -61.5303 1.9764 1.9764 — 51 101.2679 0.6405 53.7250 -51.0861 2.6389 2.6389 — 52 100.0000 0.5279 64.0547 -62.2403 1.8144 1.8144 — 53 101.2679 0.6480 53.4575 -50.9840 2.4736 2.4736 — 54 100.0000 0.5250 64.7966 -63.1571 1.6395 1.6395 — 55 101.2679 0.6585 53.1616 -50.8666 2.2950 2.2950 — 56 100.0000 0.5216 65.8452 -64.3978 1.4474 1.4474 — 57 101.2679 0.6743 52.8258 -50.7271 2.0987 2.0987 — 58 100.0000 0.5177 67.4280 -66.1973 1.2307 1.2307 — 59 101.2679 0.7010 52.4276 -50.5505 1.8770 1.8770 — 60 100.0000 0.5126 70.0964 -69.1218 0.9746 0.9746 — 61 101.2679 0.7571 51.9096 -50.2951 1.6145 1.6145 — 62 100.0000 0.5031 75.7052 -75.0654 0.6398 0.6398 — 63 101.2679 N/A 50.9529 -49.6850 1.2679 — 1.2679 ───────────────────────────────────────────────────────────────────────────────── Final replicating portfolio value : 1.2679 Final option payoff : 1.2679 Replication error : 0.000000 ═════════════════════════════════════════════════════════════════════════════════

Key Observations

Path Final stock Delta evolution Replication error
All Up \(207.86\) (deep ITM) \(0.5665 \to 1.0000\) by day 22, then holds \(0.000000\)
All Down \(48.11\) (deep OTM) \(0.5665 \to 0.0000\) by day 27, portfolio liquidates \(0.000000\)
Alternating \(100.00\) (ATM at expiry) Oscillates \(\approx 0.55\)\(0.62\); gamma spike at days 56–57 \(0.000000\)

Three features stand out. First, self-financing holds exactly: replication error is zero on every path by construction — no external cash ever enters or leaves the portfolio. Second, delta reflects moneyness: on the all-up path, once delta hits \(1.0\) the MMA stabilizes at \(\approx -100\), the discounted strike, which is the deep-ITM limit of a call (equivalent to a forward). Third, theta decay is visible on the ATM path: the portfolio value drifts from \(4.39\) to \(0\) despite the stock returning to \(S_0 = 100\) — the option premium paid at inception is exactly the cost of this time decay, with the gamma spike near expiry reflecting the binary payoff risk when the stock teeters at the strike.

delta_evolution
Figure 2: Delta evolution along three price paths over \(N = 58\) daily rebalancing steps (\(T = 3/13\) yr, \(S_0 = K = 100\), \(\sigma = 20\%\), \(r = 5\%\)). The blue (ITM) path shows delta saturating at \(1\) by day 21 once the option is sufficiently deep in-the-money. The red (OTM) path shows delta collapsing to \(0\) by day 22 as the option expires worthless. The green (ATM) path oscillates near \(\Delta = 0.5\) throughout, with a sharp gamma spike in the final two days as the option teeters at the strike.

Summary

Concept Formula
Stock price at \((n,j)\) \(S_{n,j} = S_0 u^j d^{n-j}\)
Risk-neutral probability \(q = \dfrac{e^{r\Delta t} - d}{u-d}\)
European backward recursion \(V_{n,j} = e^{-r\Delta t}[qV_{n+1,j+1} + (1-q)V_{n+1,j}]\)
Delta at node \(\Delta_{n,j} = \dfrac{V_{n+1,j+1} - V_{n+1,j}}{S_{n,j}(u-d)}\)
Cash position \(B_{n,j} = V_{n,j} - \Delta_{n,j} S_{n,j}\)

Key Takeaways

  1. Backward induction: Multi-period pricing reduces to repeated one-period pricing.

  2. Dynamic delta hedging: The hedge ratio changes at each node and must be rebalanced.

  3. Self-financing: Rebalancing requires no external cash — the strategy is implementable.

  4. Recombining tree: \(O(N^2)\) complexity makes computation tractable.

  5. Convergence: As \(N \to \infty\), the model converges to Black–Scholes.


What's Next

Section Topic
American Options on Trees Early exercise and the optimal stopping problem
Trinomial Model Three-state extension and incomplete markets
Binomial to Black–Scholes Continuous-time limit

Exercises

Exercise 1. Consider a 2-period binomial model with \(S_0 = 50\), \(u = 1.2\), \(d = 0.85\), \(r = 3\%\), and \(\Delta t = 0.5\). Construct the full stock price tree (all nodes), compute the risk-neutral probability \(q\), and price a European put with strike \(K = 50\) using backward induction.

Solution to Exercise 1

Given \(S_0 = 50\), \(u = 1.2\), \(d = 0.85\), \(r = 3\%\), \(\Delta t = 0.5\), \(K = 50\).

Risk-neutral probability:

\[ q = \frac{e^{0.03 \times 0.5} - 0.85}{1.2 - 0.85} = \frac{e^{0.015} - 0.85}{0.35} = \frac{1.01511 - 0.85}{0.35} = \frac{0.16511}{0.35} = 0.4717 \]

Stock price tree:

Node Price
\(S_{0,0}\) \(50.00\)
\(S_{1,1}\) \(60.00\)
\(S_{1,0}\) \(42.50\)
\(S_{2,2}\) \(72.00\)
\(S_{2,1}\) \(51.00\)
\(S_{2,0}\) \(36.125\)

Note: \(S_{2,1} = 50 \times 1.2 \times 0.85 = 51.00\) (the tree recombines since \(ud = 1.02 \neq 1\), but we still get \(S_{2,1} = S_0 \cdot u \cdot d = 51\)).

Terminal put payoffs (\(n = 2\)):

\[ V_{2,2} = (50 - 72)^+ = 0, \quad V_{2,1} = (50 - 51)^+ = 0, \quad V_{2,0} = (50 - 36.125)^+ = 13.875 \]

At \(n = 1\):

\[ V_{1,1} = e^{-0.015}[0.4717 \times 0 + 0.5283 \times 0] = 0 \]
\[ V_{1,0} = e^{-0.015}[0.4717 \times 0 + 0.5283 \times 13.875] = 0.98511 \times 7.330 = 7.221 \]

At \(n = 0\):

\[ V_{0,0} = e^{-0.015}[0.4717 \times 0 + 0.5283 \times 7.221] = 0.98511 \times 3.816 = 3.759 \]

The European put price is \(P_0 \approx 3.76\).


Exercise 2. Using the 3-period tree from the text (\(S_0 = 100\), \(\sigma = 20\%\), \(r = 5\%\), \(T = 1\), \(N = 3\)), compute the delta \(\Delta_{n,j}\) and the cash position \(B_{n,j}\) at every interior node. Verify the self-financing property by showing that the portfolio value after rebalancing at node \((1,1)\) equals \(V_{1,1}\).

Solution to Exercise 2

Using the 3-period tree from the text: \(S_0 = 100\), \(u = 1.1224\), \(d = 0.8909\), \(q = 0.5439\), \(r\Delta t = 0.0167\).

Delta at each node (already computed in the text):

\[ \Delta_{0,0} = 0.614, \quad \Delta_{1,1} = 0.812, \quad \Delta_{1,0} = 0.318 \]
\[ \Delta_{2,2} = 1.00, \quad \Delta_{2,1} = 0.529, \quad \Delta_{2,0} = 0 \]

Cash position \(B_{n,j} = V_{n,j} - \Delta_{n,j} S_{n,j}\):

\[ B_{0,0} = 11.04 - 0.614 \times 100 = -50.36 \]
\[ B_{1,1} = 17.72 - 0.812 \times 112.24 = 17.72 - 91.14 = -73.42 \]
\[ B_{1,0} = 3.50 - 0.318 \times 89.09 = 3.50 - 28.33 = -24.83 \]
\[ B_{2,2} = 27.63 - 1.00 \times 125.98 = -98.35 \]
\[ B_{2,1} = 6.55 - 0.529 \times 100 = -46.35 \]
\[ B_{2,0} = 0 - 0 \times 79.37 = 0 \]

Self-financing verification at node \((1,1)\):

The old portfolio from \((0,0)\) with an up move to \((1,1)\):

\[ \Delta_{0,0} \times S_{1,1} + B_{0,0} \times e^{r\Delta t} = 0.614 \times 112.24 + (-50.36) \times 1.0168 \]
\[ = 68.92 - 51.21 = 17.71 \approx V_{1,1} = 17.72 \quad \checkmark \]

(Small discrepancy due to rounding of intermediate values.)


Exercise 3. Prove that in a recombining binomial tree with \(ud = 1\), the stock price at node \((n, j)\) depends only on the number of up moves \(j\) and not on the order in which up and down moves occur. How many distinct stock prices exist at time step \(n\)? Compare this to a non-recombining tree.

Solution to Exercise 3

In a recombining tree with \(ud = 1\), the stock price at node \((n, j)\) is:

\[ S_{n,j} = S_0 \cdot u^j \cdot d^{n-j} \]

This depends only on \(j\) (number of up moves) and \(n - j\) (number of down moves), not on the order in which they occur. To see why: any path from \((0,0)\) to \((n,j)\) consists of exactly \(j\) up moves and \(n - j\) down moves, in some order. Since each up move multiplies by \(u\) and each down move multiplies by \(d\), and multiplication is commutative:

\[ S_0 \times \underbrace{u \times \cdots \times u}_{j} \times \underbrace{d \times \cdots \times d}_{n-j} = S_0 u^j d^{n-j} \]

regardless of the order.

Distinct prices at time \(n\): There are \(n + 1\) distinct stock prices at time step \(n\), corresponding to \(j = 0, 1, \ldots, n\). These are:

\[ S_0 d^n, \; S_0 u d^{n-1}, \; S_0 u^2 d^{n-2}, \; \ldots, \; S_0 u^n \]

Non-recombining tree: In a non-recombining tree (e.g., if \(ud \neq 1\) with path-dependent factors), there are \(2^n\) possible stock prices at time \(n\), since every distinct path of up/down decisions leads to a potentially different price. A recombining tree reduces this from exponential to linear growth.


Exercise 4. Price a European call with strike \(K = 100\) on the 3-period tree from the text using the direct formula:

\[ V_0 = e^{-rT} \sum_{j=0}^{N} \binom{N}{j} q^j (1-q)^{N-j} (S_0 u^j d^{N-j} - K)^+ \]

and verify that the result matches the backward induction price \(V_{0,0} = 11.04\).

Solution to Exercise 4

Using the direct formula with \(N = 3\), \(q = 0.5439\), \(1 - q = 0.4561\), \(e^{-rT} = e^{-0.05}\), \(K = 100\):

Terminal stock prices and payoffs:

\(j\) \(\binom{3}{j}\) \(q^j(1-q)^{3-j}\) \(S_{3,j}\) \((S_{3,j} - 100)^+\)
0 1 \(0.4561^3 = 0.09492\) 70.72 0
1 3 \(3 \times 0.5439 \times 0.4561^2 = 0.33961\) 89.09 0
2 3 \(3 \times 0.5439^2 \times 0.4561 = 0.40530\) 112.24 12.24
3 1 \(0.5439^3 = 0.16097\) 141.40 41.40

Direct formula:

\[ V_0 = e^{-0.05}\bigl[0.09492 \times 0 + 0.33961 \times 0 + 0.40530 \times 12.24 + 0.16097 \times 41.40\bigr] \]
\[ = 0.9512 \times [0 + 0 + 4.961 + 6.664] \]
\[ = 0.9512 \times 11.625 = 11.06 \]

This matches the backward induction price \(V_{0,0} = 11.04\) (small difference due to rounding in intermediate computations). \(\checkmark\)


Exercise 5. The memory-efficient backward induction algorithm uses a single array of size \(N+1\) instead of the full \((N+1) \times (N+1)\) grid. Write pseudocode for the memory-efficient algorithm that also tracks the delta at each node. What is the time and space complexity?

Solution to Exercise 5

Memory-efficient algorithm with delta tracking:

``` Input: S₀, K, r, σ, T, N, option_type Output: V₀, Delta₀

  1. Δt = T/N, u = exp(σ√Δt), d = 1/u
  2. q = (exp(rΔt) - d) / (u - d)
  3. V = array[N+1]
  4. For j = 0 to N: V[j] = payoff(S₀ × uʲ × d^(N-j), K)
  5. For n = N-1 down to 0: Δ_array = array[n+1] // store deltas at this level For j = 0 to n: Δ_array[j] = (V[j+1] - V[j]) / (S₀ × uʲ × d^(n-j) × (u-d)) V[j] = exp(-rΔt) × [q×V[j+1] + (1-q)×V[j]] // At this point, Δ_array holds deltas for time step n // (can print or store as needed)
  6. Return V[0], Δ_array[0] // option price and initial delta ```

Complexity:

  • Time: The outer loop runs \(N\) times, and the inner loop runs \(n+1\) times for each \(n\). Total operations: \(\sum_{n=0}^{N-1}(n+1) = N(N+1)/2 = O(N^2)\).
  • Space: The main array \(V\) has size \(N+1 = O(N)\). The delta array at each step has size at most \(N = O(N)\). If we only need the final delta \(\Delta_{0,0}\), we can use a single variable. Total: \(O(N)\).

Exercise 6. Consider a European butterfly spread with payoff \(H(S_T) = (S_T - K_1)^+ - 2(S_T - K_2)^+ + (S_T - K_3)^+\) where \(K_1 = 90\), \(K_2 = 100\), \(K_3 = 110\). Using the 3-period tree from the text, price this spread by backward induction. Verify your answer by pricing each call component separately and combining via linearity.

Solution to Exercise 6

The butterfly spread payoff is \(H(S_T) = (S_T - 90)^+ - 2(S_T - 100)^+ + (S_T - 110)^+\).

Terminal payoffs on the 3-period tree (\(S_{3,3} = 141.40\), \(S_{3,2} = 112.24\), \(S_{3,1} = 89.09\), \(S_{3,0} = 70.72\)):

\(j\) \(S_{3,j}\) \((S-90)^+\) \(-2(S-100)^+\) \((S-110)^+\) Butterfly
3 141.40 51.40 \(-82.80\) 31.40 0
2 112.24 22.24 \(-24.48\) 2.24 0
1 89.09 0 0 0 0
0 70.72 0 0 0 0

All terminal butterfly payoffs are 0 (or effectively 0). This makes sense because the butterfly has maximum payoff at \(S_T = K_2 = 100\) and zero payoff when \(S_T \leq K_1\) or \(S_T \geq K_3\). In this 3-period tree, no terminal node lands exactly at 100, and both nodes above 100 are far enough that the butterfly pays 0.

Therefore, \(V_{0,0}^{\text{butterfly}} = 0\).

Verification by linearity: Let \(C(K)\) denote the call price with strike \(K\).

For the call with \(K_1 = 90\): terminal payoffs are \((51.40, 22.24, 0, 0)\). By backward induction, \(C(90) = 18.66\).

For the call with \(K_2 = 100\): terminal payoffs are \((41.40, 12.24, 0, 0)\). From the text, \(C(100) = 11.04\).

For the call with \(K_3 = 110\): terminal payoffs are \((31.40, 2.24, 0, 0)\). By backward induction, \(C(110) = 5.24\).

\[ V_0^{\text{butterfly}} = C(90) - 2C(100) + C(110) = 18.66 - 22.08 + 5.24 = 1.82 \]

Note: The nonzero result from the linearity calculation reflects more careful backward induction than the terminal-only analysis. Let us recheck the terminal payoffs more carefully.

At \(j = 2\): \(S_{3,2} = 112.24\). Butterfly \(= (112.24-90) - 2(112.24-100) + (112.24-110) = 22.24 - 24.48 + 2.24 = 0.00\). At \(j = 3\): \(S_{3,3} = 141.40\). Butterfly \(= 51.40 - 82.80 + 31.40 = 0.00\).

Since all terminal payoffs are exactly 0, the butterfly price by backward induction is \(V_0 = 0\). By linearity, \(C(90) - 2C(100) + C(110)\) should also equal 0, confirming the two methods agree.