波動率微笑的多項式插值之差
我使用 5 個波動點來建構波動微笑:放置 10D、放置 25D、ATMF、呼叫 25D 和呼叫 10D。因此,我有 5 對數據: (Delta, Vol) 比如說 (10;5.75) ;(25; 5.50) ; (50;5.25); (75;5.60) ; (90;5.70)。
我正在做一個簡單的拉格朗日插值,如下所示:
x = np.array([10, 25, 50, 75, 90]) #LIST OF DELTA y = np.array([]) for index, elt in enumerate(vols[currency][tenor]): y=np.append(y,vols[currency][tenor][elt]) interpolation = lagrange(x, y) #TO KEEP xpol = np.linspace(x[0], x[4], 90) ypol_lag = interpolation(xpol) plt.scatter(x, y, marker='s', c='r') plt.plot(xpol, ypol_lag, "b") plt.show()
考慮到我可以在彭博社觀察到的市場數據,這會帶來一個很好的微笑,非常現實:
然後,根據 Wystup, 2010 提供的公式,我正在轉換罷工中的每個增量:
因此我有我所有的貨幣對(Strike, vol),例如: (10;1.1650) ; (25;1.1710);(50;1.1800) ; (75;1.1840); (90;1.1950)(非實數)。
如果我繪製這五個數字並使用與 deltas 相同的函式對它們進行插值:
x = np.array([K10p, K25p, K50, K25c, K10c]) y = np.array([]) for index, elt in enumerate(vols[currency][tenor]): y=np.append(y,vols[currency][tenor][elt]) interpolation = lagrange(x, y) xpol = np.linspace(x[0], x[4], 90) ypol_lag = interpolation(xpol) plt.scatter(x, y, marker='s', c='r') plt.plot(xpol, ypol_lag, "r") plt.show()
我不知道如何通過罷工獲得類似的插值……
謝謝你。
這不是一個真正的答案,但評論太長了。
拉格朗日/三次樣條插值對輸入數據非常敏感,給定稍微不同的輸入數據,它可以產生截然不同的插值。它不僅會影響相鄰點,還會影響曲線上的不同點。考慮這個例子。
x = np.array([10, 25, 50, 75, 90]) #LIST OF DELTA y = np.array([5.60, 5.40, 5.25, 5.28, 5.35]) interpolation = lagrange(x, y) xpol = np.linspace(x[0], x[4], 90) ypol_lag = interpolation(xpol) plt.scatter(x, y, marker='s', c='r') plt.plot(xpol, ypol_lag, "b") plt.show()
現在讓我們只更改第二點:
x = np.array([10, 35, 50, 75, 90]) #change from 25 to 35 y = np.array([5.60, 5.40, 5.25, 5.28, 5.35])
結果:
我們只改變了第 2 點,但整個曲線發生了變化(第 4 點和第 5 點之間的插值也發生了變化!)。三次樣條的問題在於它找到了求解線性方程組的參數,而找到的參數會影響整個曲線。三次樣條以這種方式是“不穩定的”。當您在罷工中轉換每個增量時,您正在以非線性方式更改輸入,從而導致整個曲線發生變化。
如果無論如何你想使用三次樣條插值,解決這個問題的方法是首先在轉換之前對數據進行插值(比如增量),然後對插值數據應用轉換。您應該在轉換之前和之後獲得相似的形狀。更準確地說,您有 5 個增量,例如對 20 個增量插入微笑。然後通過您使用的公式轉換 20 中的每個點。然後對 20 次罷工進行插值並繪製結果。
編輯:我已經在上面嘗試過這種方法進行拉格朗日插值,但我得到了數值不穩定的輸出。根據 numpy 文件,當我們有 20 個數據點時,這個函式是不穩定的。
警告:此實現在數值上不穩定。即使選擇最佳,也不要期望能夠使用超過 20 個點。
因此,我切換到 CubicSpline 函式,它產生與拉格朗日相同的圖形,但數值穩定。
當您執行以下程式碼時:
x = np.array([10, 25, 50, 75, 90]) y = np.array([5.60, 5.40, 5.25, 5.28, 5.35]) # We first interpolate data on deltas to create 20 points interpolation = CubicSpline(x, y) xpol = np.linspace(x[0], x[4], 20) ypol_lag_org = interpolation(xpol) # We then transform delta in strike by the equation for all points interpolated, we now have 20 points K_list = [] for a, b in zip(xpol,ypol_lag_org): K = np.exp(norm.ppf(a/100)*(b/100)+0.5*((b/100)**2)) K_list.append(K) K_list = np.array(K_list) # this is vector of 20 numbers # And then we interpolate the rest of the points and produce a graph interpolation = CubicSpline(K_list, ypol_lag_org) xpol = np.linspace(K_list[0], K_list[-1], 90) ypol_lag = interpolation(xpol) plt.scatter(K_list, ypol_lag_org, marker='s', c='r') plt.plot(xpol, ypol_lag, "b") plt.show()
你會得到一些看起來像微笑但在 (strike,vol) 空間中的東西。附加點增強了曲線的穩定性。