5 votos

Quantlib-Python: usar tasas cero para obtener la curva original de bootstrap

Digamos que estoy tratando de construir una curva usando depósitos, futuros e intercambios con uno de los tres métodos de Quantlib en Python como se muestra a continuación:

crv = ql.PiecewiseLogCubicDiscount(2, ql.TARGET(), deposits + futures + swaps, ql.Actual365Fixed())

o

crv = ql.PiecewiseLinearZero(2, ql.TARGET(), deposits + futures + swaps, ql.Actual365Fixed())

o

crv = ql.PiecewiseFlatForward(2, ql.TARGET(), deposits + futures + swaps, ql.Actual365Fixed())

y que luego obtengo las tasas de cero en un conjunto de tenores clave como a continuación:

spotDate = crv.referenceDate()
dates = [ql.TARGET().advance(spotDate, t, ql.Days) for t in keytenors ]
rates = [ crv.zeroRate(t, ql.Continuous).rate() for t in keytenors ]

Si paso estas tasas cero para obtener el objeto crv original en los tres casos anteriores, ¿cómo puedo hacerlo? Lo intenté con:

zero_curve = ql.ZeroCurve(dates, rates,  ql.Actual365Fixed())

pero la curva que obtengo no es la misma que la que me he tragado. En general, la curva cero que obtengo es mucho menos suave y parece interpolarse linealmente de alguna manera. ¿Cómo puedo obtener el PiecewiseLogCubicDiscount, PiecewiseLinearZero y PiecewiseFlatForward en su lugar?

7voto

Brad Tutterow Puntos 5628

Para recuperar la curva original, es necesario utilizar los mismos tenores de clave de la curva original y con la misma interpolación. Por ejemplo, cuando se crea la curva original como:

crv = ql.PiecewiseLinearZero(2, ql.TARGET(), deposits + futures + swaps, ql.Actual365Fixed())

la curva interpola linealmente los tipos cero entre los nodos dados por los vencimientos de los depósitos, futuros y swaps pasados. Puede recuperar el conjunto de fechas subyacentes y los tipos correspondientes llamando a crv.nodes() que devuelve una secuencia de pares (fecha, tasa); por ejemplo, si lo llamo en una curva definida como en este ejemplo me sale:

((Date(8,11,2001), 0.038716178576382605),
 (Date(15,11,2001), 0.038716178576382605),
 (Date(10,12,2001), 0.037654445569665344),
 (Date(8,2,2002), 0.03663450512870074),
 (Date(8,5,2002), 0.03704480712236303),
 (Date(8,8,2002), 0.037185800177110054),
 (Date(8,11,2002), 0.03725571728097072),
 (Date(10,11,2003), 0.03633800161641973),
 (Date(8,11,2004), 0.039086101826569714),
 (Date(8,11,2006), 0.04547303923680055),
 (Date(8,11,2011), 0.051542294488560084),
 (Date(8,11,2016), 0.055797299887186284))

(La fecha de evaluación utilizada en el ejemplo es el 6 de noviembre de 2001).

Dado que la curva es una PiecewiseLinearZero los tipos devueltos arriba son tipos cero; y si los utiliza para crear una instancia de ZeroCurve (que también interpola linealmente)...

dates, rates = zip(*crv.nodes())
crv2 = ql.ZeroCurve(dates, rates, ql.Actual365Fixed())

...obtendrá la misma curva que el original:

spot = crv.referenceDate()
sample_dates = [ spot + ql.Period(i, ql.Weeks) for i in range(15*52) ]
z1 = [ crv.zeroRate(d, ql.Actual365Fixed(), ql.Continuous).rate() for d in sample_dates ]
z2 = [ crv2.zeroRate(d, ql.Actual365Fixed(), ql.Continuous).rate() for d in sample_dates ]

fig = plt.figure(figsize=(12,6))
ax = fig.add_subplot(1,1,1)
ax.plot_date([d.to_date() for d in sample_dates], z1, '.')
ax.plot_date([d.to_date() for d in sample_dates], z2, '-')

identical curves

El problema es que, si muestreas los índices cero en diferentes nodos, obtendrás puntos en la curva; pero interpolando entre ellos, obtendrás valores diferentes.

sample_nodes = [ spot + ql.Period(3*i, ql.Years) for i in range(6) ]
sample_rates = [ crv.zeroRate(d, ql.Actual365Fixed(), ql.Continuous).rate() for d in sample_nodes ]
crv3 = ql.ZeroCurve(sample_nodes, sample_rates, ql.Actual365Fixed())

z3 = [ crv3.zeroRate(d, ql.Actual365Fixed(), ql.Continuous).rate() for d in sample_dates ]

fig = plt.figure(figsize=(12,6))
ax = fig.add_subplot(1,1,1)
ax.plot_date([d.to_date() for d in sample_dates], z1, '.')
p, = ax.plot_date([d.to_date() for d in sample_dates], z3, '-')
ax.plot_date([d.to_date() for d in sample_nodes], sample_rates, 'o', markersize=8, color=p.get_color())

curves with different nodes

En resumen: hay que utilizar los mismos nodos e interpolación. Puede recuperar los primeros de la curva original como curve.nodes() y tendrá que elegir una clase que proporcione esto último. Para PiecewiseLinearZero Tendrá que utilizar ZeroCurve para PiecewiseFlatForward El nodes devolverá pares de fechas y tipos de cambio a plazo instantáneos, que puede utilizar para crear una instancia de ForwardCurve .

Para PiecewiseLogCubicDiscount El nodes devolverá pares de fechas y factores de descuento, y tendrá que pasarlos a una curva de descuento interpolada correspondiente; sin embargo, la que actualmente se exporta a Python ( DiscountCurve ) utiliza la interpolación log-lineal, y no la log-cubica. Si quiere utilizar esta última, tendrá que modificar QuantLib-SWIG/SWIG/discountcurve.i para que también exporte la curva deseada y recompilar las envolturas. Lo mismo ocurre si se quiere utilizar una interpolación diferente para las tasas cero o hacia adelante; los archivos correspondientes a editar son zerocurve.i y forwardcurve.i .

0 votos

Gracias Luigi. Pero tengo varios días en los que quiero comparar la curva, por ejemplo, porque quiero calcular el riesgo del cubo en exactamente los mismos tenores clave. Así que para cada fecha de evaluación exporto las tasas cero continuamente compuestas (como en el array de tasas de mi ejemplo). Entonces otro proceso utilizará los tipos cero exportados para reconstruir la curva en cada día y calcular el riesgo de tipo clave para un swap. Por eso necesito de alguna manera un conjunto único de puntos de tenor clave con los que trabajar. ¿Cómo puedo hacerlo?

0 votos

Puede perturbar los tenores clave independientemente de los nodos de la curva subyacente. Ver < youtube.com/watch?v=v4vQNcmYegA >, o el cuaderno correspondiente en el QuantLib Python Cookbook.

0 votos

Si necesita más información, puede contactar con la lista de correo de QuantLib. (Los sitios de StackExchange tienden a fruncir el ceño cuando los comentarios toman un giro propio y se desvían de la pregunta original...)

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