1 votos

Preguntas sobre la cuestión del recuento de días en la fijación del precio de los bonos

No entendí cómo es que QuantLib gestionar la cuestión del recuento de días a la hora de determinar el pago real del Cupón. A continuación se muestra mi bono de tipo fijo -

import QuantLib as ql
import pandas as pd

todaysDate = ql.Date(1, 9, 2019)
ql.Settings.instance().evaluationDate = todaysDate

spotDates = [todaysDate, todaysDate + ql.Period("1y"), todaysDate + ql.Period("2y"), todaysDate + ql.Period("3y")]
spotRates = [0, 0.066682, 0.067199, 0.067502]

dayCount = ql.ActualActual()
calendar = ql.Canada()
interpolation = ql.Linear()
compounding = ql.Compounded
compoundingFrequency = ql.Continuous

spotCurve = ql.ZeroCurve(spotDates, spotRates, dayCount, calendar, interpolation, compounding, compoundingFrequency)
spotCurveHandle = ql.YieldTermStructureHandle(spotCurve)

issueDate = todaysDate
maturityDate = todaysDate + ql.Period("2y")
tenor = ql.Period(ql.Annual)
bussinessConvention = ql.Following
dateGeneration = ql.DateGeneration.Backward
monthEnd = False

schedule = ql.Schedule(issueDate, maturityDate, tenor, calendar, bussinessConvention, bussinessConvention, dateGeneration, monthEnd)

couponRate = 0.09
coupons = [couponRate]

settlementDays = 3
faceValue = 100
fixedRateBond = ql.FixedRateBond(settlementDays, faceValue, schedule, coupons, dayCount)

bondEngine = ql.DiscountingBondEngine(spotCurveHandle)
fixedRateBond.setPricingEngine(bondEngine)

fixedRateBond.NPV()

Ahora, quiero ver los CF reales que QuantLib está considerando

for cf in fixedRateBond.cashflows():
    print(cf.date().ISO(), cf.amount())

Esto da -

2020-09-01 8.958904109589039
2021-09-01 8.991780821917805
2021-09-01 100.0

Pero mi pregunta es cómo se calculan los 2 primeros números. Con Actual-Actual convención, el primer número no debería ser :

>>> 9 * dayCount.yearFraction(issueDate + ql.Period("1d"),issueDate + ql.Period("1y"))
8.983561643835616

Y para el segundo pago de intereses

>>> 9 * dayCount.yearFraction(issueDate + ql.Period("1y") + ql.Period("1d"),issueDate + ql.Period("2y"))
8.967190657983382

¿Pueden ayudarme a entender el cálculo? ¿Qué se me escapa?

1voto

Chris Mc Puntos 31

La fecha que está utilizando como issueDate (01-09-2019) es un domingo, y como está utilizando el calendario canadiense, el 2 de septiembre es festivo (Día del Trabajo) por lo que la primera fecha sería en realidad el 03-09-2019.

Compruebe las fechas del calendario:

for dt in schedule:
    print(dt)

3 de septiembre de 2019
1 de septiembre de 2020
1 de septiembre de 2021

Tenga en cuenta que cuando se construye el programa, algunas fechas pueden ajustarse con el calendario y las convenciones, por lo que si desea comprobar cómo se determina el primer cupón, debe utilizar realmente:

dayCount.yearFraction(schedule[0], schedule[1]) * couponRate * 100

que te da:

8.95890410958904

Además, tenga en cuenta que Date + Period no es una buena idea porque añadirá "ciegamente" un punto a una fecha y el resultado podría no ser un día laborable. Utilizando calendar.advance(Date, Period) sería mejor

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