Python实战:二元期权(Binary Option)中缺口期权的解析解
什么是二元期权?
二元期权(Binary Option)也叫做数字期权,在OTC 市场中被广泛用于对冲和投机。二元期权只考虑标的资产的价格走向(看涨或者看跌),因此二元期权属于简化的金融工具。
二元期权的收益和风险是预先固定的,收益与否只由标的资 产的价格是否满足预定条件决定。
二元期权的分类
缺口期权
定义
缺口期权是一种同时拥有两个执行价格的期权,一个执行价格 X1 用以作为触发基准的行权价格,一旦标的资产价格大于(看涨期权)或者小于(看跌期权)便会产生损益,而损益的计算需要根据执行价格X2 ,执行价格X2 是用以作为比较计算回报收益的行权价格。 缺口期权常用于保险合约中,合约中一般会要求只有当指定风险(或者损失)达到了阈值(执行价格X1 )才会进行赔付,而赔付的计算又是根据其他参数(类似执行价格X2 )去完成的。
缺口期权收益结构
缺口看涨期权
当标的资产价格小于触发执行价格即 S<X1 时,缺口看涨期权的到期回报为0,而当标的资产价格大于触发执行价格即S>X1 时,其到期回报为标的资产与回报收益行权价格的差值即 S−X2。
缺口看涨期权的收益结构需要根据X1 与X2的大小去进行分类。当X1>X2时,缺口看涨期权在X1处收益呈阶梯状,而在[X2,X1]这一区间内收益为0,具体收益结构如图。
当X1<X2 时,缺口看涨期权在[X1,X2]这一区间呈下陷状,此区间的收益也为负值,具体收益结构如图:
缺口看跌期权
当标的资产价格大于触发执行价格即S>X1 时,缺口看跌期权的到期回报为0 ,而当标的资产价格小于触发执行价格即S<X1 时,其到期回报为回报收益行权价格和标的资产的差值 X2−S 。
缺口看跌期权的收益结构也需要根据X1 与X2的大小去进行分类。当X1>X2时,缺口看跌期权在区间[X2,X1]呈下陷状,收益为负值,具体收益结构如图:
当X1<X2时,缺口看跌期权在X1处收益呈阶梯状,而在[X2,X1]这一区间内收益为0 ,具体收益结构如图:
缺口期权定价公式
当 S≤X1 时,缺口看涨期权的到期回报为 0,而当 S>X1 时,其到期回报为 S−X2。同样地,当 S≥X1 时,缺口看跌期权的到期回报为 0,而当 S<X1 时,其到期回报为 X2−S。Renier 和 Rubinstein(1991b) 提出了这些期权的定价公式:
c=Se(b−r)TN(d1)−X2erTN(d2)
p=X2erTN(−d2)−Se(b−r)TN(−d1)
其中
d1=σTln(X1S)+(b+2σ2)T
d2=σTln(X1S)+(b−2σ2)T=d1−σT
定价模型中的参数解释如下:
函数 N(x) 为标准正态分布的累积概率分布函数。换言之,这一函数等于服从标准正态分布 ϕ(0,1) 的随机变量小于 x 的概率。
- c:缺口期权欧式看涨的价格;
- p:缺口期权欧式看跌的价格;
- S:标的资产在时间 0 的价格,可以视为当前标的资产价格;
- X1:执行价格,用以作为触发基准的行权价格;
- X2:到期回报执行价格,用以作为比较计算回报收益的行权价格;
- σ:标的资产价格的波动率;
- r:连续复利的无风险利率;
- T:期权的期限(以年作为单位);
- b:持有成本率。
需要注意的是,缺口期权的到期回报可能为负值,这取决于 X1 和 X2 的大小。
缺口期权定价代码
## 这个模型可以用于定价标的为无股息股票、支付连续股息的股票、期货、外汇的欧式缺口期权
function European_Gap_Option
param CallorPut:看涨看跌期权类型,'C'表示看涨,'P'表示看跌
param S: 标的物初始价格水平或者标的物当前价格
param X1: 执行价格,用以作为触发基准的行权价格
param X2:到期回报执行价格,用以作为比较计算汇报收益的行权价格
param T: 期权的期限(一年为单位)
param r: 连续复利的无风险利率
param sigma: 标的物波动率
param b: 持有成本率
param days:计算希腊字母的年日历天数
当b=r时,该公式是无股利欧式期权定价公式;
当b=r-q时,该公式是连续股利欧式期权定价公式;
当b=0时,该公式是期货期权定价公式;
当b=0且r=0时,该公式是权利金计息下的期货期权定价公式;
当b=r-rf时,该公式是外汇期权定价公式。
import numpy as np
from scipy import stats
def European_Gap_Option(CallorPut='C', S=1, X1=1, X2=0.5, T=1, r=0, sigma=0.1, b=0, days=244):
"""
计算欧式缺口期权价格
:param CallorPut:看涨看跌期权类型,'C'表示看涨,'P'表示看跌
;param S: 标的物初始价格水平或者比标的物当前价格
:param X1: 执行价格,用以作为触发基准的行权价格
:param X2: 到期回报执行价格,用以作为比较计算汇报收益的行权价格
:param T: 期权的期限(一年为单位)
:param r: 连续复利的无风险利率
:param sigma: 标的物波动率
:param b: 持有成本率
:return value: 欧式缺口期权价格
"""
# 计算d1、d2
d1 = (np.log(S /X1) + (b + 0.5 * sigma**2) * T )/(sigma * np.sqrt(T))
d2 = (np.log(S /X1) + (b - 0.5 * sigma**2) * T )/(sigma * np.sqrt(T))
# 分别计算call put的option
if CallorPut == 'C':
value = S * np.exp((b-r) * T)* stats.norm.cdf(d1, 0, 1) - X2 * np.exp(-r * T) * stats.norm.cdf(d2, 0, 1)
Delta = np.exp((b-r)*T) * stats.norm.cdf(d1, 0, 1) + np.exp((b-r)*T)* stats.norm.pdf(d1, 0, 1)/(sigma*np.sqrt(T))\
- X2 * np.exp(-r*T) * stats.norm.pdf(d2, 0, 1)/(sigma*S*np.sqrt(T))
Gamma = np.exp((b-r)*T) * stats.norm.pdf(d1, 0, 1)/(sigma*S*np.sqrt(T)) \
- np.exp((b-r)*T-d1**2/2)*d1/(np.sqrt(2*np.pi)*sigma**2*S*T) \
+ X2 * np.exp(-r*T)* stats.norm.pdf(d2, 0, 1)/(sigma*S**2*np.sqrt(T)) \
+ X2 * np.exp(-r*T-d2**2/2)*d2/(np.sqrt(2*np.pi)*sigma**2*S**2*T)
Theta = -(b-r)*S*np.exp((b-r)*T)* stats.norm.cdf(d1, 0, 1) - r*X2*np.exp(-r*T)*stats.norm.cdf(d2, 0, 1)\
+ S*np.exp((b-r)*T)*stats.norm.pdf(d1, 0, 1)*(np.log(S/X1)- (b+sigma**2/2)*T)/(2*sigma*T**1.5) \
- X2*np.exp(-r*T)*stats.norm.pdf(d2, 0, 1)*(np.log(S/X1)- (b-sigma**2/2)*T)/(2*sigma*T**1.5)
Theta = Theta/days
Vega = S*np.exp((b-r)*T)*stats.norm.pdf(d1, 0, 1)*(np.sqrt(T)/2-(np.log(S/X1)+b*T)/(sigma**2*np.sqrt(T))) \
+ X2 * np.exp(-r*T)*stats.norm.pdf(d2, 0, 1)*(np.sqrt(T)/2+(np.log(S/X1)+b*T)/(sigma**2*np.sqrt(T)))
Rho = S*np.exp((b-r)*T)*np.sqrt(T)*stats.norm.pdf(d1, 0, 1)/sigma + T*X2*np.exp(-r*T)*stats.norm.cdf(d2, 0, 1) \
- X2*np.exp(-r*T)*np.sqrt(T)*stats.norm.pdf(d2, 0, 1)/sigma
elif CallorPut == 'P':
value = X2 * np.exp(-r * T) * (1 - stats.norm.cdf(d2, 0, 1)) - S * (1 - stats.norm.cdf(d1, 0, 1)) * np.exp((b-r) * T)
Delta = np.exp((b-r)*T) * stats.norm.cdf(d1, 0, 1) + np.exp((b-r)*T)* stats.norm.pdf(d1, 0, 1)/(sigma*np.sqrt(T))\
- X2 * np.exp(-r*T) * stats.norm.pdf(d2, 0, 1)/(sigma*S*np.sqrt(T)) - np.exp((b-r)*T)
Gamma = np.exp((b-r)*T) * stats.norm.pdf(d1, 0, 1)/(sigma*S*np.sqrt(T)) \
- np.exp((b-r)*T-d1**2/2)*d1/(np.sqrt(2*np.pi)*sigma**2*S*T) \
+ X2 * np.exp(-r*T)* stats.norm.pdf(d2, 0, 1)/(sigma*S**2*np.sqrt(T)) \
+ X2 * np.exp(-r*T-d2**2/2)*d2/(np.sqrt(2*np.pi)*sigma**2*S**2*T)
Theta = -(b-r)*S*np.exp((b-r)*T)* stats.norm.cdf(d1, 0, 1) - r*X2*np.exp(-r*T)*stats.norm.cdf(d2, 0, 1)\
+ S*np.exp((b-r)*T)*stats.norm.pdf(d1, 0, 1)*(np.log(S/X1)- (b+sigma**2/2)*T)/(2*sigma*T**1.5) \
- X2*np.exp(-r*T)*stats.norm.pdf(d2, 0, 1)*(np.log(S/X1)- (b-sigma**2/2)*T)/(2*sigma*T**1.5) \
+ r*X2*np.exp(-r*T) + (b-r)*S*np.exp((b-r)*T)
Theta = Theta/days
Vega = S*np.exp((b-r)*T)*stats.norm.pdf(d1, 0, 1)*(np.sqrt(T)/2-(np.log(S/X1)+b*T)/(sigma**2*np.sqrt(T))) \
+ X2 * np.exp(-r*T)*stats.norm.pdf(d2, 0, 1)*(np.sqrt(T)/2+(np.log(S/X1)+b*T)/(sigma**2*np.sqrt(T)))
Rho = S*np.exp((b-r)*T)*np.sqrt(T)*stats.norm.pdf(d1, 0, 1)/sigma + T*X2*np.exp(-r*T)*stats.norm.cdf(d2, 0, 1) \
- X2*np.exp(-r*T)*np.sqrt(T)*stats.norm.pdf(d2, 0, 1)/sigma - T*X2*np.exp(-r*T)
else:
raise Exception('CallorPut输入参数有误')
return value, Delta, Gamma, Theta, Vega, Rho
European_Gap_Option(CallorPut='C', S=50, X1=40, X2=50, T=0.5, r=0.09, sigma=0.2, b=0.09)
输出:
(2.593844506850168,
0.8734497794450735,
0.036511110710742464,
-0.02263374400583377,
9.127777677685607,
20.539322232701753)