浅入隐含波动率

版权声明:本文为博主原创文章,未经博主允许不得转载 https://blog.csdn.net/qq_34356800/article/details/83188565

最近需要接触点金融的东西,大概简单记录下学习隐含波动率的笔记。

隐含波动率

简单描述就是由于期权定价模型(如BS模型)给出了期权价格与五个基本参数(标的股价、执行价格、利率、到期时间、波动率)之间的定量关系,只要将其中前4个基本参数及期权的实际市场价格作为已知量代入定价公式,就可以从中解出惟一的未知量,这个大小就是隐含波动率

对于标准的欧式权证的理论价格,可以通过B-S公式计算。在B-S公式中,共有权证价格C或P、正股价格S、行权价格X、剩余期限(T-t)、无风险收益率r和波动率σ六个参数。具体公式如下:

对于认购权证:
C = S N ( d 1 ) X e r ( T t ) N ( d 2 ) C=S\cdot N(d_{1})-Xe^{-r(T-t)}\cdot N(d_{2})

对于认沽权证:
P = X e r ( T t ) [ 1 N ( d 2 ) ] S [ 1 N ( d 1 ) ] P=Xe^{-r(T-t)}\cdot [1-N(d_{2})]-S\cdot [1-N(d_{1})]
其中: N ( ) N(\cdot ) 为累计正态概率

d 1 = l n ( S / X ) + ( r + σ 2 / 2 ) ( T t ) σ T 1 d_{1}=\frac{ln(S/X)+(r+\sigma ^{2}/2)(T-t)}{\sigma \sqrt{T-1}}
d 2 = d 1 σ T t d_{2}=d_{1}-\sigma \sqrt{T-t}
在这6个参数中,如果知道其中5个参数的值,就可以通过B-S公式求解出第6个参数的值,尽管有的参数得不到明确的解析表达式,但是可以通过数值算法求解。 详见:
http://blog.sina.com.cn/s/blog_155fed8250102xoxa.html
所以给定一组输入参数S(当前股票价格)、X(执行价格)、T(以年为单位的有效期)、r(连续复利的无风险利率)和 sigma(股票回报率的标准方差,也称为波动率)可以利用 Black-Scholes-Merton 模型来计算看涨期权的价格。函数命名为 bs.py

from scipy import log, exp, sqrt, stats
def bs_call(S, X, T, r, sigma):
    d1 = (log(S/X)+(r+sigma*sigma/2.)*T)/(sigma*sqrt(T))
    d2 = d1-sigma*sqrt(T)
    return S*stats.norm.cdf(d1)-X*exp(-r*T)*stats.norm.cdf(d2)

在py的交互模式下运行:
bs_call

实际上,找出隐含波动率是基于一个简单的逻辑:试错法。以上面的数值作为例子。有 5 个值 S=40、X=40、T=0.5、 和 c=3.30。用 100 个不同的 sigma 值,加上另外 4 个参数值,可以得到 100 个看涨期权的价格。隐含波动率的一个估计值是这 100 个 sigma 值中使得看涨期权的价格与给定的期权价格 3.30 之间的绝对差值最小的那一个。当然可以增加更多的 sigma 值,以得到更高精度的隐含波动率的估计值,也就是说精确到小数点后更多位。

或者可以采用另一个收敛标准:当计算得到的看涨期权价格和给定的看涨期权价格之间的绝对差值小于我们自定的一个临界值,比如 1 分钱,即 |c-3.30|<0.01 时,就停止计算。因为随机选取 100 或 1000 个不同的 sigma 值并不是最优的办法,可以使用循环语句来有系统的选择一些 sigma 值。

另一方面,如果知道 S、X、T、r、和期权价格 c,如何得到相对应的 sigma?

for 循环计算隐含波动率

from bs_call import bs_call
S=40; K=40; T=0.5; r=0.05; c=3.30
for i in range(200):
  sigma=0.005*(i+1)
  diff=c-bs_call(S,K,T,r,sigma) 
  if abs(diff)<=0.01:
    print(i,sigma, diff)

这个程序的逻辑是使用试错法来为 Black-Scholes-Merton 期权模型提供许多不同的 sigma(波动率)。对于给定的一个 sigma 值,如果计算得到的看涨期权价格和给定的看涨期权价格之间的绝对差值小于 0.01,就停止计算。那个 sigma 值就是隐含波动率。
在这里插入图片描述
第1个数字49是变量i在程序结束时的值,0.25是隐含波动率,最后一个数值是计算得到的看涨期权价格和给定的看涨期权价格(即 3.30 美元)之间的绝对差值。

欧式期权的隐含波动率

把上面封装成一个计算欧式期权的隐含波动率的函数保存为 vol.py

from bs import bs_call
def implied_vol_call(S,X,T,r,c):
    for i in range(200):
        sigma=0.005*(i+1)
        diff=c-bs_call(S,X,T,r,sigma)
        if abs(diff)<=0.01:
            return i,sigma,diff

在这里插入图片描述

看跌期权的隐含波动率

可以基于期权模型估计欧式看跌期权的隐含波动率写个函数

from scipy import log,exp,sqrt,stats
def implied_vol_put_min(S,X,T,r,p):
    implied_vol=1.0;min_value=0.01
    for i in range(1,10000):
        sigma=0.0001*(i+1)
        d1=(log(S/X)+(r+sigma*sigma/2.)*T)/(sigma*sqrt(T))
        d2 = d1-sigma*sqrt(T)
        put=X*exp(-r*T)*stats.norm.cdf(-d2)-S*stats.norm.cdf(-d1)
        abs_diff=abs(put-p)
        if abs_diff<min_value:
            min_value=abs_diff;implied_vol=sigma
            k=i;put_out=put
            print('k,implied_vol,put,abs_diff')
            return k,implied_vol,put_out,min_value

这个函数和前面两个有些区别,首先,这个函数计算看跌期权的隐含波动率,而不是看涨期权的隐含波动率,最后一个输入值是看跌期权的价格,而不是看涨期权的价格。其次,收敛标准是估计的期权价格和给定的看跌期权价格的绝对价差最小,因此,这个函数将保证一定可以得到一个隐含波动率的估计值而前面的函数不行。
先输入一组参数值来估计隐含波动率,然后解释这个函数内在的逻辑。假设 S = 40,X = 40,T = 12 个月,r = 0.1,看跌期权价格为 1.50 美元,结果如下。
在这里插入图片描述
结果显示隐含波动率为 20%。这个算法的逻辑是我们首先为一个名为 min_value 的变量赋一个大的数,如 100。给定参数 sigma 的第 1 个值 0.0002,计算得出近乎为零的看跌期权价格,其与输入的看跌期权价格的绝对价差为 1.50。因为绝对价差小于 100,所以 min_value 变量的值将替换为 1.50。重复这个过程,直到循环结束。最后得到的 min_value 对应的 sigma 值就是隐含波动率。

使用 while 循环计算隐含波动率

以下代码使用 while 循环来估计看跌期权的隐含波动率。

from bs_put import bs_put
import scipy as sp 
S=40; K=40; T=0.5; r=0.05; p=1.77
diff=1; i=1;sigma_old=0.005
sign_1=sp.sign(p-bs_put(S,K,T,r,sigma_old)) 
while(1):
  sigma=0.0001*(i+1)
  sign_2=sp.sign(p-bs_put(S,K,T,r,sigma)) 
  i+=1
  if sign_1*sign_2<0: 
    break
  else:
    sigma_old=sigma 
print('i, implied-vol, diff')
print(i,(sigma_old+sigma)/2, diff)

以下的输出结果显示隐含波动率等于 0.2 ,与我们使用 Black-Scholes-Merton 看涨期权模型估计的结果一样。还可以使用 0.2 作为波动率的输入值来计算,从而确定得到相同的期权价格。
在这里插入图片描述

需要了解更多详见python金融实战

猜你喜欢

转载自blog.csdn.net/qq_34356800/article/details/83188565