Processing math: 100%

4 votos

Números complejos en VBA

¡Hola! Estoy tratando de calcular precios de opciones en VBA. Para hacer esto necesito definir una función característica y realizar 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 hacerlo para que este código funcione. ¿Quizás hay bibliotecas mejores disponibles?

8voto

Foxy Puntos 46

Ahhh números complejos en Excel VBA, la cima de la programación de oficina. ¡Lo he hecho antes, ya lo he vivido!

Las funciones que mencionas son en efecto que devuelven tipos de 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 de todas formas Excel 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 "variance:", Round(CDbl(x2) - CDbl(x1) ^ 2, 6), sigma ^ 2 * ttm
End Sub

dará como resultado

drift:         0,03          0,03 
variance:      0,04          0,04 

es decir, la expectativa de retorno.

Si deseas otra implementación, hay una disponible en pfadintegral (nunca la he verificado). Otro camino, por supuesto, sería componer tu propia biblioteca en VBA (como dije, ¡lo he hecho antes, ya lo he vivido!), pero creo que puede que no valga la pena ya que hay muchos casos especiales a tener en cuenta, por ejemplo, cortes de rama, desbordamiento numérico, etc. ...

¿Te ayuda?

0 votos

Recuerdo haber implementado 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 floats regulares y b representa la parte imaginaria. Luego, se pueden realizar operaciones como c2 usando la lógica: "Real=a2b2", "Complejo=2ab". Creo que es posible trabajar con números complejos sin tener que llamar a funciones "complejas" de Excel, en cambio, se puede simplemente codificar la lógica que trabaja en las partes real e imaginaria de varias operaciones....

1 votos

Hola @JanStuller sí, eso funciona hasta cierto punto. Pero en algún momento quieres 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 los desbordamientos numéricos en algunos cálculos de ángulos :-D

0 votos

Por curiosidad, ¿alguna vez has usado números complejos para algo 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