Cuestión breve: Tengo valores para las Opciones Asiáticas que estoy tratando de replicar usando una calculadora vba de construcción propia. Los valores que tengo que golpear es de FinCAD y estoy usando una opción de tasa media aritmética discreta basada en Haug, Haug y Margrabe y también tratando la versión Curran (implementado en VBA). Todo el código a continuación:
Más información: Estoy seguro de que calculamos utilizando las informaciones de manera diferente ya que mi valor es bastante diferente al de él. Debajo está la entrada exacta utilizada:
- Opción de compra asiática (precio medio, no de ejercicio)
- Fecha de valoración: 06-04-2017
- Periodo de promediación: 01-05-2017 hasta 31-05-2017 (mayo)
- Precio subyacente (al 05-04-2017): 515,25
- Huelga: 515
- Volatilidad: 20.669%.
- Tasa libre de riesgo: 0,980%
Utilizo los días laborables (en mi país) así que:
- Tiempo hasta el siguiente punto medio (t1): 15 días (del 06-04-2017 al 01-05-2017)
- Plazo de vencimiento (T): 35 días (del 06-04-2017 al 31-05-2017)
Mis valores (después de usar 252):
- Valor asiático (Haug, Haug y Margrabe): 12,7763
- Valor asiático (Curran): 12,7753
- Valor europeo BS: 16.2952
Es un valor:
- 18.64
Simplemente no puedo entender la diferencia. No se trata sólo de los días utilizados. Tal vez sea la volatilidad. También porque mi valor europeo de BS es inferior al de él y eso no debería ser así. También he validado mis valores según las calculadoras disponibles gratuitamente en www. Acabo de recibir la información de que FinCAD está utilizando su función, aaGeo_Asian, así que probé una versión geométrica, pero todavía no se obtienen los números. No tengo información sobre los detalles de su función. Sin embargo, podría parecer que también utilizan valores futuros proyectados y no "sólo" el precio actual del subyacente.
Public Function DiscreteAsianHHM(runFlag As String, CallPutFlag As String,
TimeFlag As String, ContinuousFlag As String, S As Double, SA As Double, X
As Double, _
input_t1 As Double, input_t As Double, n As Double, m As Double,
input_r As Double, input_b As Double, v As Double) As Double
Dim d1 As Double, d2 As Double, h As Double, EA As Double, EA2 As Double
Dim vA As Double, OptionValue As Double
Dim t1 As Double, T As Double
Dim r As Double, b As Double
'Making sure of the chosen input time (years/days)
t1 = TimeConvert(TimeFlag, input_t1)
T = TimeConvert(TimeFlag, input_t)
'Converting to continious compounding rate
r = CCRConvert(ContinuousFlag, input_r)
b = CCRConvert(ContinuousFlag, input_b)
' Calculate either Asian (A) or plain European (E) by BS formula
If runFlag = "A" Then
h = (T - t1) / (n - 1)
If b = 0 Then
EA = S
Else
EA = S / n * Exp(b * t1) * (1 - Exp(b * h * n)) / (1 - Exp(b * h))
End If
'If we are in the averaging period and way ITM
If m > 0 Then
If SA > n / m * X Then ' Exercise is certain for call, put must be
out-of-the-money
If CallPutFlag = "Put" Then
DiscreteAsianHHM = 0
ElseIf CallPutFlag = "Call" Then
SA = SA * m / n + EA * (n - m) / n
DiscreteAsianHHM = (SA - X) * Exp(-r * T)
End If
Exit Function
End If
End If
If m = n - 1 Then ' Only one fix left use Black-Scholes weighted with
time
X = n * X - (n - 1) * SA
DiscreteAsianHHM = GBlackScholes(CallPutFlag, S, X, T, r, b, v) * 1
/ n
Exit Function
End If
If b = 0 Then
EA2 = S * S * Exp(v * v * t1) / (n * n) _
* ((1 - Exp(v * v * h * n)) / (1 - Exp(v * v * h)) _
+ 2 / (1 - Exp(v * v * h)) * (n - (1 - Exp(v * v * h * n)) / (1 -
Exp(v * v * h))))
Else
EA2 = S * S * Exp((2 * b + v * v) * t1) / (n * n) _
* ((1 - Exp((2 * b + v * v) * h * n)) / (1 - Exp((2 * b + v * v)
* h)) _
+ 2 / (1 - Exp((b + v * v) * h)) * ((1 - Exp(b * h * n)) / (1 -
Exp(b * h)) _
- (1 - Exp((2 * b + v * v) * h * n)) / _
(1 - Exp((2 * b + v * v) * h))))
End If
vA = Sqr((Log(EA2) - 2 * Log(EA)) / T)
OptionValue = 0
'If we are in the averaging period we need to adjust the strike price
If m > 0 Then
X = n / (n - m) * X - m / (n - m) * SA
End If
d1 = (Log(EA / X) + vA ^ 2 / 2 * T) / (vA * Sqr(T))
d2 = d1 - vA * Sqr(T)
If CallPutFlag = "Call" Then
OptionValue = Exp(-r * T) * (EA * CND(d1) - X * CND(d2))
ElseIf (CallPutFlag = "Put") Then
OptionValue = Exp(-r * T) * (X * CND(-d2) - EA * CND(-d1))
End If
DiscreteAsianHHM = OptionValue * (n - m) / n
ElseIf runFlag = "E" Then
'Generalized BS model
DiscreteAsianHHM = GBlackScholes(CallPutFlag, S, X, T, r, b, v)
End If
End Function
Public Function TimeConvert(TimeFlag As String, input_t As Double) As Double
If TimeFlag = "Days" Then
TimeConvert = input_t / 252
Else
TimeConvert = input_t
End If
End Function
'The generalized Black and Scholes formula
Public Function GBlackScholes(CallPutFlag As String, S As Double, X _
As Double, T As Double, r As Double, b As Double, v As Double)
As Double
Dim d1 As Double, d2 As Double
'I thought this was a mistake but note that q=r-b. r is risk free rate, b is
cost of carry and q is dividend
d1 = (Log(S / X) + (b + v ^ 2 / 2) * T) / (v * Sqr(T))
d2 = d1 - v * Sqr(T)
If CallPutFlag = "Call" Then
GBlackScholes = S * Exp((b - r) * T) * CND(d1) - X * Exp(-r * T) * CND(d2)
ElseIf CallPutFlag = "Put" Then
GBlackScholes = X * Exp(-r * T) * CND(-d2) - S * Exp((b - r) * T) * CND(-d1)
End If
End Function
Public Function CCRConvert(ContinuousFlag As String, rate As Double) As
Double
If ContinuousFlag = "Continuous" Then
CCRConvert = rate
ElseIf ContinuousFlag = "Annual" Then
CCRConvert = Log(1 + rate)
ElseIf ContinuousFlag = "Semi-annual" Then
CCRConvert = 2 * Log(1 + rate / 2)
ElseIf ContinuousFlag = "Quarterly" Then
CCRConvert = 4 * Log(1 + rate / 4)
ElseIf ContinuousFlag = "Monthly" Then
CCRConvert = 12 * Log(1 + rate / 12)
ElseIf ContinuousFlag = "Daily" Then
CCRConvert = 252 * Log(1 + rate / 252)
End If
End Function
'Using the build in cummulative normal distribution
Function CND(X As Double) As Double
CND = WorksheetFunction.Norm_Dist(X, 0, 1, True)
End Function