1 votos

Valoración de opciones mediante la transformada discreta de Fourier (python)

Estoy tratando de implementar la fórmula de fijación de precios para una opción europea (call) que se da en el documento de Ales Cerny " Introducción a la transformada rápida de Fourier en Finanzas "(el documento se puede encontrar aquí ), de la siguiente manera:

enter image description here

Mi código python de abajo no devuelve la respuesta correcta, y en particular si aumento significativamente el número de pasos entonces obtengo una respuesta mucho mayor. ¿En qué me he equivocado?

import numpy as np
from numpy.fft import fft, ifft

def price_vanilla_option(s: float,
                         k: float,
                         r: float,
                         ro: float,
                         t: float) -> float:
    """
    price vanilla option using Fast Fourier Transform
    """

    steps = 1023  # 2^n - 1 for efficient fft
    d_t = t / steps
    discount = 1/(1 + r * d_t)

    # use CRR probabilities
    u = np.exp(ro * np.sqrt(d_t))
    d = np.exp(-ro * np.sqrt(d_t))
    p = (np.exp(r * d_t) - d)/(u - d)

    # set up terminal vector and prob vector
    c_n = np.zeros(steps + 1)
    c_n[0] = s * (d ** steps)
    for i in range(1, steps + 1):
        c_n[i] = c_n[i - 1] * u / d
    c_n = np.maximum(c_n - k, 0)
    p_vec = np.pad([p, 1 - p], (0, steps - 1))

    # fast fourier transform
    c_0 = fft(ifft(c_n) * np.power(fft(p_vec) * discount, steps))
    return np.real(c_0[0])

0 votos

¡Hola y bienvenido! No creo que esté conduciendo el problema aquí, pero ¿no deberías multiplicar por el descuento en la penúltima línea de tu código?

0 votos

... y otra pregunta: ¿estás seguro de que tus funciones en la penúltima línea son capaces de manejar números complejos?

0 votos

Muchas gracias @Kermittfrog - tienes toda la razón sobre el descuento, he actualizado en consecuencia. En su segundo punto, creo que pueden hacer - He probado tanto fft y ifft para ejemplos simples con números complejos y parecen llegar al resultado esperado.

1voto

armerc Puntos 1

En caso de que esto sea útil para cualquier otra persona que se encuentre con esto, el problema era que había configurado mi vector de valores terminales al revés (es decir, de menor a mayor en lugar de mayor a menor). El código para configurar el vector de terminales debería ser el siguiente:

# set up terminal vector and prob vector
c_n = np.zeros(steps + 1)
c_n[0] = s * (u ** steps)
for i in range(1, steps + 1):
   c_n[i] = c_n[i - 1] * d / u
c_n = np.maximum(c_n - k, 0)

Con este cambio, el código produce los resultados esperados.

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