Skip to content
All library documents

Choosing Compounding for a Flat Forward Curve in QuantLib

Article Quant Q&A · Author: Roshan Yadav

Summary

The document explains why a floating-rate bond’s forecast coupons decline when its QuantLib curve is constructed with simple compounding. The proposed fix is to build the FlatForward curve with compounded or continuous compounding so the quoted rate is represented consistently across forecast periods.

The question provides a code example and shows falling coupon rates under the simple convention; the answer reports near-constant rates after changing the convention. This is a narrow implementation example, not a general comparison of curve-building methods. The small variations in its reported output also mean the example should not be read as demonstrating perfectly identical coupon rates in every period.

Key ideas

  • A flat curve’s coupon forecasts can vary when the curve uses simple compounding.
  • Using compounded or continuous conventions is the proposed way to keep the forecast rate approximately constant.
  • The example demonstrates the effect on floating-rate bond coupons in QuantLib.
  • The reported rates are close but not exactly identical.

Tags

Full text
# falling flatforward curve in quantlib


# falling flatforward curve in quantlib












I am trying to create a floating rate bond where I need to create a flatforward curve, but the curve seems falling over the time, or is there any way to keep the rate constant.

```
ql.Settings.instance().evaluationDate = today
issueDate = ql.Date(11,10,2019)
maturityDate = ql.Date(11, 10, 2021)
tenor = ql.Period(ql.Quarterly)
dayCount = ql.Actual365Fixed()
bussinessConvention = ql.Unadjusted
dateGeneration = ql.DateGeneration.Forward
monthEnd = False
calendar = ql.NullCalendar()
faceValue = 100000
schedule = ql.Schedule(issueDate, maturityDate,tenor, calendar, ql.Unadjusted, ql.Unadjusted, dateGeneration,False)

forcast_curve = ql.RelinkableYieldTermStructureHandle()
curve = ql.FlatForward(0,calendar,0.04, ql.Actual365Fixed(),ql.Simple)
#curve = ql.FlatForward(today,ql.QuoteHandle(ql.SimpleQuote(0.04)),dayCount,ql.Simple,ql.Monthly)
forcast_curve.linkTo(curve)
index = ql.IborIndex("myindex",tenor, 0, ql.INRCurrency(),  calendar, ql.Unadjusted,  False, dayCount, forcast_curve)

nominals = faceValue
cashflows = ql.IborLeg(nominals=[nominals], schedule=schedule, index=index,paymentDayCounter=dayCount, paymentConvention =ql.ModifiedFollowing,fixingDays=[], gearings=[],spreads=[],caps=[])
bond = ql.Bond(0, calendar, 100.0,maturityDate, issueDate, cashflows)
yldcurve= ql.RelinkableYieldTermStructureHandle()
bondEngine = ql.DiscountingBondEngine(yldcurve)
bond.setPricingEngine(bondEngine)
print([ql.as_coupon(c).rate() for c in bond.cashflows()])
```

output : [0.039999999999999584, 0.03960073776717019, 0.03921357971637247, 0.03883391850196816, 0.03845748603940633, 0.03808828133152389, 0.03773389848030649, 0.03738222040147477]

## Answer by lampishthing (score 1)

https://quant.stackexchange.com/a/70601

Set the interest rate in the FlatForward construction to be ql.Compounded or ql.Continuous.

```
curve = ql.FlatForward(0,calendar,0.04, ql.Actual365Fixed(),ql.Compounded)
```

returns: [0.03941521701609075, 0.03941309594147902, 0.03941309594147813, 0.03941521701609075, 0.03941521701609075, 0.0394109750189309, 0.03941309594147813, 0.03941521701609163]

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.