0
$\begingroup$

When we price a fixed rate bond using Quantlib, we generally take below approach -

import QuantLib as ql import pandas as pd todaysDate = ql.Date(31, 8, 2019) ql.Settings.instance().evaluationDate = todaysDate spotDates = [ql.Date(1,9,2019), ql.Date(5,9,2019), ql.Date(7,9,2019)] spotRates = [0.066682, 0.067199, 0.067502] dayCount = ql.Actual365Fixed() calendar = ql.SouthAfrica() interpolation = ql.Linear() compounding = ql.Compounded compoundingFrequency = ql.Semiannual spotCurve = ql.ZeroCurve(spotDates, spotRates, dayCount, calendar, interpolation, compounding, compoundingFrequency) spotCurveHandle = ql.YieldTermStructureHandle(spotCurve) issueDate = ql.Date(20, 4, 2017) maturityDate = ql.Date(20, 4, 2019) tenor = ql.Period(ql.Semiannual) calendar = ql.SouthAfrica() bussinessConvention = ql.Following dateGeneration = ql.DateGeneration.Backward monthEnd = False schedule = ql.Schedule(issueDate, maturityDate, tenor, calendar, bussinessConvention, bussinessConvention, dateGeneration, monthEnd) dayCount = ql.Actual365Fixed() couponRate = 0.0925 coupons = [couponRate] settlementDays = 3 faceValue = 100 fixedRateBond = ql.FixedRateBond(settlementDays, faceValue, schedule, coupons, dayCount) bondEngine = ql.DiscountingBondEngine(spotCurveHandle) fixedRateBond.setPricingEngine(bondEngine) fixedRateBond.NPV() 

However my question is - instead of a typical bond if I need to price the Annuity (i.e. there is no Principal payment at the maturity), how can I modify above codebase?

Any pointer will be highly appreciated.

$\endgroup$

1 Answer 1

1
$\begingroup$

The bond engine uses the CashFlows::npv() method internally, so you can do the same after stripping the principal payment from the bond cashflows:

cashflows = fixedRateBond.cashflows() coupons = cashflows[:-1] # all except the last includeSettlementDateFlows = False annuity = CashFlows.npv( coupons, spotCurveHandle, False, spotCurveHandle.referenceDate() ) 

This will be consistent to fixedRateBond.NPV() (and you can verify it by not stripping the last coupon, i.e., setting coupons = cashflows: you'll get the same result).

However, note that this (and fixedRateBond.NPV()) discounts to the reference date of the spot curve, i.e., to the first of the spotDates. If you want to discount to the settlement date of the bond, you should use instead

annuity = CashFlows.npv( coupons, spotCurveHandle, False, bond.settlementDate() ) 

and you should also use fixedRateBond.dirtyPrice() instead of fixedRateBond.NPV().

$\endgroup$
5
  • 2
    $\begingroup$ To add to Luigi's answer, you could also use the FixedRateLeg class and get just the coupons: ql.FixedRateLeg(schedule, dayCount, [faceValue], [couponRate] ) $\endgroup$ Commented Aug 14, 2020 at 13:02
  • 1
    $\begingroup$ Thanks. What is the purpose of "includeSettlementDateFlows = False" $\endgroup$ Commented Aug 14, 2020 at 16:48
  • $\begingroup$ Additionally, I am getting error "Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'tuple' object has no attribute 'npv'" $\endgroup$ Commented Aug 14, 2020 at 17:06
  • $\begingroup$ About the error, careful not to confuse CashFlows (the class) with cashflows (the variable) in the above. Capitalization matters. $\endgroup$ Commented Aug 14, 2020 at 17:20
  • $\begingroup$ With includeSettlementDateFlows set to False (the default), if a coupon pays today it's not included in the NPV. If set to True, the coupon is included. $\endgroup$ Commented Aug 14, 2020 at 17:22

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.