5 votos

Quantlib-Python: utilizar tasas cero para obtener la curva originalmente ajustada

Supongamos que estoy tratando de construir una curva utilizando depósitos, futuros e intercambios con uno de los tres métodos 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 luego obtengo las tasas cero en un conjunto de tenores clave de la siguiente manera:

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? Intenté con:

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

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

7voto

Brad Tutterow Puntos 5628

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

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

la curva interpola linealmente tasas de cero entre los nodos dados por las madureces de los depósitos, futuros e intercambios pasados. Puedes recuperar el conjunto de fechas subyacentes y las tasas correspondientes llamando a crv.nodes(), que devuelve una secuencia de pares de (fecha, tasa); por ejemplo, si lo llamo en una curva definida como en este ejemplo, obtengo:

((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 6 de noviembre de 2001).

Dado que la curva es una instancia de PiecewiseLinearZero, las tasas devueltas anteriormente son tasas de cero; y si las utilizas para crear una instancia de ZeroCurve (la cual también interpola linealmente)...

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

...obtendrás la misma curva que la 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, '-')

curvas idénticas

El problema es que, si muestreas las tasas de cero en nodos diferentes, obtendrás puntos en la curva; pero al interpolar 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())

curvas con nodos diferentes

En resumen: necesitas usar los mismos nodos e interpolación. Puedes obtener los primeros de la curva original como curve.nodes(), y tendrás que elegir una clase que proporcione la última. Para PiecewiseLinearZero, tendrás que usar ZeroCurve; para PiecewiseFlatForward, el método nodes devolverá pares de fechas y tasas instantáneas forward, las cuales puedes utilizar para crear una instancia de ForwardCurve.

Para PiecewiseLogCubicDiscount, el método nodes devolverá pares de fechas y factores de descuento, y tendrías que pasarlos a una curva de descuento interpolada correspondiente; sin embargo, la que actualmente se exporta a Python (DiscountCurve) utiliza interpolación log-lineal, y no log-cúbica. Si deseas utilizar esta última, tendrás que modificar QuantLib-SWIG/SWIG/discountcurve.i para que también exporte la curva deseada y compilar nuevamente los envoltorios. Lo mismo sucede si deseas utilizar una interpolación diferente para tasas de cero o forward; los archivos correspondientes a editar son zerocurve.i y forwardcurve.i.

0 votos

Gracias Luigi. Pero tengo varios días que quiero comparar la curva, por ejemplo porque quiero calcular el riesgo del bucket en exactamente los mismos tenores clave. Por lo tanto, para cada fecha de evaluación exporto las tasas de cero continuamente compuestas (como en la matriz de tasas en mi ejemplo). Luego, otro proceso usará las tasas de cero exportadas para reconstruir la curva en cada día y calcular el riesgo de tasa clave para un intercambio. Por eso de alguna manera necesito un conjunto único de puntos clave de tenor con los que trabajar. ¿Cómo puedo hacer eso?

0 votos

Puede perturbar los tenores clave de forma independiente 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 necesitas más discusión, puedes comunicarte en la lista de correo de QuantLib. (Los sitios de StackExchange tienden a desaprobar los comentarios que se desvían y se apartan 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