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.