cost = 0.5*P - B/r
print(f'Cost: ${cost:5.2f}\n')Cost: $ 6.82
import numpy as np
import pandas as pd
from scipy.special import comb
import mathParameters. share price is $50 and will be either $40 or $60 one year from now. Call option on the share has an exercise price of $50. Exercise a year from now. Borrowing rate is 10%.
What is the value of the call?
We need to equal alternatives, to compare and contrast
Buy the option
Borrow \$18.18, which will lead us to pay \$20 a year from now.
Parameters:
PU = 60
PD = 40
P = 50
U = 0.5
D = 0.5
r = 1.1
B = 20| Payoff at $60 | Payoff at $40 | |
|---|---|---|
| Buy the call | 60-50=10 | 0 |
| Replicate: | ||
| Buy half the stock | 30 | 20 |
| Borrow $18.18 at 10% | -20 | -20 |
| Net | 10 | 0 |
What are the cost of the replication strategy?
cost = 0.5*P - B/r
print(f'Cost: ${cost:5.2f}\n')Cost: $ 6.82
Why buy half of the share?
Answer: the price of call price if eiter $0 or $10 while the share prices will be either $40 of $60:
Swing_call = 0.5 * PU - B - 0
Swing_stock = PU - PD
Delta = Swing_call/Swing_stock
print(f'Swing_call: ${Swing_call:5.2f}\n')
print(f'Swing_stock: ${Swing_stock:5.2f}\n')
print(f'Delta: ${Delta:5.2f}\n')Swing_call: $10.00
Swing_stock: $20.00
Delta: $ 0.50
The replication strategy should give us the same risk for the both strategies. This is achieved by buying half of the share.
Busying half of the share gives us either \$30 or \$20 at expiration. Which is exactly \$20 more than the payoffs of \$10 and \$0.
Call value = Stock Price x Delta - Borrowed
Call = P * Delta - B/r
print(f'Call value: ${Call:5.2f}\n')Call value: $ 6.82
We thank Sagi Haim for developing this script
State prices - Up
# Input:
S0 = 50
X = 50
U = 1.1
D = 0.97
r = 1.06
m = 4qU = (r - D) / (r * (U - D))
print("qU",qU)qU 0.6531204644412192
State prices - Down
qD = (U - r) / (r * (U - D))
print("qD",qD)qD 0.29027576197387517
Risk neutral probabilities - Up
pi_U = qU * r
print("pi_U",pi_U)pi_U 0.6923076923076924
Risk neutral probabilities - Down
pi_D = qD * r
print("pi_D",pi_D)pi_D 0.3076923076923077
ex_payoff = np.empty(m + 1)
for i in np.arange(0, m + 1):
ex_payoff[i] = max(S0 * U ** i * D ** (m - i) - X, 0)
pass
print(pd.Series(ex_payoff))0 0.000000
1 0.197015
2 6.924450
3 14.553500
4 23.205000
dtype: float64
ex_prob = np.empty(m + 1)
for i in np.arange(0, m + 1):
ex_prob[i] = pi_U ** i * pi_D ** (m - i) * comb(m, i, exact=False)
pass
print(pd.Series(ex_prob))0 0.008963
1 0.080669
2 0.272259
3 0.408389
4 0.229719
dtype: float64
call_price = np.dot(ex_prob, ex_payoff) / r ** m
print("Call Price",call_price)Call Price 10.436036460331527
# Input:
S0 = 50
X = 50
U = 1.1
D = 0.97
r = 1.06
m = 2State prices
qU = (r - D) / (r * (U - D))
qD = (U - r) / (r * (U - D))Risk neutral probabilities
pi_U = qU * r
pi_D = qD * rCreate a payoff matrix
ex_payoff = np.empty((m + 1, m + 1))
ex_payoff[:] = np.NaNCalculate Payoff at Exercise
for col in np.arange(0, m + 1):
for row in np.arange(0, col + 1):
St = S0 * U ** (row) * D ** (col - row)
ex_payoff[row, col] = max(X - St, 0)
pass
passCreate a Put value matrix
put_value = np.empty((m + 1, m + 1))
put_value[:] = np.NaN
put_value[:, m] = ex_payoff[:, m] # At maturity put value = exerciseCalculate Put tree
for col in np.flip(np.arange(0, m)):
for row in np.arange(0, col + 1):
ex_value = ex_payoff[row, col]
pv_down = put_value[row, col + 1] * qD
pv_up = put_value[row + 1, col + 1] * qU
pres_value = pv_up + pv_down
put_value[row, col] = max(ex_value, pres_value)
pass
passprint("Put Value",put_value[0, 0])Put Value 0.43541364296081275
S0 = 50 # Current stock price
X = 50 # Option exercise price
t = 10 # Time to option exercise (in years)
vesting = 3 # Vesting period (years)
interest = 0.05 # Annual interest rate
sigma = 0.35 # Riskiness of stock
div_rate = 0.025 # Annual dividend rate on stock
exit_rate = 0.1 # Exit rate
ex_multiple = 3 # Option exercise multiple
n = 50 # Number of subdivisions of one yearDelta t
delta_t = 1/n # Delta tRisk neutral probabilities
U = math.exp((interest - 0.5 * sigma ** 2) * delta_t + math.sqrt(delta_t) * sigma)
D = math.exp((interest - 0.5 * sigma ** 2) * delta_t - math.sqrt(delta_t) * sigma)
R = math.exp(interest * delta_t)
div = math.exp(-div_rate / n)
pi_U = (R * div - D) / (U - D)
pi_D = (U - R * div) / (U - D)# Create a payoff matrix
ex_payoff = np.empty((n * t + 1, n * t + 1))
ex_payoff[:] = np.NaNCreate a Stock Price matrix
St = np.empty((n * t + 1, n * t + 1))
St[:] = np.NaNCalculate Payoff at Exercise
for col in np.arange(0, n * t + 1):
for row in np.arange(0, col + 1):
St[row, col] = S0 * U ** (row) * D ** (col - row)
ex_payoff[row, col] = max(St[row, col] - X, 0)
pass
passCreate an ESO value matrix
ESO_value = np.empty((n * t + 1, n * t + 1))
ESO_value[:] = np.NaNAt maturity ESO value = exercise
ESO_value[:, n * t] = ex_payoff[:, n * t]Calculate Payoff at Exercise
for col in np.flip(np.arange(0, n * t)):
for row in np.arange(0, col + 1):
pv_down = ESO_value[row, col + 1] * pi_D
pv_up = ESO_value[row + 1, col + 1] * pi_U
pres_value = pv_up + pv_down
if col > vesting * n: # when passed the vesting period
if St[row, col] >= ex_multiple * X: # Case where we cross the multiple execise
ESO_value[row, col] = ex_payoff[row, col]
pass
elif St[row, col] < ex_multiple * X: # Case where we didn't cross the multiple execise
ESO_value[row, col] = (1-exit_rate) ** (1/n) * pres_value / \
R + (1 - (1 - exit_rate) ** (1 / n)) * ex_payoff[row, col]
pass
pass
elif col <= vesting * n: # before we passed the vesting period
ESO_value[row, col] = (1-exit_rate) ** (1/n) * pres_value / R
pass
pass
pass
passprint("ESO Value", ESO_value[0, 0])ESO Value 13.29213862828601