最近在一家券商的场外衍生品部门实习,刚做的一个课题是关于delta动态对冲为香草期权定价,参考了John Hull的《期权、期货及其他衍生产品》,发现里面有关于delta对冲的内容,现在先用python来将书上的案例进行还原。
为了对冲卖出的看涨期权带来的风险,需要买入一定的股票进行对冲,买入股票的数量即为该看涨期权的delta值乘上卖出的期权数,在该案例中delta为0.522
下面是两种对冲的情形,分别对应期权到期日能否行权的两种情况。
第一种情况:到期日股价高于执行价,可以行权,此时的期权复制成本为263300美元。
第二种情况:到期日股价低于执行价,不能行权,此时的期权复制成本为256600美元。
下面是python代码实现
先写一个bsm.py,定义在BSM模型下看涨期权的价值和delta
from math import log, sqrt, exp
from scipy import stats
import numpy as np
class BSMOptionValuation:
def __init__(self, S0, K, T, r, sigma, div=0.0):
self.S0 = float(S0)
self.K = float(K)
self.T = float(T)
self.r = float(r)
self.sigma = float(sigma)
self.div_yield = float(div)
self.d1 = ((log(self.S0 / self.K) + (self.r - self.div + 0.5 * self.sigma ** 2) * self.T) / (self.sigma * sqrt(self.T)))
self.d2 = self.d1 - self.sigma * sqrt(self.T)
def call_value(self):
call_value = (self.S0 * exp(-self.div * self.T) * stats.norm.cdf(self.d1, 0.0, 1.0) - self.K * exp(-self.r * self.T) * stats.norm.cdf(self.d2, 0.0, 1.0))
return call_value
def delta(self):
delta_call = exp(- self.div * self.T) * stats.norm.cdf(self.d1, 0.0, 1.0)
delta_put = -exp(- self.div * self.T) * stats.norm.cdf(-self.d1, 0.0, 1.0)
return delta_call, delta_put
然后进行案例复现
这里我用的是第一种股票走势进行模拟,大家可以测试用第二种来模拟,结果和书上的一样
from math import log, sqrt, exp
import numpy as np
import scipy.stats as si
from scipy.stats import norm
from bsm import *
import pandas as pd
if __name__=='__main__':
#期权的关键参数
N = 100000 # 期权份数
S1 = [49,48.12,47.37,50.25,51.75,53.12,53,51.87,51.38,53,49.88,48.5,49.88,50.37,52.13,51.88,52.87,54.87,54.62,55.87,57.25] # 股票价格第一种走势
S2 = [49,49.75,52,50,48.38,48.25,48.75,49.63,48.25,48.25,51.12,51.5,49.88,49.88,48.75,47.5,48,46.25,48.13,46.63,48.12] # 股票价格第二张走势
K = 50 # 行权价
r = 0.05 # 无风险利率
sigma = 0.2 # 波动率
T = 0.3846 # 期限
simulation = 20 # 路径步数
dt =T / simulation # 单位步数
# 初始结构设定
expire_time = np.append((np.ones((simulation , 1)) * dt).cumsum()[::-1],0) # 到期期限的时间序列
cash = np.zeros(simulation + 1) # 现金账户
div = np.zeros(simulation) # 利息账户
delta = np.zeros(simulation) # delta
#开始对冲
for step in range(simulation+1):
# 期初开仓
if step == 0:
delta[step] = BSMOptionValuation(S1[step], K, expire_time[step], r, sigma).delta()[0] # 计算对冲路径上delta
cash[step] = delta[step] * N * S1[0] # 期初现金账户
div[step] = cash[step] * r * dt # 期初利息账户
# 中途对冲
if step in range(1,simulation):
delta[step] = BSMOptionValuation(S1[step], K, expire_time[step], r, sigma).delta()[0]
cash[step] = cash[step-1] + div[step-1] + (delta[step] - delta[step - 1]) * S1[step] * N # 每日结算损益
div[step] = cash[step] * r * dt
# 期末结算
if step == simulation:
if S1[step] > K:
cash[step] = cash[step-1] + div[step-1] - N * K
elif S1[step] <=K :
cash[step] = cash[step-1] + div[step-1] - delta[step - 1] * S2[step] * N
print(cash[-1]) # 返回期权复制成本
C:\ProgramData\Anaconda3\envs\untitled\python.exe C:/Users/Administrator/PycharmProjects/pythonProject/deltahedge_clone.py
263061.29677824676
结果非常接近书上的263300美元,误差在于书上的计算都只保留了小数点后一位,我这里没有这样操作,另一种股票走势的结果如下,和书上的256600美元非常接近:
C:\ProgramData\Anaconda3\envs\untitled\python.exe C:/Users/Administrator/PycharmProjects/pythonProject/deltahedge_clone.py
256520.06138881645
后面我了解到,业界往往会用cash delta而非delta来进行动态对冲,同时股票路径可以用蒙特卡洛来进行模拟,下一篇我将展示如何用python来实现基于蒙特卡洛模拟的cash delta动态对冲。