0
$\begingroup$

I am trying the following example of calculating duration and convexity for a zero coupon bond. For the sake of an easy example, I set the Interest rate to be zero.

In the first attempt, I try using the object ZeroCouponBond(), shown in code below:

maturity_date = ql.Date(1,6,2025)
settlement_date = ql.Date(20,4,2013)
interest_rate_float = 0
coupon_rate = 0

start_date = settlement_date
schedule = ql.Schedule()

day_counter = ql.ActualActual(ql.ActualActual.Bond)
created_bond = ql.ZeroCouponBond(0, ql.NullCalendar(), float(100), maturity_date)
Interest_Rate = ql.InterestRate(interest_rate_float/100, day_counter, ql.Compounded, 2)

Convexity = ql.BondFunctions.convexity(created_bond, Interest_Rate, settlement_date)
print(Convexity/100)

mod_dur = ql.BondFunctions.duration(created_bond, Interest_Rate, ql.Duration.Modified, settlement_date)
print(mod_dur)

sim_dur = ql.BondFunctions.duration(created_bond, Interest_Rate, ql.Duration.Simple, settlement_date)
print(sim_dur)

This gives me the following values:

convexity: 1.5283241884030772

modified duration: 12.115068493150684

simple duration: 12.115068493150684

I repeat this process with a FixedRateBond() with coupon rate set to zero, as shown below:

maturity_date = ql.Date(1,6,2025)
settlement_date = ql.Date(20,4,2013)
interest_rate_float = 0
coupon_rate = 0

start_date = settlement_date
schedule = ql.Schedule(start_date, maturity_date, ql.Period(ql.Semiannual), ql.NullCalendar(), ql.Unadjusted, ql.Unadjusted, ql.DateGeneration.Backward, True)

day_counter = ql.ActualActual(ql.ActualActual.Bond)
created_bond = ql.FixedRateBond(0, float(100), schedule, [float(coupon_rate/100)], day_counter)
Interest_Rate = ql.InterestRate(interest_rate_float/100, day_counter, ql.Compounded, 2)

Convexity = ql.BondFunctions.convexity(created_bond, Interest_Rate, settlement_date)
print(Convexity/100)

mod_dur = ql.BondFunctions.duration(created_bond, Interest_Rate, ql.Duration.Modified, settlement_date)
print(mod_dur)

sim_dur = ql.BondFunctions.duration(created_bond, Interest_Rate, ql.Duration.Simple, settlement_date)
print(sim_dur)

This time, I get the following results:

convexity: 1.528402366863905

modified duration: 12.115384615384615

simple duration: 12.115384615384615

Why is there a difference in the two ways? Am I doing something wrong?

P.S: I checked the results against bloomberg and the values match with those that I get when I use Method 2 (i.e. FixedRateBond())

$\endgroup$

1 Answer 1

1
$\begingroup$

My guess is that Quantlib is mixing the stated compounding frequencies.

If I run this,

# PYTHON v3.12
from rateslib import *  # v 1.4.0

frb = FixedRateBond(
    effective=dt(2013, 4, 20),
    termination=dt(2025, 6, 1),
    fixed_rate=0.0,
    convention="ActActBond",
    frequency="S",
    modifier="none",
)
frb.convexity(ytm=0, settlement=dt(2013, 4, 20))
# 1.528402366863905
frb.duration(ytm=0, settlement=dt(2013, 4, 20), metric="modified")
# 12.115384615384615
frb.duration(ytm=0, settlement=dt(2013, 4, 20), metric="duration")
# 12.115384615384615

whilst,


frb = FixedRateBond(
    effective=dt(2013, 4, 20),
    termination=dt(2025, 6, 1),
    fixed_rate=0.0,
    convention="ActActBond",
    frequency="A",    # <- NOTE THIS CHANGE
    modifier="none",
)
frb.convexity(ytm=0, settlement=dt(2013, 4, 20))
# 1.588899530868831
frb.duration(ytm=0, settlement=dt(2013, 4, 20), metric="modified")
# 12.115068493150686
frb.duration(ytm=0, settlement=dt(2013, 4, 20), metric="duration")
# 12.115068493150686

You can match these figures against your output and note that in Quantlib the convexity doesn't change from one to the another so that leads to my guess.

$\endgroup$
2
  • $\begingroup$ In QuantLib, the convexity does change, although by a smaller amount. I get your point. I test it out by changing the day count convention to Actual365Fixed() in both the methods and get the same durations and convexities $\endgroup$
    – TheRealMKS
    Commented Jul 10 at 13:46
  • $\begingroup$ On further thought, I wonder why changing the compounding frequency is changing the duration of zero coupon bond at all. The duration of a zero coupon bond is simply the time to maturity, so this should be independent of compounding frequency $\endgroup$
    – TheRealMKS
    Commented Jul 10 at 14:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.