Black-Scholes

python scipy optimize 最小化隱含波動率的參數

  • March 13, 2019

我在嘗試使用scipy.optimize.minimize.

在下面的程式碼中,我創建了一個函式bs_nor(),並設置了一個目標函式objfunc_vol。我宣布最初的猜測x0 = 0.01;以及參數 ( args = ()) 中的其他常量。

我使用scipy minimize, 我想恢復由 給出的隱含體積sigma,而其他參數args, 是常量。

import xlrd
import numpy as np
import math
import pandas as pd
import matplotlib.pyplot as plt
import scipy as sp
import scipy.stats as stats
from scipy.optimize import minimize
from IPython.display import display

class option:
   def bs_nor(F = 1.0, K = 1.05, time = 1.0, sigma = 0.015, bs_type = 'call'):
           d1 = (F-K)/(sigma * np.sqrt(time))
           if (bs_type == 'call') or (bs_type == 'c') or (bs_type == 'Call'):
               opt = (F-K) * stats.norm.cdf(d1, 0.0, 1.0) + sigma * np.sqrt(time/(2.0*math.pi)) * np.exp(-0.5 * d1**2)
           else:
               opt = (K-F) * stas.norm.cdf(-d1, 0.0, 1.0) + sigma * np.sqrt(time/(2.0*math.pi)) * np.exp(-0.5 * d1**2)

           return np.array([opt, d1, stats.norm.cdf(d1, 0.0, 1.0)])

   def objfunc_vol(param = np.array([0.15]), F = 1.0, K = 1.0, time = 1.0, mode = 'normal', quote = 0.5):
           sigma = param[0]
           if (mode == 'normal') or (mode == 'norm') or (mode == 'n') :
               prx = option.bs_nor(F, K, time, sigma, bs_type = 'call')[0]
           else:
               prx = option.bs_log(F, K, time, sigma, bs_type = 'call')[0]
           diff = prx - quote
           return diff

options={'maxiter': 200}
x0 = 0.0255
res_vol = minimize(option.objfunc_vol, x0, args = (0.03057, -0.02, 1.0 ,'normal', 0.05079), method ='SLSQP', options = options)
print(res_vol)

option.bs_nor(F = 0.03057, K = -0.02, time = 1.0, sigma = 0.025507, bs_type = 'call')[0]

我知道解決方案應該是 0.0255;給定我輸入的常數。但是, scipy optimize 似乎並沒有給我正確的答案。它給了我 -1.15528343e+08 而不是 0.0255。

我指定錯了什麼?

fun: -46089140.7916228
    jac: array([ 0.])
message: 'Optimization terminated successfully.'
   nfev: 42
    nit: 14
   njev: 14
 status: 0
success: True
      x: array([ -1.15528343e+08])
0.050796884487313197

誤差在差異線中,它應該是差異的模數。我們希望差異為零,而不是最小值(即 -infinity)。感謝“LocalVolatility”。

def objfunc_vol(param = np.array([0.15]), F = 1.0, K = 1.0, time = 1.0, mode = 'normal', quote = 0.5):
           sigma = param[0]
           if (mode == 'normal') or (mode == 'norm') or (mode == 'n') :
               prx = option.bs_nor(F, K, time, sigma, bs_type = 'call')[0]
           else:
               prx = option.bs_log(F, K, time, sigma, bs_type = 'call')[0]
           diff = abs(prx - quote)
           return diff

引用自:https://quant.stackexchange.com/questions/44535