Other Greeks


Public Sub McOptV(F As Double, K As Double, T As Double, V As Double, R As Double, _
  Cp As String, CalcType As String, Steps As Integer, _
  Px As Double, Delta As Double, Gamma As Double, Theta As Double, Vega As Double)
  ' Calculates and returns PX (PREMIUM), DELTA, GAMMA, THETA and VEGA from
  ' Binomial calculation fixed as 50 (wSteps)
  '   F         Future price
  '   K         Strike
  '   T         Time in years to expiry
  '   V         Annualised volatility
  '   R         Continuously componded dicount rate
  '   Cp        'C'all or 'P'ut
  '   Calctype  'E'uropean, 'A'merican or 'Z' european binomial
  '   Steps     No. of binomial steps
       
       
  Dim A(0 To 2001) As Double
  Dim FSHIFT As Double, TSHIFT As Double, VSHIFT As Double
  Dim F_PLUS As Double, F_MINUS As Double, T_MINUS As Double, V_PLUS As Double
  Dim PX_NOW As Double, GkPx As Double, GkDelta As Double, PX_PLUS As Double
  Dim BinPx  As Double, DELTA_PLUS  As Double, PX_MINUS As Double
  Dim DELTA_MINUS As Double, BinDelta As Double, FF As Double
  Dim FK As Double, FT  As Double, FV As Double, ONE As Double, Discount As Double
  Dim X1 As Double, X2 As Double, CUMX1 As Double, CUMX2 As Double
  Dim z As Double, X As Double, K1 As Double, Rval As Double, PX_ODD As Double
  Dim DELTA_ODD As Double, PX_EVEN As Double, FN As Double, TN As Double
  Dim U  As Double, D As Double, P As Double, Q As Double, S As Double
  Dim VEG As Double, DELTA_EVEN  As Double
 
  Dim wx As Integer, wi As Integer, wj As Integer, wSteps As Integer
       
  On Error GoTo Errors
  GoSub 5100                                          ' Initialise
  If CalcType = "E" Then GoSub 6000                   ' European style
  If CalcType = "A" Or CalcType = "Z" Then GoSub 6100 ' Binomial
  Exit Sub
5100    '******************************************
        '   I N I T I A L I S E
        '   -------------------
        '
        Px = 0
        Delta = 0
        Gamma = 0
        Theta = 0
        Vega = 0
        Cp$ = Left$(Cp$, 1)
        CalcType = Left$(CalcType$, 1)
        If InStr(1, "CP", Cp$) = 0 Then Exit Sub
        If InStr(1, "EAZ", CalcType) = 0 Then Exit Sub
        FSHIFT = F * 0.001
        TSHIFT = 1 / 365
        VSHIFT = 0.01
        F_PLUS = F + FSHIFT
        F_MINUS = F - FSHIFT
        T_MINUS = T - TSHIFT
        V_PLUS = V + VSHIFT
        Return
6000    '******************************************
        '       E U R O P E A N     S T Y L E
        '       -----------------------------
        '
        FF = F: FK = K: FT = T: FV = V
        GoSub EuroStyle                   ' Price/delta
        Px = GkPx
        PX_NOW = GkPx
        Delta = GkDelta
       
        FF = F_PLUS: FK = K: FT = T: FV = V
        GoSub EuroStyle                    ' Price/delta on fut price + .1%
        PX_PLUS = GkPx
        DELTA_PLUS = GkDelta
       
        FF = F_MINUS: FK = K: FT = T: FV = V
        GoSub EuroStyle                     ' Price/delta on fut price - .1%
        PX_MINUS = GkPx
        DELTA_MINUS = GkDelta
        Gamma = (DELTA_PLUS - DELTA_MINUS) / (2 * FSHIFT)
        FF = F: FK = K: FT = T_MINUS: FV = V
        GoSub EuroStyle                   ' Price/delta on time - 1 day
        Theta = GkPx - PX_NOW
        FF = F: FK = K: FT = T: FV = V_PLUS
        GoSub EuroStyle                     ' Price/delta on volatity + .01
        Vega = GkPx - PX_NOW
        Return
6100    '***************************************************************
        '       B I N O M I A L    S T Y L E
        '       ----------------------------
        '
        FF = F: FK = K: FT = T: FV = V
        GoSub BinOEStyle              ' Price/delta
        Px = BinPx
        PX_NOW = BinPx
        Delta = BinDelta
       
        FF = F_PLUS: FK = K: FT = T: FV = V
        GoSub BinOEStyle            '  Price/delta on fut price + .1%
        PX_PLUS = BinPx
        DELTA_PLUS = BinDelta
       
        FF = F_MINUS: FK = K: FT = T: FV = V
        GoSub BinOEStyle            ' Price/delta on fut price - .1%
        PX_MINUS = BinPx
        DELTA_MINUS = BinDelta
        Gamma = (DELTA_PLUS - DELTA_MINUS) / (2 * FSHIFT)
       
        FF = F: FK = K: FT = T_MINUS: FV = V
        GoSub BinOEStyle            ' Price/delta on time - 1 day
        Theta = BinPx - PX_NOW
        
        FF = F: FK = K: FT = T: FV = V_PLUS
        GoSub BinOEStyle            ' Price/delta on volatity + .01
        Vega = BinPx - PX_NOW
        Return
EuroStyle:
    ' European style calc (GK), returns GkPx and GkDelta
    If FT <= 0 Then
      GkDelta = 0
      If Cp = "C" Then GkPx = FnMax(FF - FK, 0)
      If Cp = "P" Then GkPx = FnMax(FK - FF, 0)
      Return
    End If
    ONE = 0
    If Cp = "P" Then ONE = 1
    Discount = Exp(-R * FT)
    X1 = (Log(FF / FK) + FV * FV / 2 * FT) / (FV * FT ^ 0.5)
    X2 = X1 - FV * FT ^ 0.5
    CUMX1 = FnCum(X1) - ONE
    CUMX2 = FnCum(X2) - ONE
    GkPx = Discount * (FF * CUMX1 - FK * CUMX2)
    GkDelta = Discount * CUMX1
    Return
BinOEStyle:
  ' Binomial calc on odd and even. Returns BinPx and BinDelta
  wSteps = Steps
  GoSub BinCalc
  PX_ODD = BinPx
  DELTA_ODD = BinDelta
  wSteps = Steps + 1
  GoSub BinCalc
  PX_EVEN = BinPx
  DELTA_EVEN = BinDelta
  BinPx = (PX_ODD + PX_EVEN) / 2
  BinDelta = (DELTA_ODD + DELTA_EVEN) / 2
  Return
 
BinCalc:
    ' Binomial calculation, returns BinPx and BinDelta
    If FT <= 0 Then
      BinDelta = 0
      If Cp = "C" Then BinPx = FnMax(FF - FK, 0)
      If Cp = "P" Then BinPx = FnMax(FK - FF, 0)
      Return
    End If
    TN = FT / wSteps
    U = Exp(FV * TN ^ 0.5)
    D = 1 / U
    P = (Exp(R * TN) / Exp(R * TN) - D) / (U - D)
    Q = 1 - P
    Select Case Cp
      Case "C"
        For wi = wSteps To 0 Step -1
          A(wi) = FnMax(0, FF * U ^ wi * D ^ (wSteps - wi) - FK)
        Next wi
      Case "P"
        For wi = wSteps To 0 Step -1
          A(wi) = FnMax(0, FK - FF * U ^ wi * D ^ (wSteps - wi))
        Next wi
     End Select
         
     If CalcType = "Z" Then
       wx = 0
       For wj = 1 To wSteps Step 1
         S = FF * D ^ (wSteps - wj + 1) / U
         For wi = 0 To (wSteps - wj) Step 1
           S = S * U / D
           A(wi) = (P * A(wi + 1) + Q * A(wi)) * Exp(-R * TN)
         Next wi
         If wj = wSteps - 1 Then BinDelta = (A(1) - A(0)) / (FF * U - FF * D)
       Next wj
       BinPx = A(0)
     End If
         
     If CalcType = "A" Then
       wx = 0
       For wj = 1 To wSteps Step 1
         S = FF * D ^ (wSteps - wj + 1) / U
         For wi = 0 To (wSteps - wj) Step 1
           S = S * U / D
           If Cp = "C" Then A(wi) = FnMax(S - FK, (P * A(wi + 1) + Q * A(wi)) * Exp(-R * TN))
           If Cp = "P" Then A(wi) = FnMax(FK - S, (P * A(wi + 1) + Q * A(wi)) * Exp(-R * TN))
          Next wi
          If wj = (wSteps - 1) Then BinDelta = (A(1) - A(0)) / (FF * U - FF * D)
        Next wj
        BinPx = A(0)
      End If
      Return
     
Errors:
    Resume Errors2
   
Errors2:
    Px = 0
    Delta = 0
    Gamma = 0
    Theta = 0
    VEG = 0
    Exit Sub
End Sub
       
Function FnCum(z As Double) As Double
  ' Used in McOptV
  Dim Rval As Double, K1 As Double, X As Double
  Dim Alpha As Double, Pie As Double, a1 As Double, a2 As Double, a3 As Double
 
  Alpha = 0.33267
  a1 = 0.4361836
  a2 = -0.1201676
  a3 = 0.937298
  Pie = 3.141593
     
  X = Abs(z)
  K1 = 1 / (1 + Alpha * X)
  Rval = 1 - 1 / (2 * Pie) ^ 0.5 * Exp(-X * X / 2) * (a1 * K1 + a2 * K1 * K1 + a3 * K1 * K1 * K1)
  If z < 0 Then Rval = 1 - Rval
  FnCum = Rval
 
End Function
Function FnMax(N1 As Double, N2 As Double) As Double
  If N1 > N2 Then
    FnMax = N1
  Else
    FnMax = N2
  End If
End Function