2 votos

Python Quantlib para la calibración de capas de tasas de interés

Estoy tratando de calibrar el modelo G2++ a los cap de tasas de interés utilizando la biblioteca Quantlib en Python. Tengo el problema de que mi optimización siempre se detiene con los valores iniciales. Así que probablemente mi configuración para los ayudantes de cap o la optimización en sí está mal. Desafortunadamente, no puedo avanzar aquí y estaría encantado de tener algo de ayuda.

Espero que alguien tenga experiencia con Quantlib y pueda ayudar. Adjunto está mi código con algunos datos de muestra.

¡Muchas gracias!

import QuantLib as ql

# Configuraciones iniciales
fecha_valoracion = ql.Date(29, 1, 2024)
ql.Settings.instance().evaluationDate = fecha_valoracion

# Configuración de la curva de rendimiento
vencimientos_swap = [ql.Period(6, ql.Months), ql.Period(1, ql.Years), ql.Period(2, ql.Years),
ql.Period(3, ql.Years), ql.Period(4, ql.Years), ql.Period(5, ql.Years),
ql.Period(6, ql.Years), ql.Period(7, ql.Years), ql.Period(8, ql.Years),
ql.Period(9, ql.Years), ql.Period(10, ql.Years), ql.Period(12, ql.Years),
ql.Period(15, ql.Years), ql.Period(20, ql.Years), ql.Period(25, ql.Years),
ql.Period(30, ql.Years)]
fechas = [fecha_valoracion + vencimiento for vencimiento in vencimientos_swap]

tasas = [0.03873, 0.03524, 0.02955, 0.02745, 0.02662, 0.02631, 0.02625, 0.02631,
0.02644, 0.02661, 0.02680, 0.02720, 0.02749, 0.02696, 0.02598, 0.02499]

dias = ql.Actual360()
calendario = ql.Germany()
interpolacion = ql.Linear()
capitalizacion = ql.Compounded
frecuencia_capitalizacion = ql.Semiannual

estructura_plazos = ql.ZeroCurve(fechas, tasas, dias, calendario,
interpolacion, capitalizacion, frecuencia_capitalizacion)
ts_manejador = ql.YieldTermStructureHandle(estructura_plazos)

# Cap Vols
vols_mercado = {
1: 0.9081,
2: 1.0488,
3: 1.0533,
4: 1.0391,
5: 1.0232,
6: 1.008,
7: 0.9926,
8: 0.978,
9: 0.9633,
10: 0.9498,
12: 0.9246,
15: 0.8901,
20: 0.8439,
25: 0.8091,
}

# Configuración del Modelo
modelo = ql.G2(ts_manejador)

# Crear Objetos Cap
ayudantes_cap = []
fecha_inicio = fecha_valoracion + ql.Period(6,ql.Months)

for vencimiento, volatilidad in vols_mercado.items():
periodo = ql.Period(vencimiento, ql.Years)
fecha_fin = calendario.advance(fecha_valoracion, periodo)
cronograma = ql.Schedule(fecha_inicio, fecha_fin, ql.Period(ql.Annual), calendario,
ql.Unadjusted, ql.Unadjusted, ql.DateGeneration.Forward, False)

# Cálculo de la Tasa de Strike
tasa_fwd = estructura_plazos.forwardRate(fecha_inicio, fecha_fin, dias, capitalizacion, frecuencia_capitalizacion).rate()
cita_strike = ql.SimpleQuote(tasa_fwd)

# Cita de Volatilidad
vol_cita = ql.QuoteHandle(ql.SimpleQuote(volatilidad))

# Configuración del Ayudante de Cap
ayudante = ql.CapHelper(periodo, vol_cita, cita_strike, ql.Annual, dias, False, ts_manejador)
ayudante.setPricingEngine(ql.BlackCapFloorEngine(ts_manejador, vol_cita))
ayudantes_cap.append(ayudante)

# Configuración del método de calibración
metodo_optimizacion = ql.LevenbergMarquardt(1e-8, 1e-8, 1e-8)

# Definición de criterios de finalización
criterios_fin = ql.EndCriteria(1000, 500, 1e-8, 1e-8, 1e-8)

# Calibración
modelo.calibrate(ayudantes_cap, metodo_optimizacion, criterios_fin)

# Resultados
a, sigma, b, eta, rho = modelo.params()
print(f"Parámetros del modelo G2++: a = {a}, sigma = {sigma}, b = {b}, eta = {eta}, rho = {rho}")
```

3voto

user35980 Puntos 1

Creo que deberías usar algo como TreeCapFloorEngine para la calibración de cap/floor con G2. BlackCapFloorEngine es para la fijación de precios Black en forma cerrada. Por ejemplo,

modelo=ql.G2(usd3mcurve)
metodo_optimizacion = ql.LevenbergMarquardt(1e-8, 1e-8, 1e-8)
criterio_fin = ql.EndCriteria(1000, 500, 1e-8, 1e-8, 1e-8)
periodos = [ql.Period('1y'),ql.Period('2y'),ql.Period('5y'),ql.Period('7y'),ql.Period('10Y'),ql.Period('15Y')]
comillas = [ql.QuoteHandle(ql.SimpleQuote(0.45)),ql.QuoteHandle(ql.SimpleQuote(0.55)),ql.QuoteHandle(ql.SimpleQuote(0.65)),
               ql.QuoteHandle(ql.SimpleQuote(0.55)),ql.QuoteHandle(ql.SimpleQuote(0.35)),ql.QuoteHandle(ql.SimpleQuote(0.25))]
yts = usd3mcurve
indice = ql.USDLibor(ql.Period('3m'),usd3mcurve)

ayudantes = [ql.CapHelper(i, j, indice, ql.Quarterly, ql.Actual360(), False, yts) for i,j in zip(periodos,comillas)]
for h in ayudantes:
    h.setPricingEngine(ql.TreeCapFloorEngine(modelo,20))

modelo.calibrate(ayudantes,metodo_optimizacion,criterio_fin)
print(modelo.params())

devuelve:

[ 0.0514912; 0.00746613; 0.0497814; 0.011121; -0.39568 ]

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