波動率

為什麼計算的隱含波動率如此不同

  • March 24, 2013

我用二分法計算了 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

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