4 votos

Números complejos en VBA

Hey Intento de fijar precios de opciones en VBA. Para hacer esto necesito definir una función característica y hacer algunas operaciones con números complejos. Por ejemplo, tengo este código:

Function cf(u, T, r, q, sigma)
i = WorksheetFunction.Complex(0, 1)
b = r - q - 0.5 * sigma ^ 2
cf = WorksheetFunction.ImExp(T * (i * u * b - 0.5 * u ^ 2 * sigma ^ 2)
End Function

Pero no funciona. Sé que WorksheetFunction.Complex(0, 1) devuelve una cadena y me pregunto cómo hacer esto para que funcione este código. ¿Quizás hay alguna biblioteca mejor?

8voto

Foxy Puntos 46

¡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?

0 votos

Recuerdo implementar un código que imprime un conjunto de Mandelbrot en la pantalla: la forma en que lo hice fue simplemente definir un número complejo como $c=a+b$, donde tanto $a$ como $b$ son números decimales regulares y $b$ representa la parte imaginaria. Luego, uno puede realizar operaciones como $c^2$ usando la lógica: "$Real = a^2-b^2$", "$Complejo = 2ab$". Creo que es posible trabajar con números complejos sin tener que llamar a funciones "complejas" de excel: en su lugar, uno puede simplemente codificar la lógica que resuelve las partes reales e imaginarias de varias operaciones....

1 votos

Hola @JanStuller sí eso funciona hasta cierto punto. Pero en algún momento querrás introducir logaritmos complejos, exponenciales, etc... ahí es donde comienza la diversión. Terminé con una clase para todas estas operaciones, y mi integral compleja en VBA todavía está un poco desviada debido a subdesbordamientos numéricos en algunos cálculos de ángulos :-D

0 votos

Por curiosidad, ¿alguna vez has usado números complejos para alguna cosa en finanzas?

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X