程式

反轉上限價格的黑色公式以找到黑色隱含波動率

  • August 9, 2021

作為Coursera 上利率模型課程的一部分,我正在解決以下問題

1 因子高斯 HJM 的校準

我很難使用非線性根求解器來反轉上限價格的黑色公式,以獲得將進一步用於校準目的的黑色隱含波動率。我的 Python 程式碼附在下面。

import numpy as np
import math
import scipy
from scipy import optimize
from scipy import stats

Time = [0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4]
ForwardRates = [0.06, 0.08, 0.09, 0.10, 0.10, 0.10, 0.09, 0.09]
CapPrices = [0.20, 0.80, 1.20, 1.60]
SimpleRates = []
DiscountFactors = []

SimpleRates.append(ForwardRates[0])
DiscountFactors.append(1/(1+Time[0]*SimpleRates[0]))

for i in range(1, len(Time)):
   SimpleRates.append(((1+0.5*ForwardRates[i])*(1+Time[i-1]*SimpleRates[i-1])-1)/Time[i])
   DiscountFactors.append(1/(1+Time[i]*SimpleRates[i]))

SwapRates = []
for k in range(1, len(Time)):
   s = sum(DiscountFactors[i] for i in range(1, k + 1))
   SwapRates.append((DiscountFactors[0] - DiscountFactors[k])/(0.5*s))

def d1(i, sigma):
   return (np.log(ForwardRates[i]/SwapRates[i])+0.5*math.pow(sigma, 2)*Time[i-1])/(sigma*math.sqrt(Time[i-1]))

def d2(i, sigma):
   return (np.log(ForwardRates[i]/SwapRates[i])+math.pow(sigma, 2)*Time[i-1])/(sigma*math.sqrt(Time[i-1])) - sigma*math.sqrt(Time[i-1])

def caplet(begin, end, sigma):
   return 0.5*DiscountFactors[end]*(ForwardRates[end]*scipy.stats.norm.cdf(d1(end, sigma))-SwapRates[end]*scipy.stats.norm.cdf(d2(end, sigma)))

def cap(end, sigma):
   price = 0
   for j in range(1, end + 1):
       price += caplet(j - 1, j, sigma)
   return price

s = scipy.optimize.bisect(lambda sigma: cap(1, sigma) - CapPrices[0], 0.0005, 0.5)

我收到一個錯誤,即 f(a) 和 f(b) 必須具有不同的符號,無論我的間隔選擇如何。我應該在 Python 中使用什麼特定的根求解方法來解決這個問題?還有什麼我做錯了嗎?

請注意,上限價格以百分比形式給出,因此您的上限價格向量應該是

CapPrices = [0.002, 0.008, 0.012, 0.016]

當你有

CapPrices = [0.20, 0.80, 1.20, 1.60]

程式碼應該為這些上限價格找到沒有問題的解決方案。

請注意,對於您錯誤給出的 CapPrices,沒有解決方案。注意:

$ {Caplet(F,\sigma,t) \to F} $ 作為 $ \sigma \to \infty $ . 因此最高的 caplet 值是 $ F $ ,但您正試圖大致找到解決方案 $ 2.5F $ 即 (0.20 / 0.08 = 2.5),因此求解器失敗。

我還注意到您在 d2 中的公式有錯誤,它應該等於:

return (np.log(ForwardRates[i]/SwapRates[i])+0.5*math.pow(sigma, 2)*Time[i-1])/(sigma*math.sqrt(Time[i-1])) - sigma*math.sqrt(Time[i-1])

雖然你有(缺少乘以 0.5)

return (np.log(ForwardRates[i]/SwapRates[i])+math.pow(sigma, 2)*Time[i-1])/(sigma*math.sqrt(Time[i-1])) - sigma*math.sqrt(Time[i-1])

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