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
$\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$ Aug 14 at 5:25

Your Answer

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

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