¡Ahhh números complejos en Excel VBA, la cumbre de la programación en la oficina. ¡Estuve allí, lo hice!
Las funciones que citas de hecho están devolviendo tipos string
. Pero deberías ser capaz de componer esas funciones, por ejemplo
Option Explicit
Public Function cf(u As Double, ttm As Double, rf As Double, q As Double, s As Double) As String
Dim b As Double
b = rf - q - 0.5 * s ^ 2
If u = 0 Then
cf = "1.0"
Else
With Application.WorksheetFunction
cf = .ImExp(.Complex(-0.5 * u ^ 2 * s ^ 2 * ttm, ttm * u * b))
End With
End If
End Function
Esta función ahora devolverá un tipo string, pero Excel aún puede consumirla:
Sub ATest()
Dim z1 As String, z2 As String, z3 As String
Dim x1 As Double, x2 As Double
' algunos parámetros
Const ttm As Double = 1#
Const rf As Double = 0.05
Const q As Double = 0#
Const sigma As Double = 0.2
Const eps As Double = 0.0001
z1 = cf(-eps, ttm, rf, q, sigma)
z2 = cf(0, ttm, rf, q, sigma)
z3 = cf(eps, ttm, rf, q, sigma)
With Application.WorksheetFunction
x1 = .ImReal(.ImDiv( _
.ImSub(z3, z1), _
.Complex(0, 2 * eps))) ' estimador de primer momento
x2 = .ImReal(.ImDiv( _
.ImSum(.ImSub(z1, z2), .ImSub(z3, z2)), _
.Complex(-eps * eps, 0))) ' estimador de segundo momento
End With
Debug.Print "drift:", Round(CDbl(x1), 6), (rf - 0.5 * sigma ^ 2) * ttm
Debug.Print "varianza:", Round(CDbl(x2) - CDbl(x1) ^ 2, 6), sigma ^ 2 * ttm
End Sub
dará como resultado
drift: 0,03 0,03
varianza: 0,04 0,04
es decir, la expectativa de retorno.
Si deseas otra implementación, hay una disponible en pfadintegral (Nunca la he revisado). Otro camino, por supuesto, sería componer tu propia biblioteca en VBA (como dije, ¡Estuve allí, lo hice!), pero creo que puede que no valga la pena ya que hay muchos casos especiales para pensar, como cortar ramas, desbordamiento numérico, etc. ...
¿Te ayuda eso?