期权计算隐含波动率

68 篇文章 14 订阅
牛顿迭代法

 

from scipy.stats import norm
import numpy as np
def bscall(S,K,r,sigma,t):
    d1=(np.log(S/K)+(r+0.5*sigma**2)*t)/(sigma*np.sqrt(t))
    d2=d1-sigma*np.sqrt(t)
    return S*norm.cdf(d1)-K*np.exp(-r*t)*norm.cdf(d2)
def bsput(S,K,r,sigma,t):
    d1=(np.log(S/K)+(r+0.5*sigma**2)*t)/(sigma*np.sqrt(t))
    d2=d1-sigma*np.sqrt(t)
    return -S*norm.cdf(-d1)+K*np.exp(-r*t)*norm.cdf(-d2)

def newton_call(P,S,K,r,t):
    #print('call')
    sigma = 0.2
    while abs(bscall(S,K,r,sigma,t)-P)>0.0001:
        if bscall(S,K,r,sigma,t)>P:
            sigma-=0.001
        else:
            sigma+=0.001
    return sigma
def newton_put(P,S,K,r,t):
    #print('put')
    sigma=0.2
    while abs(bsput(S,K,r,sigma,t)-P)>0.0001:
        if bsput(S,K,r,sigma,t)>P:
            sigma-=0.0001
        else:
            sigma+=0.0001
    return sigma

二分法

#二分法
def binary_call(P,S,K,r,t):
    sigma_up=1
    sigma_down=0.001
    sigma_mid=(sigma_up+sigma_down)/2
    while abs(bscall(S,K,r,sigma_mid,t)-P)>0.0001:
        if bscall(S,K,r,sigma_down,t)<P<bscall(S,K,r,sigma_mid,t):
            sigma_up=sigma_mid
            sigma_mid=(sigma_mid+sigma_down)/2
        elif bscall(S,K,r,sigma_up,t)>P>bscall(S,K,r,sigma_mid,t):
            sigma_down=sigma_mid
            sigma_mid=(sigma_up+sigma_down)/2
        else:
            print('error!')
            break
    return sigma_mid
def binary_put(P,S,K,r,t):
    sigma_up=1
    sigma_down=0.001
    sigma_mid=(sigma_up+sigma_down)/2
    while abs(bsput(S,K,r,sigma_mid,t)-P)>0.0001:
        if bsput(S,K,r,sigma_down,t)<P<bsput(S,K,r,sigma_mid,t):
            sigma_up=sigma_mid
            sigma_mid=(sigma_mid+sigma_down)/2
        elif bsput(S,K,r,sigma_up,t)>P>bsput(S,K,r,sigma_mid,t):
            sigma_down=sigma_mid
            sigma_mid=(sigma_up+sigma_down)/2
        else:
            print('error!')
            break
    return sigma_mid

微笑曲线

'''
波动率微笑和波动率偏斜
  波动率微笑(smile)描述了期权隐含波动率和执行价格之间的关系,即在其他条件相同的情况下,期权的隐含波动率在平值点附近最小,在虚值和实值区域更大;
若隐含波动率在低执行价格区域高于高执行价格区域(即单调递减),那么就称为波动率偏斜(skew),对于股票期权来说这种情况更常见
'''
import numpy as np
from datetime import date
import matplotlib.pyplot as plt
from pylab import mpl
def smile(df1=0,df2=0):
    
    t=(date(2018,6,27)-date(2017,12,29)).days/365
    S=2.859;r=0.032
    K=np.arange(2.7,3.05,0.05)
    Pcall=np.array([0.2841,0.2486,0.2139,0.1846,0.1586,0.1369,0.1177])
    Pput=np.array([0.0464,0.0589,0.0750,0.0947,0.1183,0.1441,0.1756])
    volcall=np.zeros_like(K)
    for i in range(len(K)):
        volcall[i]=(binary_call(Pcall[i],S,K[i],r,t))
    volput=np.zeros_like(K)
    for i in range(len(K)):
        volput[i]=(binary_put(Pput[i],S,K[i],r,t))
    
    mpl.rcParams['font.sans-serif']=['SimHei']
    mpl.rcParams['axes.unicode_minus']=False
    plt.plot(K,volcall,label='50ETF认购期权')
    plt.plot(K,volput,label='50ETF认沽期权')
    plt.xlabel('执行价格')
    plt.ylabel('隐含波动率')
    plt.title('50ETF期权的波动率微笑(偏斜)')
    plt.legend()
    plt.grid()
smile()

计算期权隐含波动,你可以使用数值方法来解决这个问题。最常用的方法是牛顿-拉夫森方法(Newton-Raphson method),它是一种迭代算法,用于找到使得理论期权价格与市场价格相等的波动值。在Python中,你可以使用`scipy.optimize`模块中的`fsolve`函数来实现这种迭代。 以下是一个使用Python计算隐含波动的简单示例,假设我们正在处理欧式看涨期权,并且使用Black-Scholes公式: ```python import scipy.optimize as spo # Black-Scholes公式中的d1和d2计算函数 def blackscholes_d1(S, K, T, r, sigma): d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T)) return d1 def blackscholes_price(S, K, T, r, sigma, option_type='call'): # 计算d1和d2 d1 = blackscholes_d1(S, K, T, r, sigma) d2 = d1 - sigma * np.sqrt(T) # 计算期权价格 if option_type == 'call': price = (S * np.exp(-q * T) * norm.cdf(d1, 0.0, 1.0) - K * np.exp(-r * T) * norm.cdf(d2, 0.0, 1.0)) elif option_type == 'put': price = (K * np.exp(-r * T) * norm.cdf(-d2, 0.0, 1.0) - S * np.exp(-q * T) * norm.cdf(-d1, 0.0, 1.0)) else: raise ValueError("option_type must be 'call' or 'put'") return price def implied_volatility(S, K, T, r, market_price, option_type='call'): # 初始猜测的波动 sigma_guess = 0.2 # 使用fsolve找到使得期权价格与市场价格相等的波动 implied_vol = spo.fsolve(lambda sigma: blackscholes_price(S, K, T, r, sigma, option_type) - market_price, sigma_guess) return implied_vol[0] # 示例参数 S = 100.0 # 标的资产当前价格 K = 100.0 # 行权价格 T = 1.0 # 到期时间(以年为单位) r = 0.05 # 无风险利 market_price = 10.0 # 市场上的期权价格 # 计算看涨期权隐含波动 call_volatility = implied_volatility(S, K, T, r, market_price, option_type='call') print("隐含波动(看涨期权):", call_volatility) # 计算看跌期权隐含波动 put_volatility = implied_volatility(S, K, T, r, market_price, option_type='put') print("隐含波动(看跌期权):", put_volatility) ``` 这段代码中使用了`fsolve`函数来解决隐含波动的问题。首先,我们定义了计算Black-Scholes期权价格的函数,然后定义了一个函数`implied_volatility`,它接受当前市场条件和期权价格作为输入,并返回隐含波动。注意,实际的期权定价模型可能需要考虑股息、连续复利等因素,这里提供的是一个简化的模型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神出鬼没,指的就是我!

必须花钱,数据超好

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值