2014-02-09 193 views
0

我試圖從金融期權數據中退出Black-Scholes隱含波動率。如果數據包含無法找到隱含波動率的選項,則會使所有結果與初始猜測相等。請參見以下示例Scipy fsolve:沒有解決方案使所有有效的解決方案失效

from scipy.optimize import fsolve 
import numpy as np 
from scipy.stats import norm 

S = 1293.77 
r = 0.05 
K = np.array([1255, 1260, 1265, 1270, 1275]) 
T = 2./365 
price = np.array([38.9, 34.35, 29.7, 25.35, 21.05]) 

def black_scholes(S, K, r, T, sigma): 
    d1 = (np.log(S/K) + (r + sigma ** 2/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) 

volatility = lambda x: black_scholes(S, K, r, T, x) - price 

print fsolve(volatility, np.repeat(0.1, len(K))) 

RuntimeWarning: The iteration is not making good progress, as measured by the 
    improvement from the last ten iterations. 
    warnings.warn(msg, RuntimeWarning) 
[ 0.1 0.1 0.1 0.1 0.1] 

這樣做同樣的操作與Matlab或楓木我知道,沒有解決方案可以爲第一選項中找到。如果我排除一個,這樣

K = np.array([1260, 1265, 1270, 1275]) 
price = np.array([34.35, 29.7, 25.35, 21.05]) 

我得到正確的結果

[ 0.19557092 0.20618568 0.2174149 0.21533821] 

因此,如果一個解決方案不能找到我希望fsolve返回NaN而不是我最初的猜測和不亂的解決其餘的解決方案。

回答

3

使用full_output參數告訴fsolve返回更多信息,並在返回時檢查ier的值。例如,

sol, info, ier, msg = fsolve(volatility, np.repeat(0.1, len(K)), full_output=True) 

if ier != 1: 
    print "ier = %d" % (ier,) 
    print msg 
else: 
    print "sol =", sol 

你說:

...如果解決方案無法找到我希望fsolve來回報我最初的猜測,不會弄亂解決方案的其餘部分,而不是NaN的。

fsolve無法知道您正在解決的問題實際上是一組解耦問題。你已經給了它一個單一的n維問題。要麼它成功,要麼找不到解決這個問題的辦法。