# CRR二项式期权定价模型
# 模型假设一个离散时间和离散状态空间上的BSM经济体
# CRR模型对标准的欧式期权没有什么优势,但是对于标准欧式期权以外的其他期权,CRR模型的优势就很明显
# CRR模型可以处理提前行权的期权,即百慕大期权或者美式期权
# CRR模型/看涨期权
# Cox-Ross-Rubinstein Binomial Model
# European Option Valuation
#
import math
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams['font.family'] = 'serif'
import sys
sys.path.append('C:/Users/gws/Documents/PYTHON_DAIMA/python36/05_com')
from BSM_option_valuation import BSM_call_value
#
# Model Parameters
#
S0 = 100.0 # index level
K = 100.0 # option strike
T = 1.0 # maturity date
r = 0.05 # risk-less short rate
sigma = 0.2 # volatility
# Valuation Function
def CRR_option_value(S0, K, T, r, sigma, otype, M=4):
''' Cox-Ross-Rubinstein European option valuation.
Parameters
==========
S0 : float
stock/index level at time 0
K : float
strike price
T : float
date of maturity
r : float
constant, risk-less short rate
sigma : float
volatility
otype : string
either 'call' or 'put'
M : int
number of time intervals
'''
# Time Parameters
dt = T / M # length of time interval
df = math.exp(-r * dt) # discount per interval
# Binomial Parameters
u = math.exp(sigma * math.sqrt(dt)) # up movement
d = 1 / u # down movement
q = (math.exp(r * dt) - d) / (u - d) # martingale branch probability
# Array Initialization for Index Levels
mu = np.arange(M + 1)
mu = np.resize(mu, (M + 1, M + 1))
md = np.transpose(mu)
mu = u ** (mu - md)
md = d ** md
S = S0 * mu * md
# Inner Values
if otype == 'call':
V = np.maximum(S - K, 0) # inner values for European call option
else:
V = np.maximum(K - S, 0) # inner values for European put option
z = 0
for t in range(M - 1, -1, -1): # backwards iteration
V[0:M - z, t] = (q * V[0:M - z, t + 1] +
(1 - q) * V[1:M - z + 1, t + 1]) * df
z += 1
return V[0, 0]
def plot_convergence(mmin, mmax, step_size):
''' Plots the CRR option values for increasing number of time
intervals M against the Black-Scholes-Merton benchmark value.'''
BSM_benchmark = BSM_call_value(S0, K, 0, T, r, sigma)
m = range(mmin, mmax, step_size)
CRR_values = [CRR_option_value(S0, K, T, r, sigma, 'call', M) for M in m]
plt.figure(figsize=(9, 5))
plt.plot(m, CRR_values, label='CRR values')
plt.axhline(BSM_benchmark, color='r', ls='dashed', lw=1.5,
label='BSM benchmark')
plt.xlabel('# of binomial steps $M$')
plt.ylabel('European call option value')
plt.legend(loc=4)
plt.xlim(0, mmax)
BSM_benchmark = BSM_call_value(S0, K, 0, T, r, sigma)
BSM_benchmark
%time CRR_option_value(S0, K, T, r, sigma, 'call', M=2000)
结果为:
Wall time: 671 ms
10.449583775457942
%%time
plot_convergence(10, 1011, 20) #CRR模型的欧式看涨期权每增加20个时间步数的价值变化
%%time
plot_convergence(10, 1011, 25)#CRR模型的欧式看涨期权每增加25个时间步数的价值变化