3 votos

Calibración de Theta, A(t) y B(t) del modelo Hull White de 1 factor

Estoy simulando tasas de interés a través del modelo de un factor de Hull-White. Para simular la tasa corta estoy utilizando el código del 'Quantlib Python Cookbook', capítulo 15 y más allá (por Goutham Balaraman y Luigi Ballabio). El código se puede encontrar aquí:

El código genera la tasa corta. Desafortunadamente, el código termina solo con la tasa corta simulada, mientras que mi objetivo es crear una nueva estructura a término basada en la curva simulada.

Para crear una estructura a término, necesito calibrar theta basado en la estructura inicial a término. Además de eso, también necesito calcular A(t) y B(t) de manera que pueda crear la estructura a término.

Preguntas: ¿Alguien tiene un algoritmo para calcular theta, A(t) y B(t)?

3voto

Chris Mc Puntos 31

Puedes consultar aquí una publicación en el blog sobre cómo simular la estructura temporal de rendimientos para el modelo HullWhite.

La idea básica es que una vez que se tienen las trayectorias para la tasa de interés a corto plazo, simplemente se integra (aproximadamente) la tasa de interés a corto plazo a lo largo de cada trayectoria para obtener los factores de descuento.

El promedio de las simulaciones debería coincidir con la estructura temporal inicial.

Aquí hay un ejemplo basado en esa excelente publicación del blog, con una mejora en el tiempo de ejecución mediante la vectorización de la integración.

import QuantLib as ql
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import copy 

nPaths = 500
years = 30

startDate = ql.Date(3, 12, 2018)
endDate = startDate + ql.Period(years, ql.Years)
tenor = ql.Period(1, ql.Days)
schedule = ql.MakeSchedule(startDate, endDate, tenor)

dates = [dt for dt in schedule]

times = [ql.Actual360().yearFraction(startDate, dt) for dt in dates]

curve = ql.YieldTermStructureHandle(ql.FlatForward(startDate, 0.04875825, ql.Actual365Fixed()))
reversionSpeed = 0.01
rateVolatility = 0.001
process = ql.HullWhiteProcess(curve, reversionSpeed, rateVolatility)

periods = (endDate - startDate) + 1
sequenceGenerator = ql.UniformRandomSequenceGenerator(periods, ql.UniformRandomGenerator())
gaussianSequenceGenerator = ql.GaussianRandomSequenceGenerator(sequenceGenerator)
pathGenerator = ql.GaussianPathGenerator(process, years, periods, gaussianSequenceGenerator, False)

paths = np.zeros(shape = (nPaths, periods))
for i in range(nPaths):
    path = pathGenerator.next().value()
    paths[i, :] = np.array([path[j] for j in range(periods)])

dfs = np.zeros(shape=paths.shape)
dt = years / len(schedule)
integral = 0
for j in range(periods):
    if j == 0:
        dfs[:, 0] = 1
        integral = copy.deepcopy(paths[:, 0])
    else:
        integral += paths[:, j]        
        dfs[:, j] += np.exp(-integral * dt)

simulatedCurve = ql.DiscountCurve(dates, dfs.mean(0), ql.Actual365Fixed(), ql.NullCalendar())
simulatedDfs = np.array([simulatedCurve.discount(dt) for dt in dates])
dfs_curve = np.array([curve.discount(dt) for dt in dates])

fig, ax = plt.subplots(1,2, figsize=(10,3))
plt.tight_layout()

ax[0].set_title('Factores de Descuento')
ax[0].plot(times, simulatedDfs, linestyle = 'dashed', label = 'curva simulada')
ax[0].plot(times, dfs_curve, linestyle = 'solid', label = 'curva original')
ax[0].legend()

ax[1].set_title('Trayectorias')
ax[1].plot(paths.T, linewidth=0.5)

La salida sería:

ingresa la descripción de la imagen aquí

0 votos

¿Puedes explicar qué representa el 0.04875825 y cómo se determina?

0 votos

Es una tasa plana fija. No está determinada y es simplemente un valor fijo en este caso. Alternativamente, podría iniciar una curva completa a partir de instrumentos de mercado

0 votos

Gracias por el ejemplo, muy útil. ¿Cómo puedo construir una curva de descuento (o curva cero) para cada camino en la simulación para los años 1, 2, .., 30?

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