二叉树法的基本思路
二叉树法为欧式期权定价
n步二叉树每一列有n+1个结点,假设每个结点坐标为(i,j),比如3步二叉树中,最后一列(第4列)最上面的结点坐标为(3,3),最下面的结点坐标为(0,3),开始坐标为(0,0)。以欧式看涨期权为例,python代码如下:
import numpy as np
def tree_europ(S,X,r,sigma,t,steps):
u=np.exp(sigma*np.sqrt(t/steps));d=1/u#注意时间间隔为△t=t/steps
P=(np.exp(r*t/steps)-d)/(u-d)
prices=np.zeros(steps+1)#生成最后一列的股票价格空数组
c_values=np.zeros(steps+1)#生成最后一列的期权价值空数组
prices[0]=S*d**steps#最后一行最后一列的股票价格
c_values[0]=np.maximum(prices[0]-X,0)#最后一行最后一列的期权价值
for i in range(1,steps+1):
prices[i]=prices[i-1]*(u**2)#计算最后一列的股票价格
c_values[i]=np.maximum(prices[i]-X,0)#计算最后一列的期权价值
for j in range(steps,0,-1):#逐个节点往前计算
for i in range(0,j):
c_values[i]=(P*c_values[i+1]+(1-P)*c_values[i])/np.exp(r*t/steps)
return c_values[0]
有一欧式看涨期权标的资产价格为100元,K=100,年波动率为0.25,无风险利率为2.5%,权利期间为1年,利用二叉树求此期权的价格:
tree_europ(100,100,0.025,0.25,1,100)
Out[3]: 11.083521101164578
注意有一个很难发现的点,np.max()里面必须是array才有效,否则会得出np.max(-1,0) = -1的结果(实际上这里的第二个参数0表示axis),也就是说max()函数适用范围更广。当然用np.maximum()也行。
二叉树法为美式期权定价
美式期权定价存在提前行权问题,在上述代码的基础上加入这一条件即可。因为这是比较方便且为数不多的求美式期权价格方法之一,下面给出美式看涨和看跌期权的二叉树求法:
def tree_americacall(S,X,r,sigma,t,steps):
u=np.exp(sigma*np.sqrt(t/steps));d=1/u
P=(np.exp(r*t/steps)-d)/(u-d)
prices=np.zeros(steps+1)
c_values=np.zeros(steps+1)
prices[0]=S*d**steps
c_values[0]=np.maximum(prices[0]-X,0)
for i in range(1,steps+1):
prices[i]=prices[i-1]*(u**2)
c_values[i]=np.maximum(prices[i]-X,0)
for j in range(steps,0,-1):
for i in range(0,j):
prices[i]=prices[i+1]*d#或者prices[i]=prices[i]*u
c_values[i]=np.maximum((P*c_values[i+1]+(1-P)*c_values[i])/np.exp(r*t/steps),prices[i]-X)#检查是否提前行权
return c_values[0]
def tree_americaput(S,X,r,sigma,t,steps):
u=np.exp(sigma*np.sqrt(t/steps));d=1/u
P=(np.exp(r*t/steps)-d)/(u-d)
prices=np.zeros(steps+1)
c_values=np.zeros(steps+1)
prices[0]=S*d**steps
c_values[0]=np.maximum(X-prices[0],0)
for i in range(1,steps+1):
prices[i]=prices[i-1]*(u**2)
c_values[i]=np.maximum(X-prices[i],0)
for j in range(steps,0,-1):
for i in range(0,j):
prices[i]=prices[i+1]*d
c_values[i]=np.maximum((P*c_values[i+1]+(1-P)*c_values[i])/np.exp(r*t/steps),X-prices[i])#检查是否提前行权
return c_values[0]
有一美式期权标的资产价格为100元,K=100,年波动率为0.25,无风险利率为10%,权利期间为1年,利用二叉树求看涨期权和看跌期权的价格:
tree_americacall(100,100,0.1,0.25,1,100)
Out[8]: 14.950509715369122
tree_americaput(100,100,0.1,0.25,1,100)
Out[9]: 6.546911861041632
二叉树法为支付连续红利率的美式期权定价
假设红利率为q,只需将P的计算公式中的er△t改为e(r-q)△t,其他代码不变。在上例的基础上,该美式期权每年支付8%的连续红利率,计算该美式看涨期权的价格:
def tree_americacall_Div(S,X,r,q,sigma,t,steps):
u=np.exp(sigma*np.sqrt(t/steps));d=1/u
P=(np.exp((r-q)*t/steps)-d)/(u-d)
prices=np.zeros(steps+1)
c_values=np.zeros(steps+1)
prices[0]=S*d**steps
c_values[0]=np.maximum(prices[0]-X,0)
for i in range(1,steps+1):
prices[i]=prices[i-1]*(u**2)
c_values[i]=np.maximum(prices[i]-X,0)
for j in range(steps,0,-1):
for i in range(0,j):
prices[i]=prices[i+1]*d
c_values[i]=np.maximum((P*c_values[i+1]+(1-P)*c_values[i])/np.exp(r*t/steps),prices[i]-X)
return c_values[0]
tree_americacall_Div(100,100,0.1,0.08,0.25,1,100)
Out[10]: 10.0782277099019
同理,对于本国汇率为Rf、外国汇率为rf的外汇期权,那么P=(e(Rf-rf)t-d)/(u-d);对于期货期权,P=(1-d)/(u-d)。