使用 Scipy 计算隐含波动率优化 brentq 误差

VSP*_*VSP 1 optimization scipy

我想使用 scipy 优化布伦特根查找算法计算隐含波动率:

def calcimpliedvol(S,K,T,r,marketoptionPrice):
  d1=(np.log(S/K)+(r-0.5*sigma**2)*T)/(sigma*np.sqrt(T))
  d2=d1-(sigma*np.sqrt(T))
  BSprice_call=S*si.norm.cdf(d1,0,1)-K*np.exp(-r*T)*si.norm.cdf(d2,0,1)

  fx=BSprice_call-marketoptionPrice
  return optimize.brentq(fx,0,1,maxiter=1000)
Run Code Online (Sandbox Code Playgroud)

但是,当我运行该函数并为其指定所有输入时 K=6,S=8,T=0.25,r=0,OptionPrice=4 我收到一条错误消息,指出 sigma 未定义。西格玛是我想用优化算法找到的。

有人可以告诉我在定义函数时做错了什么吗?

pit*_*arg 7

您的代码存在多个问题

  • brentq需要一个函数作为第一个参数,它可以找到其根。你给它传递了一个变量。这是主要问题
  • Black-Scholes 公式是错误的((r+0.5*sigma**2)不适(r-0.5*sigma**2)用于d1
  • sigma=0当您除以 时,该代码不起作用sigma。至少你不应该将 0 作为边界之一。更好的是,sigma=0在代码中单独处理大小写
  • 期权价格 4 的值非常高,S=8,K=6,T=0.25。本例中的隐含波动率为 2.18(即 218%),超出了您为根求解器提供的上限

这是更正后的代码。对于第一点,请注意我们如何bs_price在函数内部定义函数,然后将其传递给求解器。其他问题也得到解决

from scipy import optimize
import scipy.stats as si
def calcimpliedvol(S,K,T,r,marketoptionPrice):
  
    def bs_price(sigma):
        d1=(np.log(S/K)+(r+0.5*sigma**2)*T)/(sigma*np.sqrt(T))
        d2=d1-(sigma*np.sqrt(T))
        BSprice_call=S*si.norm.cdf(d1,0,1)-K*np.exp(-r*T)*si.norm.cdf(d2,0,1)
        fx=BSprice_call-marketoptionPrice
        return fx

    return optimize.brentq(bs_price,0.0001,100,maxiter=1000)

calcimpliedvol(S=8,K=6,T=0.25, r=0, marketoptionPrice=4)
Run Code Online (Sandbox Code Playgroud)

它返回2.188862879492475