波動率
為什麼計算的隱含波動率如此不同
我用二分法計算了 facebook 期權(13 年 12 月 4 日到期)隱含波動率。程序將在最後附上。不同行使價的結果是如此不同:
call put call put put Stock Price 26.55 26.55 26.55 26.55 26.55 Strike Price 26.5 26.5 27 27 28 Time to maturity 0.06301 Risk Free Rate 1.88E-02 Dividend Yield 0 0 0 0 Option Price 0.87 0.86 0.63 1.08 1.65 Result Implied Volatility 0.312236566 0.308462006 0.306893589 0.477272194 0.840291866
誰能告訴我程序有什麼問題?
Public TargetColume As Integer Function BlackScholesCall( _ ByVal S As Double, _ ByVal X As Double, _ ByVal T As Double, _ ByVal r As Double, _ ByVal d As Double, _ ByVal v As Double) As Double Dim d1 As Double Dim d2 As Double d1 = (Log(S / X) + (r - d + v ^ 2 / 2) * T) / v / Sqr(T) d2 = d1 - v * Sqr(T) BlackScholesCall = Exp(-d * T) * S * Application.NormSDist(d1) - X * Exp(-r * T) * Application.NormSDist(d2) End Function Function ImpliedVolatility( _ ByVal S As Double, _ ByVal X As Double, _ ByVal T As Double, _ ByVal r As Double, _ ByVal d As Double, _ ByVal Price As Double) As Double Dim epsilonABS As Double Dim epsilonSTEP As Double Dim volMid As Double Dim niter As Integer Dim volLower As Double Dim volUpper As Double epsilonABS = 0.0000001 epsilonSTEP = 0.0000001 niter = 0 volLower = 0.001 volUpper = 1 Do While volUpper - volLower >= epsilonSTEP Or Abs(BlackScholesCall(S, X, T, r, d, volLower) - Price) >= epsilonABS And epsilonABS <= Abs(BlackScholesCall(S, X, T, r, d, volUpper) - Price) >= epsilonABS volMid = (volLower + volUpper) / 2 If Abs(BlackScholesCall(S, X, T, r, d, volMid) - Price) <= epsilonABS Then Exit Do ElseIf ((BlackScholesCall(S, X, T, r, d, volLower) - Price) * (BlackScholesCall(S, X, T, r, d, volMid) - Price) < 0) Then volUpper = volMid Else volLower = volMid End If niter = niter + 1 Loop ImpliedVolatility = volLower End Function Function CalcImpliedVolatility() Dim S, X, T, r, d, Price As Double Dim volatility As Double S = ActiveSheet.Cells(6, TargetColume).Value X = ActiveSheet.Cells(7, TargetColume).Value T = ActiveSheet.Cells(8, "B").Value r = ActiveSheet.Cells(9, "B").Value d = ActiveSheet.Cells(10, TargetColume).Value Price = ActiveSheet.Cells(11, TargetColume).Value volatility = ImpliedVolatility(S, X, T, r, d, Price) ActiveSheet.Cells(14, TargetColume).Value = volatility End Function Private Sub CommandButton1_Click() CalcImpliedVolatility End Sub Private Sub Worksheet_SelectionChange(ByVal Target As Range) TargetColume = Target.Column End Sub
線
Dim S, X, T, r, d, Price As Double
最好寫成
Dim S As Double, X As Double, T As Double, r As Double, d As Double, Price As Double
因為’as’只適用於它之前的變數。
二分算法似乎像宣傳的那樣工作。你可以用一個線上計算器來檢查,比如這個。儘管我相信初始輸出也是正確的,但列標題錯誤,但我已將函式重寫為更高效和更短,一些 puts 是呼叫,並且不包括 puts 的程式碼。無論如何,這裡是程式碼。
Private Const maxIter As Long = 100000# Private Const epsilonABS As Double = 0.0000001 Private Const epsilonSTEP As Double = 0.0000001 Public Function ImpliedVolatility( _ S As Double, X As Double, T As Double, r As Double, d As Double, _ Price As Double _ ) As Double Dim volMid As Double, valMid As Double, diff As Double Dim niter As Integer volLower = 0.001 volUpper = 1 niter = 0 Do volMid = (volLower + volUpper) / 2 valMid = BlackScholesCall(S, X, T, r, d, volMid) diff = Abs(valMid - Price) If valMid > Price Then volUpper = volMid Else volLower = volMid End If niter = niter + 1 Loop While volUpper - volLower >= epsilonSTEP And diff > epsilonABS And _ niter < maxIter ImpliedVolatility = volMid End Function
您可以使用 Uwe Wystup FX 期權和結構化產品中的此程式碼。你可以在網上找到它。它使用 vega 和 taylor 展開(只是到 vega 的一階導數)來找到 vol。你必須有歐洲通話價格的程式碼,但你已經有了
Function VanillaVolRetriever(spot As Double, rd As Double,rf As Double, strike As Double, T As Double, type As Integer, GivenValue As Double) As Double Dim func As Double Dim dfunc As Double Dim maxit As Integer ’maximum number of iterations Dim j As Integer Dim s As Double ’first check if a volatility exists, otherwise set result to zero If GivenValue<Application.Max(0,type*(spot*Exp(-rf*T)-strike*Exp(-rd * T)))Or(type = 1 And GivenValue > spot*Exp(-rf * T)) Or (type = -1 And GivenValue > strike * Exp(-rd * T)) Then VanillaVolRetriever = 0 Else ’ there exists a volatility yielding the given value, ’ now use Newton’s method: ’ the mapping vol to value has a saddle point. ’ First compute this saddle point: saddle = Sqr(2/T * Abs(Log(spot / strike) + (rd - rf) * T)) If saddle > 0 Then VanillaVolRetriever = saddle * 0.9 Else VanillaVolRetriever = 0.1 End If maxit = 100 For j = 1 To maxit Step 1 func = Vanilla(spot, strike, VanillaVolRetriever, rd, rf, T, type, value) - GivenValue dfunc = Vanilla(spot, strike, VanillaVolRetriever,rd, rf, T, type, vega) VanillaVolRetriever = VanillaVolRetriever - func / dfunc If VanillaVolRetriever <= 0 Then VanillaVolRetriever = 0.01 If Abs(func / dfunc) <= 0.0000001 Then j = maxit Next j End If End Function
你也可以在這裡找到
它們完全取決於罷工是完全可以的,否則您會懷疑您的功能中存在錯誤。這就是現實:我們使用具有 const vol 假設的 BS 模型,並為不同的罷工/增量引用不同的 vol