0
$\begingroup$

I've used Luigi Ballabio's workaround to calculate the duration/modified duration of a floating rate bond (which you can find here: https://www.youtube.com/watch?v=r_1wSd0hnN4). However, if I add a spread (Euribor6M + 172bps in this example) the calculation doesn't hold anymore. The duration calculation per se can be done as a difference between the calculation date and the time to the next reset date. But how can we take into account the spreads? I'm attaching a minimal working example (coupons are paid semi-annually):

import QuantLib as ql

face_amount = 100.0

todays_date = ql.Date(5,2,2020)
ql.Settings.instance().evaluationDate= todays_date

issue_date = ql.Date(27,3,2015)
maturity_date = ql.Date(27, 3, 2022)
settlement_days = 3
calendar = ql.TARGET()

fixing_days = 3
rate = 0

flat_forward = ql.FlatForward(settle_date,
                           rate,
                           Actual360(),
                           Compounded,
                           frequency_enum)

discounting_term_structure = ql.RelinkableYieldTermStructureHandle(flat_forward)
index_term_structure = ql.RelinkableYieldTermStructureHandle(flat_forward)

index = ql.Euribor(ql.Period(6, ql.Months), index_term_structure)
index.addFixing(ql.Date(24,9,2019), -0.403/100)

schedule = ql.Schedule(issue_date,
                    maturity_date, ql.Period(ql.Semiannual),
                    calendar,
                    ql.Unadjusted, ql.Unadjusted,
                    ql.DateGeneration.Backward, False)

floating_bond = ql.FloatingRateBond(settlement_days,
                                 face_amount,
                                 schedule,
                                 index,
                                 Actual360(),
                                 Unadjusted,
                                 fixing_days,
                                 spreads=[0.0172])

floating_bond.setPricingEngine(ql.DiscountingBondEngine(discounting_term_structure))

print(floating_bond.NPV(), floating_bond.cleanPrice(), floating_bond.dirtyPrice())

next_cashflow_date = [c.date() for c in floating_bond.cashflows() if c.date()>todays_date][0]

duration = (next_cashflow_date - todays_date)/360
print(duration)

Which yields:

104.15359444444445 103.6560611111111 104.15359444444444
0.14166666666666666

Then, I calculate the duration using QuantLib generic function:

ytm = floating_bond.bondYield(ql.Actual360(),ql.Compounded,ql.Annual)
ytm_handler = ql.InterestRate(ytm, ql.Actual360(),ql.Compounded,ql.Annual)

ql.BondFunctions.duration(floating_bond,ytm_handler,ql.Duration.Simple)

Results in:

2.1171292975546914

Can this last figure be interpreted as Spread Duration?

Thank you very much in advance!

| improve this question | | | | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.