4  Binomial Trees

This chapter introduces binomial tree models for valuing derivative securities. We begin with the fundamental concepts of arbitrage pricing in a one-period model, extend to multi-period trees, and then discuss practical implementation and parameter calibration.

4.1 One-Period Binomial Model

We start with the simplest possible model. A stock has price \(S\) today (date 0) and will have one of two possible values at date \(t\): either \(S_u\) (up state) or \(S_d\) (down state), where \(S_u > S_d\). There is also a risk-free asset earning a continuously compounded rate \(r\), so the gross return of the risk-free asset between 0 and \(t\) is \(\mathrm{e}^{rt}\).

We assume that \(S_u/S > \mathrm{e}^{rt}>S_d/S_0\). This ensures that neither asset dominates the other in the sense of always having an equal or higher return. If such a dominance were to exist, then riskless profits could be made by going long the high return asset and short the low return asset. We call a riskless profitable trade an arbitrage. Thus, we call our assumption that \(S_u/S > \mathrm{e}^{rt}>S_d/S_0\) a no-arbitrage assumption. It is very reasonable to assume there are no arbitrage opportunities in the market, because they would be quickly exploited by market participants, whose trades cause prices to move so that the opportunities vanish.

Deltas and Replication

Consider a European call option with strike \(K\) and maturity \(t\). Its payoff will be \(C_u = \max(0, S_u - K)\) in the up state and \(C_d = \max(0, S_d - K)\) in the down state. A key insight is that we can replicate the option payoff in this simple model using a portfolio of the stock and risk-free asset. This insight extends to more realistic models, as we will see later.

Define

\[\delta = \frac{C_u - C_d}{S_u - S_d} \qquad(4.1)\]

and consider buying \(\delta\) shares of the stock and borrowing an amount \(B\) at the risk-free rate. The portfolio value at maturity will be \(\delta S_u - B e^{rt}\) in the up state and \(\delta S_d - B e^{rt}\) in the down state. For replication, we need these to equal the option payoff: \[\delta S_u - B e^{rt} = C_u\,,\] \[\delta S_d - B e^{rt} = C_d\,.\]

Subtracting the second equation from the first gives \[\delta(S_u - S_d) = C_u - C_d\,.\]

This is the same as our delta formula Equation 4.1. We can solve for the amount to borrow:

\[B = e^{-rt}(\delta S_u - C_u) = e^{-rt}(\delta S_d - C_d)\,.\]

The initial cost of this replicating portfolio is: \[\text{Portfolio Cost} = \delta S - B = \delta S - e^{-rt}(\delta S_u - C_u)\,.\]

If the portfolio were cheaper than the call option, then there would be an arbitrage opportunity—buy the portfolio and sell the call. The reverse trade would be an arbitrage if the portfolio were more expensive than the call option. Therefore, the assumption that there are no arbitrage opportunities implies that the call option must trade for \(C\) defined as

\[C = \delta S - e^{-rt}(\delta S_u - C_u)\,. \qquad(4.2)\]

Suppose \(S = 100\), \(S_u = 110\), \(S_d = 90\), \(K = 105\), \(r = 0.05\), \(t = 1\). Then:

  • \(C_u = \max(0, 110 - 105) = 5\)
  • \(C_d = \max(0, 90 - 105) = 0\)
  • \(\delta = \frac{5 - 0}{110 - 90} = 0.25\)
  • \(B = e^{-0.05}(0.25 \times 110 - 5) = e^{-0.05} \times 22.5 \approx 21.43\)
  • Option price \(= 0.25 \times 100 - 21.43 = 3.57\)

Verification: In the up state, the portfolio is worth \(0.25 \times 110 - 22.5 = 5\), matching \(C_u\). In the down state, it’s worth \(0.25 \times 90 - 22.5 = 0\), matching \(C_d\). Thus, by buying 0.25 shares and borrowing $21.43, we can perfectly replicate the option payoff.

State Prices

Define

\[\pi_u = \frac{S - \mathrm{e}^{-rt}S_d}{S_u - S_d}, \quad \pi_d = \frac{\mathrm{e}^{-rt}S_u - S}{S_u - S_d}\,.\]

We can rearrange Equation 4.2 to obtain \[C = \pi_u C_u + \pi_d C_d\,. \qquad(4.3)\] We can also confirm by simple algebra that \[S = \pi_u S_u + \pi_d S_d \qquad(4.4)\] and \[1 = \pi_u \mathrm{e}^{rt} + \pi_d \mathrm{e}^{rt}\,. \qquad(4.5)\]

It is useful to envision hypothetical securities that pay $1 in a single state and 0 in the other. We can regard \(\pi_u\) as the price of the up security and \(\pi_d\) as the price of the down security.1 We call them state prices. Equation 4.3Equation 4.5 show that we can value each of the actual assets—the call option, the underlying asset, and the risk-free asset—as a portfolio, breaking the asset down into a payoff in the up state and a payoff in the down state and pricing the payoffs using the state prices. Our no-arbitrage condition \(S_u/S > \mathrm{e}^{rt} > S_d/S\) implies that the state prices are positive—it costs something today to get something in the future.

Risk-Neutral Pricing

Rather than working directly with state prices, it is conventional to make a simple transformation. Define \(p_u = \mathrm{e}^{rt}\pi_u\) and \(p_d = \mathrm{e}^{rt}\pi_d\). We have \(p_u+p_d=1\) and our no-arbitrage assumption implies that \(p_u>0\) and \(p_d>0\). This makes it possible to view \(p_u\) and \(p_d\) as artificial probabilities. We make no claim that they represent anyone’s beliefs, but they have the mathematical properties of probabilities. They are universally called the risk-neutral probabilities. The motivation for this terminology is that Equation 4.3 and Equation 4.4 can be rewritten as

\[C = \mathrm{e}^{-rt}\big[p_u C_u + p_dC_d\big]\,. \qquad(4.6)\] \[S = \mathrm{e}^{-rt}\big[p_u S_u + p_dS_d\big]\,. \qquad(4.7)\]

These equations state that each risky asset can be valued as its expected value discounted at the risk-free rate, when we calculate the expected values using the risk-neutral probabilities. This is how securities would be valued if investors were risk neutral, using the investors’ actual beliefs. We do not assume that investors are risk neutral; nevertheless, we can compute option values as if investors were risk-neutral, by using the risk-neutral probabilities as their beliefs. Rather than risk neutrality, all that we are assuming is that there are no arbitrage opportunities. Thus, the absence of arbitrage opportunities allows us to do risk-neutral pricing in the form of Equation 4.6 and Equation 4.7.

Our rather circuitous calculation of the risk-neutral probabilities via the state prices can be streamlined. We can calculate the risk-neutral probabilities directly as \[p_u = \frac{\mathrm{e}^{rt} - S_d/S}{S_u/S - S_d/S} \qquad(4.8)\] and \(p_d = 1-p_u\). Both the numerator and denominator on the right-hand side of Equation 4.8 are differences of returns: the difference between the risk-free return and the underlying asset’s down return in the numerator and the difference between the up and down returns of the underlying asset in the denominator. We will use the same calculation for multiperiod trees.

4.2 Two-Period Model

Now consider a two-period model where the stock price evolves over two time steps of length \(\Delta t = t/2\). To simplify notation and ensure that the tree recombines, we parameterize the price movements using multiplicative factors \(u > 1\) and \(d = 1/u < 1\).

Starting from \(S\), after one period the stock price is either \(uS\) or \(dS\). After two periods, the possible prices are:

  • \(u^2S\) (two up moves)
  • \(udS = S\) (one up, one down)
  • \(d^2S\) (two down moves)

The tree recombines because \(ud = du = 1\), so the middle node has price \(S\) regardless of the path taken.

Define the risk-neutral probabilities as in Equation 4.8, replacing \(t\) with \(t/2\) (because \(S_u/S\) and \(S_d/S\) are now returns over periods of length \(t/2\)). We can write this in a form that generalizes more readily as \[p_u = \frac{\mathrm{e}^{r\Delta t} - S_d/S}{S_u/S - S_d/S} \qquad(4.9)\] and \(p_d=1-p_u\).

Backward Induction Process

The key to valuing options in multi-period trees is backward induction. We start at maturity and work backwards to find today’s value.

Step 1: Final Period (t = 2) Calculate option payoffs at each terminal node:

  • Node (2,2): \(C_{uu} = \max(0, u^2S - K)\)
  • Node (2,1): \(C_{ud} = \max(0, udS - K) = \max(0, S - K)\)
  • Node (2,0): \(C_{dd} = \max(0, d^2S - K)\)

Step 2: Intermediate Period (t = 1) At each node, calculate the option value as the discounted risk-neutral expectation of the next period’s values.

At the up node (1,1) with stock price \(uS\): \[C_u = e^{-r\Delta t}[p \cdot C_{uu} + (1-p) \cdot C_{ud}]\]

At the down node (1,0) with stock price \(dS\): \[C_d = e^{-r\Delta t}[p \cdot C_{ud} + (1-p) \cdot C_{dd}]\]

Step 3: Initial Period (t = 0) Finally, calculate today’s option value: \[C_0 = e^{-r\Delta t}[p \cdot C_u + (1-p) \cdot C_d]\]

For American Options: At each intermediate node, compare the continuation value with immediate exercise: - Up node: \(C_u = \max(\text{continuation value}, \max(0, uS - K))\) - Down node: \(C_d = \max(\text{continuation value}, \max(0, dS - K))\)

This backward induction process automatically finds the optimal exercise strategy by comparing holding versus exercising at each node. The following code is a somewhat inefficient implementation in which the backward induction process should be transparent. We will later accelerate it by vectorizing.

Code
import numpy as np
def binomial_american_detailed(S0, K, r, sigma, T, N, option_type='put'):
    """
    Price American option using binomial tree with detailed backward induction
    
    This function shows exactly how backward induction works step by step
    """
    # Step 1: Set up tree parameters
    dt = T / N                          # Time per step
    u = np.exp(sigma * np.sqrt(dt))     # Up factor
    d = 1 / u                           # Down factor (ensures recombining tree)
    p = (np.exp(r * dt) - d) / (u - d)  # Risk-neutral probability
    disc = np.exp(-r * dt)              # Discount factor
    
    print(f"Tree parameters: u={u:.4f}, d={d:.4f}, p={p:.4f}")
    
    # Step 2: Initialize option values at maturity (time N)
    # At maturity, we have N+1 possible stock prices
    V = np.zeros(N+1)  # Option values
    S = np.zeros(N+1)  # Stock prices
    
    for j in range(N+1):
        S[j] = S0 * (u**j) * (d**(N-j))  # Stock price at node j
        if option_type == 'call':
            V[j] = max(0, S[j] - K)      # Call payoff
        else:
            V[j] = max(0, K - S[j])      # Put payoff
    
    print(f"\nAt maturity (time {N}):")
    print(f"Stock prices: {[f'{s:.2f}' for s in S]}")
    print(f"Option values: {[f'{v:.4f}' for v in V]}")
    
    # Step 3: Backward induction through the tree
    for i in range(N-1, -1, -1):  # Work backwards from time N-1 to 0
        print(f"\nTime step {i}:")
        
        # At time i, we have i+1 nodes
        new_V = np.zeros(i+1)
        new_S = np.zeros(i+1)
        
        for j in range(i+1):
            # Stock price at this node
            new_S[j] = S0 * (u**j) * (d**(i-j))
            
            # Continuation value (discounted expected value)
            continuation = disc * (p * V[j+1] + (1-p) * V[j])
            
            # Immediate exercise value
            if option_type == 'call':
                exercise = max(0, new_S[j] - K)
            else:
                exercise = max(0, K - new_S[j])
            
            # American option: take maximum of continuation and exercise
            new_V[j] = max(continuation, exercise)
            
            print(f"  Node {j}: S={new_S[j]:.2f}, Cont={continuation:.4f}, "
                  f"Exercise={exercise:.4f}, Value={new_V[j]:.4f}")
        
        # Update for next iteration
        V = new_V.copy()
        S = new_S.copy()
    
    return V[0]

# Example with small tree to see the process
print("Detailed backward induction for 2-step American put:")
S0, K, r, sigma, T, N = 100, 105, 0.05, 0.2, 1.0, 2
put_value = binomial_american_detailed(S0, K, r, sigma, T, N, 'put')
print(f"\nFinal American put value: {put_value:.4f}")
Detailed backward induction for 2-step American put:
Tree parameters: u=1.1519, d=0.8681, p=0.5539

At maturity (time 2):
Stock prices: ['75.36', '100.00', '132.69']
Option values: ['29.6362', '5.0000', '0.0000']

Time step 1:
  Node 0: S=86.81, Cont=15.5952, Exercise=18.1877, Value=18.1877
  Node 1: S=115.19, Cont=2.1754, Exercise=0.0000, Value=2.1754

Time step 0:
  Node 0: S=100.00, Cont=9.0883, Exercise=5.0000, Value=9.0883

Final American put value: 9.0883

The numerical output above shows the exact backward induction process for our 2-step example. Let’s visualize this same tree to better understand how the calculations flow through the nodes:

Code
import pydot
from IPython.display import Image, display
import numpy as np

# Use the same parameters as the detailed example above
S0 = 100  # Initial stock price
K = 105   # Strike price  
r = 0.05  # Risk-free rate
sigma = 0.2  # Volatility
T = 1.0   # Time to maturity
N = 2     # Number of periods

# Calculate tree parameters
dt = T / N
u = np.exp(sigma * np.sqrt(dt))
d = 1 / u
p = (np.exp(r * dt) - d) / (u - d)
disc = np.exp(-r * dt)

# Calculate all stock prices and option values using same logic as detailed function
V = np.zeros(N+1)  # Option values
S = np.zeros(N+1)  # Stock prices

# Time 2 (maturity) - put option payoffs
for j in range(N+1):
    S[j] = S0 * (u**j) * (d**(N-j))
    V[j] = max(0, K - S[j])  # Put payoff

S_20, S_21, S_22 = S[0], S[1], S[2]
V_20, V_21, V_22 = V[0], V[1], V[2]

# Time 1 - backward induction  
V_new = np.zeros(2)
S_new = np.zeros(2)
for j in range(2):
    S_new[j] = S0 * (u**j) * (d**(1-j))
    continuation = disc * (p * V[j+1] + (1-p) * V[j])
    exercise = max(0, K - S_new[j])
    V_new[j] = max(continuation, exercise)

S_10, S_11 = S_new[0], S_new[1]
V_10, V_11 = V_new[0], V_new[1]
V = V_new.copy()

# Time 0 - final backward induction
S_00 = S0
continuation = disc * (p * V[1] + (1-p) * V[0])
exercise = max(0, K - S_00)
V_00 = max(continuation, exercise)

# Create the graph
graph = pydot.Dot(graph_type='digraph', rankdir='LR', bgcolor='white')
graph.set_node_defaults(shape='circle', style='filled', fillcolor='lightblue', 
                       fontname='Arial', fontsize='9')
graph.set_edge_defaults(fontname='Arial', fontsize='8')

# Time 0
graph.add_node(pydot.Node('t0', 
                         label=f't=0\\nS={S_00:.2f}\\nV={V_00:.4f}',
                         fillcolor='lightgreen'))

# Time 1
graph.add_node(pydot.Node('t1_u', 
                         label=f't=1 Up\\nS={S_11:.2f}\\nV={V_11:.4f}',
                         fillcolor='lightyellow'))
graph.add_node(pydot.Node('t1_d', 
                         label=f't=1 Down\\nS={S_10:.2f}\\nV={V_10:.4f}',
                         fillcolor='lightyellow'))

# Time 2 (maturity)
graph.add_node(pydot.Node('t2_uu', 
                         label=f't=2 UU\\nS={S_22:.2f}\\nV={V_22:.4f}',
                         fillcolor='lightcoral'))
graph.add_node(pydot.Node('t2_ud', 
                         label=f't=2 UD\\nS={S_21:.2f}\\nV={V_21:.4f}',
                         fillcolor='lightcoral'))
graph.add_node(pydot.Node('t2_dd', 
                         label=f't=2 DD\\nS={S_20:.2f}\\nV={V_20:.4f}',
                         fillcolor='lightcoral'))

# Add edges
graph.add_edge(pydot.Edge('t0', 't1_u', label=f'p={p:.3f}'))
graph.add_edge(pydot.Edge('t0', 't1_d', label=f'1-p={1-p:.3f}'))

graph.add_edge(pydot.Edge('t1_u', 't2_uu', label=f'p={p:.3f}'))
graph.add_edge(pydot.Edge('t1_u', 't2_ud', label=f'1-p={1-p:.3f}'))
graph.add_edge(pydot.Edge('t1_d', 't2_ud', label=f'p={p:.3f}'))
graph.add_edge(pydot.Edge('t1_d', 't2_dd', label=f'1-p={1-p:.3f}'))

# Save and display
graph.write_png('two_step_tree.png')
display(Image('two_step_tree.png'))

print(f"Tree parameters matching the numerical example:")
print(f"u = {u:.4f}, d = {d:.4f}")
print(f"Risk-neutral probability p = {p:.4f}")
print(f"\nThis tree shows the exact same values computed in the numerical output above.")
Figure 4.1: Two-step binomial tree showing the same numerical example with backward induction
Tree parameters matching the numerical example:
u = 1.1519, d = 0.8681
Risk-neutral probability p = 0.5539

This tree shows the exact same values computed in the numerical output above.

The tree visualization above corresponds exactly to the numerical backward induction process shown in the previous output. You can verify that the option values at each node match the calculations displayed in the step-by-step algorithm.

4.3 N-Period Model

The extension to N periods is straightforward. With parameters \(u\) and \(d = 1/u\), after \(n\) periods we have \(n+1\) nodes with stock prices:

\[S_j = u^j d^{n-j} S = u^{2j-n} S, \quad j = 0, 1, \ldots, n\]

The critical insight for efficient implementation is backward induction rather than computing all possible paths.

Interactive N-Period Trees

Now let’s explore how N-period binomial trees behave with different parameters using an interactive tool:

Figure 4.2: Interactive Binomial Tree Explorer. This tool allows you to experiment with N-period binomial trees. Key features: (i) Interest rate: Enter the rate per period (for annual rate with N periods, use r/N), (ii) Up move: This corresponds to \((u-1)\) where \(u\) is our up factor, (iii) Down move: The model automatically sets \(d = 1/u\) to ensure recombination, (iv) Number of periods: See how increasing N affects option values and convergence, (v) Option types: Compare European and American option pricing, (vi) Parameters: Observe how volatility, strike price, and time to maturity affect values

Backward Induction Implementation

For American options especially, we must use backward induction. Here’s the streamlined version for practical use:

Code
def binomial_american_fast(S0, K, r, sigma, T, N, option_type='put'):
    """
    Efficient American option pricing using backward induction
    
    This version uses vectorized operations for speed
    """
    dt = T / N
    u = np.exp(sigma * np.sqrt(dt))
    d = 1 / u
    p = (np.exp(r * dt) - d) / (u - d)
    disc = np.exp(-r * dt)
    
    # Initialize option values at maturity
    # Use vectorized operations for efficiency
    j_values = np.arange(N+1)
    S_final = S0 * (u**j_values) * (d**(N-j_values))
    
    if option_type == 'call':
        V = np.maximum(S_final - K, 0)
    else:
        V = np.maximum(K - S_final, 0)
    
    # Backward induction
    for i in range(N-1, -1, -1):
        j_values = np.arange(i+1)
        S_current = S0 * (u**j_values) * (d**(i-j_values))
        
        # Continuation values (vectorized)
        V_new = disc * (p * V[1:i+2] + (1-p) * V[0:i+1])
        
        # Exercise values
        if option_type == 'call':
            exercise = np.maximum(S_current - K, 0)
        else:
            exercise = np.maximum(K - S_current, 0)
        
        # Take maximum (American feature)
        V = np.maximum(V_new, exercise)
    
    return V[0]

# Examples
print("\nAmerican option values:")
put_american = binomial_american_fast(100, 105, 0.05, 0.2, 1, 100, 'put')
call_american = binomial_american_fast(100, 105, 0.05, 0.2, 1, 100, 'call')
print(f"American put (K=105): {put_american:.4f}")
print(f"American call (K=105): {call_american:.4f}")

American option values:
American put (K=105): 8.7476
American call (K=105): 8.0262

How the Code Works

Key algorithmic insights:

  1. Vectorization: Instead of nested loops, we use NumPy arrays to compute all nodes at each time step simultaneously

  2. Memory efficiency: We only store option values for the current time step, not the entire tree

  3. Backward induction logic:

    • Start with the payoffs at maturity
    • At each prior time step, compute the continuation value as the discounted expected next-period value
    • For American options, compare it to the immediate exercise value
    • Take the maximum (American feature)

4.4 Parameter Calibration

We need \(\Delta t\) to be small for it to be reasonable to assume that the underlying asset can only do two possible things over the next time period. If we’re going to take it be very small, we might as well ask what happens if we take it to be infinitesimal, meaning that we take \(\Delta t \rightarrow 0\). This is the continuous-time limit.

We should choose the parameters of the model to match the properties of the underlying asset. If we’re going to take the limit, then the important feature is that the limiting parameters match the properties of the underlying asset. Several choices are possible, but the most popular set of parameters is that proposed by (Cox, Ross, and Rubinstein 1979).

They set

\[u = \mathrm{e}^{\sigma\sqrt{\Delta t}}, \quad d = \frac{1}{u}, \quad p = \frac{\mathrm{e}^{(r-q)\Delta t} - d}{u - d}\]

where \(\sigma\) is the standard deviation of the underlying asset return, \(r\) is the risk-free rate, and \(q\) is the dividend yield. This choice ensures:

  • The tree recombines (\(ud = 1\))
  • The discrete model converges to geometric Brownian motion (see Chapter 7).
  • The risk-neutral probability is well-defined when \(d < \mathrm{e}^{(r-q)\Delta t} < u\)

The following interactive figure shows how the option prices derived from the binomial model settle down around fixed values as the number of periods in a given time period increases (that is, as \(\Delta t = T/N \rightarrow 0\)). We will later see that this limit is the celebrated Black-Scholes formula (see Chapter 9).

Figure 4.3: Binomial Convergence to Continuous-Time Limit The binomial model (blue dots) converges to the continuous-time limit (red dotted line) for European options as the number of time steps is increased. The deviations from the continuous-time values are the same for both calls and puts, reflecting put-call parity in both the discrete and continuous-time models.

4.5 Summary

The binomial tree model provides an intuitive and flexible framework for option pricing:

  1. One-period model: Introduces replication and risk-neutral valuation
  2. Multi-period extension: Uses backward induction
  3. Parameter choice: Cox-Ross-Rubinstein parameters with \(u = \mathrm{e}^{\sigma\sqrt{\Delta t}}\) and \(d = 1/u\) ensure convergence

4.6 Exercises

One-Period Model Exercises

Exercise 4.1 In a one-period binomial model with \(S = 50\), \(S_u = 60\), \(S_d = 40\), and \(r = 0.05\): a) Calculate the risk-neutral probabilities b) Price a call option with strike \(K = 55\) c) Verify your answer using delta hedging

Exercise 4.2 Create a Python function in which the user inputs \(S\), \(S_d\), \(S_u\), \(K\), \(r\) and \(t\). Check that the no-arbitrage condition is satisfied (\(S_d < Se^{rt} < S_u\)). Compute the value of a call option in each of the following ways:

  1. Compute the delta and use the replication formula
  2. Compute the state prices and use linear pricing
  3. Compute the risk-neutral probabilities and use the discounted expectation
  4. Compute the probabilities using the stock as numeraire

Verify that all of these methods produce the same answer.

Exercise 4.3 In a two-state model, a put option is equivalent to \(\delta_p\) shares of the stock, where \(\delta_p = (P_u-P_d)/(S_u-S_d)\) (this will be negative, meaning a short position) and some money invested in the risk-free asset. Derive the amount of money \(x\) that should be invested in the risk-free asset to replicate the put option. The value of the put at date \(0\) must be \(x+\delta_pS\).

Exercise 4.4 Using the result of the previous exercise, repeat Exercise 4.2 for a put option using all four pricing methods.

Two-Period and Multi-Period Exercises

Exercise 4.5 Modify the visual tree code to create a two-period tree for an American put option with \(S_0 = 100\), \(K = 105\), \(r = 0.05\), \(\sigma = 0.3\), and \(T = 0.5\). At each intermediate node, show both the continuation value and the immediate exercise value, highlighting when early exercise is optimal.

Exercise 4.6 Compare the detailed backward induction algorithm with the fast vectorized version for pricing American options. Time both implementations for \(N = 50, 100, 200, 500\) time steps. At what point does the speed difference become significant? Verify that both give identical results.

Exercise 4.7 Show that in the Cox-Ross-Rubinstein model, the expected return on the stock under the risk-neutral measure equals the risk-free rate: \(\mathbb{E}^p[S_{t+\Delta t}/S_t] = \mathrm{e}^{r\Delta t}\)

Parameter Calibration and Convergence

Exercise 4.8 Consider an at-the-money European call option on a dividend-reinvested stock with six months to maturity. Take the initial stock price to be $50, the interest rate to be 5% and \(\sigma = 30\%\). Compute the value in a binomial model with \(N = 10, 11, \ldots, 30\) and plot the values against \(N\). Is convergence monotone? Comment on the oscillations you observe.

Exercise 4.9 Consider the same option as in the previous problem. Roughly what value of \(N\) is needed to get penny accuracy? (To evaluate the accuracy, compare the price to the price given by the Black-Scholes formula.)

Exercise 4.10 Compare the convergence of European option prices using: a) Cox-Ross-Rubinstein parameters: \(u = e^{\sigma\sqrt{\Delta t}}\), \(d = 1/u\) b) Jarrow-Rudd parameters: \(p = 1/2\), adjust \(u\) and \(d\) to match moments

Plot the option values against the number of time steps \(N\) for both methods. Which converges faster? Which is more stable?

Exercise 4.11 Verify that the Cox-Ross-Rubinstein parameters satisfy the moment-matching conditions: a) Show that \(\frac{\mathbb{E}[\Delta \log S]}{\Delta t} \to r - q - \frac{\sigma^2}{2}\) as \(\Delta t \to 0\) b) Show that \(\frac{\mathrm{Var}[\Delta \log S]}{\Delta t} \to \sigma^2\) as \(\Delta t \to 0\)

where the expectation and variance are under the risk-neutral measure.

American Options and Early Exercise

Exercise 4.12 The early exercise premium is the difference between the value of an American option and the value of a European option with the same parameters. Compute the early exercise premium for an American put with varying: a) Interest rates (\(r = 0\%, 2\%, 5\%, 10\%\)) b) Exercise prices (\(K = 80, 90, 100, 110, 120\) with \(S_0 = 100\)) c) Time to maturity (\(T = 0.25, 0.5, 1, 2\) years)

Under what circumstances is the early exercise premium relatively large?

Exercise 4.13 Implement a function to compute the early exercise boundary for an American put option. Plot the boundary as a function of time to maturity for different parameter values. Explain intuitively why the boundary has the shape it does.

Exercise 4.14 For an American call option on a dividend-paying stock, show analytically that it may be optimal to exercise just before an ex-dividend date. Implement this in your binomial tree by adding discrete dividend payments and compare American and European call values.

Advanced Applications

Exercise 4.15 A shout option is an option where the holder is entitled to “shout” at any time prior to expiration. Upon shouting, the holder receives the immediate exercise value paid at expiration, plus an at-the-money option with the same expiration. The payoff if the holder shouts at time \(\tau\) is \(\max(0, S(\tau)-K, S_T-S(\tau))\) where \(K\) is the original strike.

  1. Show that it is better to shout at some time where \(S(\tau) > K\) than to never shout at all
  2. Modify the backward induction algorithm to find the optimal shouting strategy
  3. Plot the optimal shouting boundary

Exercise 4.16 A down-and-out barrier option is a call option that becomes worthless if the stock price ever falls below a barrier \(B < S_0\). Modify the binomial tree algorithm to price such options by setting the option value to zero at any node where \(S \leq B\). Compare the barrier option price to a standard call for different barrier levels.

Exercise 4.17 Extend the binomial model to a trinomial model with three possible moves at each step: up by factor \(u\), stay the same, or down by factor \(d\). a) Derive the risk-neutral probabilities \(p_u\), \(p_m\), \(p_d\) for the three states b) Implement trinomial backward induction c) Compare trinomial and binomial convergence for the same \(\Delta t\)

Cox, J., S. Ross, and M. Rubinstein. 1979. “Option Pricing: A Simplified Approach.” Journal of Financial Economics 7: 229–63.

  1. These hypothetical securities are called Arrow securities in recognition of the seminal insights of Kenneth J. Arrow.↩︎