Binomial Tree Option Pricer

Options Pricing · Medium · Free problem

Implement a recombining binomial tree to price options under the Cox-Ross-Rubinstein (CRR) model with $N$ time steps.

Define the function binomial_price(S0, K, r, sigma, T, N, option_type, exercise):

  • S0 stock price, K strike, r risk-free rate, sigma volatility, T time to expiry, N number of steps.
  • option_type is 'call' or 'put'.
  • exercise is 'european' or 'american' (American allows early exercise).

Requirements:

  1. Use CRR parameters with $\\Delta t = T/N$: $u = e^{\\sigma\\sqrt{\\Delta t}}$, $d = 1/u$, $q = (e^{r\\Delta t} - d)/(u - d)$.
  2. Backward-induct the discounted risk-neutral expectation; for 'american', take $\\max(\\text{continuation}, \\text{immediate exercise})$ at every node.
  3. Return the present value at the root as a float.
  4. Run in $O(N^2)$ time and $O(N)$ memory.

Constraints: - $1 \\leq N \\leq 10{,}000$ - $S_0, K, r, \\sigma, T > 0$

Example

binomial_price(100, 100, 0.05, 0.2, 1.0, 200, 'call', 'european') -> 10.440591259859872

A 200-step CRR tree prices this at-the-money European call, matching the Black-Scholes value of about 10.45 to two decimals.

Hints

  1. The tree is recombining because $u \cdot d = 1$, so an up followed by a down returns to the same price. This reduces $2^N$ nodes to $O(N^2)$ total.
  2. For $O(N)$ memory, use a single array of size $N+1$ and overwrite it in place during backward induction -- you only ever need the values from the next time step.
  3. For the American put, at each node during backward induction, compare the continuation value $e^{-r\Delta t}(qV_{j+1} + (1-q)V_j)$ against the immediate exercise value $\max(K - S, 0)$ and take the larger.

Worked Solution

How to Think About It: A binomial tree discretizes the continuous stock price process into $N$ time steps. At each step, the stock goes up by factor $u$ or down by factor $d$. Under risk-neutral pricing, you discount expected payoffs at the risk-free rate, using the risk-neutral probability $q$ (not the real-world probability). The tree is recombining ($u \\cdot d = 1$), so after $N$ steps there are only $N+1$ distinct stock prices instead of $2^N$ -- this is what makes $O(N^2)$ possible. For the American option, at each node you check whether exercising early beats the continuation value. The key trick for $O(N)$ memory: keep one array of option values, updated backwards from expiry.

CRR Parameters (with $\\Delta t = T/N$):

$$u = e^{\\sigma \\sqrt{\\Delta t}}, \\quad d = e^{-\\sigma \\sqrt{\\Delta t}} = 1/u, \\quad q = \\frac{e^{r \\Delta t} - d}{u - d}$$

The risk-neutral probability $q$ ensures $q \\cdot u + (1-q) \\cdot d = e^{r \\Delta t}$.

Backward Induction:

1. Compute the $N+1$ terminal stock prices $S_j = S_0 \\cdot u^{2j - N}$ and their payoffs ($\\max(S_j-K,0)$ for a call, $\\max(K-S_j,0)$ for a put). 2. Step backwards from $i = N-1$ to $0$: continuation value $C_j = e^{-r\\Delta t}(q V_{j+1} + (1-q) V_j)$. - European: $V_j = C_j$. - American: $V_j = \\max(C_j, \\text{exercise value at node }(i,j))$. 3. The price is $V_0$.

Signature: binomial_price(S0, K, r, sigma, T, N, option_type, exercise) where option_type is 'call' or 'put' and exercise is 'european' or 'american'. It returns the present value at the root as a float.

Code:

```python import math

def binomial_price(S0, K, r, sigma, T, N, option_type, exercise): dt = T / N u = math.exp(sigma * math.sqrt(dt)) d = 1.0 / u q = (math.exp(r * dt) - d) / (u - d) disc = math.exp(-r * dt)

# Terminal stock prices and payoffs V = [0.0] * (N + 1) for j in range(N + 1): S = S0 * (u ** (2 * j - N)) if option_type == 'call': V[j] = max(S - K, 0.0) else: V[j] = max(K - S, 0.0)

# Backward induction for i in range(N - 1, -1, -1): for j in range(i + 1): V[j] = disc * (q * V[j + 1] + (1 - q) * V[j]) if exercise == 'american': S = S0 * (u ** (2 * j - i)) if option_type == 'call': V[j] = max(V[j], S - K) else: V[j] = max(V[j], K - S)

return V[0]

```

Convergence: Compare against the closed-form Black-Scholes price for a European call, running $N = 50, 100, 200, 500, 1000$. The binomial price oscillates around Black-Scholes (even/odd $N$ effect) with error decreasing as $O(1/N)$; convergence follows from the CLT applied to the log-return distribution.

Complexity: Time $O(N^2)$ (triangle of nodes), space $O(N)$ (single reused array of size $N+1$).

Intuition

The binomial tree is the workhorse numerical method for option pricing before you reach for Monte Carlo or PDE solvers. Its power comes from the recombining property: because $u \cdot d = 1$, an up-down and a down-up reach the same node, collapsing the exponential tree into a triangular grid. This is exactly the same insight that makes dynamic programming efficient -- overlapping subproblems.

The American put is where the tree truly shines. Unlike European options (which have closed-form Black-Scholes prices), American options require checking for early exercise at every node. The backward induction naturally handles this: at each node, you compare "exercise now" vs. "hold and continue," which is a Bellman equation. This is why trees remain the standard method for American option pricing in practice, even though Monte Carlo and finite difference methods are used for more exotic products.

Open the full interactive solver →