Configuración inicial
import QuantLib as ql
import numpy as np
import pandas as pd
# Configuración del calendario y fecha de valoración
calendario = ql.Germany(ql.Germany.Eurex)
fecha_valor = calendario.adjust(ql.Date(30, 1, 2008))
ql.Settings.instance().evaluationDate = fecha_valor
Carga de datos de bonos
datos_bonos = pd.read_csv('DATOS_BONOS.csv',
parse_dates=['FECHA_VENCIMIENTO', 'FECHA_EMISION'])
precios = [ql.QuoteHandle(ql.SimpleQuote(p)) for p in datos_bonos['PRECIO']]
vencimientos = [ql.Date(d.day, d.month, d.year) for d in datos_bonos['FECHA_VENCIMIENTO']]
tasas_cupon = datos_bonos['TASA_CUPON'].values
Configuración de instrumentos
instrumentos = []
for i in range(len(datos_bonos)):
calendario_pagos = ql.Schedule(
vencimientos[i] - ql.Period(10, ql.Years), # Fecha aproximada de emisión
vencimientos[i],
ql.Period(ql.Annual),
calendario,
ql.Unadjusted,
ql.Unadjusted,
ql.DateGeneration.Backward,
False)
helper = ql.FixedRateBondHelper(
precios[i],
0, # Días de liquidación
100, # Valor nominal
calendario_pagos,
[tasas_cupon[i]],
ql.Actual365Fixed(),
ql.Unadjusted)
instrumentos.append(helper)
Modelos de curva de rendimiento
# Configuración de diferentes modelos
modelos = {
'Nelson-Siegel': ql.NelsonSiegelFitting(),
'Svensson': ql.SvenssonFitting(),
'Splines Cúbicos': ql.CubicBSplinesFitting([0, 5, 10, 20, 30])
}
curvas = {}
for nombre, modelo in modelos.items():
curvas[nombre] = ql.FittedBondDiscountCurve(
fecha_valor,
instrumentos,
ql.Actual365Fixed(),
modelo,
1e-6, # Tolerancia
5000) # Iteraciones máximas
Visualización de resultados
import matplotlib.pyplot as plt
plazos = np.linspace(0.1, 30, 100)
for nombre, curva in curvas.items():
tasas = [curva.zeroRate(t, ql.Actual365Fixed(), ql.Continuous).rate()*100
for t in plazos]
plt.plot(plazos, tasas, label=nombre)
plt.legend()
plt.xlabel('Plazo (años)')
plt.ylabel('Tasa (%)')
plt.title('Comparación de modelos de curva de rendimiento')
plt.show()
Consideraciones importantes
- La calidad de los resultados depende críticamente de la selección de parámetros iniciales
- Los modelos Nelson-Siegel y Svensson pueden requerri restricciones adicionales
- La implementación actual utiliza el algoritmo simplex, que puede no ser óptimo para problemas no convexos