Skip to content
All library documents

Interpreting Implied Volatility Differences Across Option Strikes

Article Quant Q&A · Author: kiev

Summary

The note addresses why implied volatilities calculated from option prices differ across strikes. It explains that Black–Scholes implied volatility is the volatility input that reproduces a given market price under the model; when the model assumes a single constant volatility, observed prices across strikes can imply different values. Such strike-dependent quotes are consistent with a volatility smile or skew and do not, by themselves, prove the numerical solver is faulty.

The discussion also identifies coding issues that can affect results. In Visual Basic, a type declaration applies only to the variable immediately before it, so declaring several variables in one statement can leave most with unintended types. A bisection routine should keep a valid price bracket and terminate when its price error or interval width is sufficiently small; the included example’s labels and missing put-pricing logic also complicate comparison. Newton iteration using vega is offered as another approach, with an initial existence check. The examples are specific to European Black–Scholes pricing and do not validate the input prices or assumptions.

Key ideas

  • Different strikes can imply different volatilities because market option prices need not follow constant-volatility Black–Scholes prices.
  • Strike-dependent implied volatility can reflect a smile or skew rather than a solver bug.
  • In Visual Basic, each variable needs its own explicit type declaration.
  • Bisection requires a valid bracket and clear stopping conditions; put prices need a put-pricing implementation.
  • Newton’s method can use vega to update volatility but should check whether a valid implied volatility exists.

Tags

Full text
# Why the implied volatilities calculated are so different


# Why the implied volatilities calculated are so different












I Calculated facebook option(expired in 12/4/13) Implied Volatility with the Bisection Method. The program will be attached at the end. The results for different strike prices are so different:

```
                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
```

Can any tell me what's wrong with the program?

```
  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
```

## Answer by Bob Jansen (score 2)

https://quant.stackexchange.com/a/7592

The line

```
Dim S, X, T, r, d, Price As Double
```

is better written as

```
Dim S As Double, X As Double, T As Double, r As Double, d As Double, Price As Double
```

because 'as' only applies to the variable directly before it.

The bisection algorithm seems to work as advertised. You could check with an online calculator such as this one. I've rewritten the function to be more efficient and shorter although I believe the initial output was also correct but the column header are wrong, some puts are calls and the code for puts is not included. Anyway here is the code.

```
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
```

## Answer by 4pie0 (score 1)

https://quant.stackexchange.com/a/7569

you can use this code from Uwe Wystup FX Options and Structured Products. you can find it online. it uses vega and taylor expansion (just to 1st derivative which is vega) to find vol. you have to have code for european call price, but you have it already

```
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
```

you can find it also here

it is absolutely OK that they are different dependent on strike, you would suspect there's bug in your function otherwise. this is reality: we use BS model with const vol assumption and we quote different vol for different strike/delta

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.