Black-Scholes
python scipy optimize 最小化隱含波動率的參數
我在嘗試使用
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