2 votos

Aplicación del modelo de tarifas cortas de Hull y White

Es la primera vez que uso quantlib, y quería comparar la velocidad de quantlib con mi propio código Python.

He encontrado un tutorial sobre Hull y White para generar las trayectorias de tasa corta con quantlib: ( Tutorial sobre el casco y el blanco )

El autor parece decir que es muy sencillo cambiar la tasa instantánea futura, que es una constante en el ejemplo... Pero cuando lo sustituyo por un array de 361 valores correspondientes a los valores de la tasa futura para las diferentes fechas definidas por el paso de tiempo, me aparece el siguiente error TypeError: in method 'new_SimpleQuote', argument 1 of type 'Real'

He intentado investigar y buscar en la librería quantlib cómo solucionar esto, pero aún no he aprendido a codificar en C++ así que puede que necesite un poco de ayuda

Gracias, y que tenga un buen día

PD: Mis datos de entrada son la curva de cupón cero en un momento determinado, así que si es posible utilizarla directamente en lugar de convertirla primero en una curva de tipos futuros, me interesa saber cómo hacerlo

Edición: Este es mi código

import QuantLib as ql
import matplotlib.pyplot as plt
import numpy as np

sigma = 0.1
a = 0.1
timestep = 360
length = 30 # in years
#forward_rate = 0.05 I replaced this line by an random array and it doesn't work
forward_rate=np.random.randn(361)
day_count = ql.Thirty360()
todays_date = ql.Date(15, 1, 2015)
print(ql.QuoteHandle(ql.SimpleQuote(forward_rate)))

ql.Settings.instance().evaluationDate = todays_date
spot_curve = ql.FlatForward(todays_date, 
ql.QuoteHandle(ql.SimpleQuote(forward_rate)), day_count)
spot_curve_handle = ql.YieldTermStructureHandle(spot_curve)

hw_process = ql.HullWhiteProcess(spot_curve_handle, a, sigma)
rng = ql.GaussianRandomSequenceGenerator(
           ql.UniformRandomSequenceGenerator(timestep, ql.UniformRandomGenerator()))
seq = ql.GaussianPathGenerator(hw_process, length, timestep, rng, False)

def generate_paths(num_paths, timestep):
    arr = np.zeros((num_paths, timestep+1))
    for i in range(num_paths):
        sample_path = seq.next()
        path = sample_path.value()
        time = [path.time(j) for j in range(len(path))]
        value = [path[j] for j in range(len(path))]
        arr[i, :] = np.array(value)
    return np.array(time), arr

num_paths = 10
time, paths = generate_paths(num_paths, timestep)
for i in range(num_paths):
    plt.plot(time, paths[i, :], lw=0.8, alpha=0.6)
plt.title("Hull-White Short Rate Simulation")
plt.show()

0 votos

Hola y bienvenido a SE. ¿Podrías añadir a tu pregunta un ejemplo mínimamente reproducible que cualquier persona dispuesta a ayudar pueda ejecutar para obtener el mismo error que te da? Así será más fácil ayudarte :) Gracias

1 votos

@byouness Vale, edito mi post para añadir el código. Al parecer no puedo publicar el código en un comentario porque es demasiado largo

1voto

tralston Puntos 76

Cuando llame ql.FlatForward simplemente significa que está construyendo una curva de tipos que conducirá a unos tipos a plazo planos.

El constructor de esta curva toma la tasa de avance como entrada. Si quieres cambiar la entrada (digamos, porque el mercado se movió y el valor a plazo cambió), entonces puedes cambiar el valor de la comilla con el nuevo valor así. Primero, mantenga un puntero en la comilla:

forward_rate = 0.05
quote = ql.SimpleQuote(forward_rate)
spot_curve = ql.FlatForward(todays_date, ql.QuoteHandle(quote), day_count)
print(spot_curve.zeroRate(1.0, ql.Continuous))
# 5.000000 % 30/360 (Bond Basis) continuous compounding

A continuación, utilice el setValue() para actualizar el valor, así:

quote.setValue(0.04)
print(spot_curve.zeroRate(1.0, ql.Continuous))
# 4.000000 % 30/360 (Bond Basis) continuous compounding

No se puede pasar un array de valores a setValue() La comilla consiste en un único valor (= el valor del tipo de interés a plazo en este caso). En particular, no entiendo por qué se quiere hacer que este forward sea aleatorio?

Ahora, para responder a tu otra pregunta, puedes instanciar una curva cero directamente usando una lista de fechas y una lista de tipos cero de esta manera:

ql.ZeroCurve(dates, rate_values, day_counter)

Por ejemplo:

zero_curve = ql.ZeroCurve([todays_date + ql.Period(p) for p in ['6M', '1Y', '5Y', '10Y']],
                          [0.04, 0.05, 0.06, 0.57], ql.Actual365Fixed())

Entonces puedes pasar esta curva a tu ql.YieldTermStructureHandle al igual que usted, con su ql.FlatForward curva.

0 votos

Ok gracias, necesito usar una tasa futura no plana, así que creo que voy a usar el segundo método con ql.YieldTermStructureHandle. (Usé una entrada aleatoria sólo para probar si podía pasar un array a la función, pero me dio un error así que no he probado con la curva de tipos futuros reales)

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