0
$\begingroup$

I have tried to price a fixed rate bond using Python QuantLib and I verified my answer using a DCF model.

Below are my codes for the pricing of the fixed rate bond using Python QuantLib:

import QuantLib as ql

valuationDate = ql.Date(30, 6, 2020)
ql.Settings.instance().evaluationDate = valuationDate
compounding = ql.Compounded
calendar = ql.UnitedStates()
coupon = 0.05
couponFrequency = ql.Annual
issueDate = ql.Date(1, 1, 2016)
maturityDate = ql.Date(1, 1, 2024)
settlementDays = 2
settlementDate = calendar.advance(issueDate, ql.Period(settlementDays, ql.Days))
dayCount = ql.ActualActual(ql.ActualActual.ISMA)
schedule = ql.Schedule(issueDate, maturityDate, ql.Period(couponFrequency), calendar, ql.Unadjusted, ql.Unadjusted, ql.DateGeneration.Forward, True)
fixedRateBond = ql.FixedRateBond(settlementDays, 100, schedule, [coupon], ql.ActualActual(ql.ActualActual.ISMA))
curve = ql.ZeroCurve([ql.Date(1, 1, 2020), ql.Date(1, 1, 2027)], [0.01, 0.02], dayCount, calendar, ql.Linear(), compounding, couponFrequency)
handle = ql.YieldTermStructureHandle(curve)
bondEngine = ql.DiscountingBondEngine(handle)
fixedRateBond.setPricingEngine(bondEngine)
print('QuantLib NPV:', fixedRateBond.NPV())

The resulting NPV using QuantLib is:

QuantLib NPV: 118.26526771080188

Below are my codes for the pricing of the fixed rate bond using the DCF model:

DCFs = []

for i, cf in enumerate(fixedRateBond.cashflows()):
    if cf.date() >= valuationDate:
        discount_factor = curve.zeroRate(cf.date(), dayCount, compounding, couponFrequency).discountFactor(valuationDate, cf.date())
        DCFs.append(discount_factor * cf.amount())
        
print('DCF Model NPV:', sum(DCFs))

The resulting NPV using the DCF model is:

DCF Model NPV: 114.13038560873856

Can someone please explain how this difference is arising? Many thanks.

$\endgroup$

1 Answer 1

2
$\begingroup$

Starting the zero curve from a date 6 months in the past with respect to the valuation date throws the bond off. If you start the curve at valuationDate instead, you'll get the same results.

You'll also be able to write your DCF loop more concisely, as:

DCFs = []

for i, cf in enumerate(fixedRateBond.cashflows()):
    if cf.date() >= valuationDate:
        discount_factor = curve.discount(cf.date())
        DCFs.append(discount_factor * cf.amount())
    
print('DCF Model NPV:', sum(DCFs))
$\endgroup$
1
  • $\begingroup$ Thank you Luigi!! $\endgroup$ Commented Aug 14, 2021 at 5:25

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.