QuantLib Bond Yields Require Decimal Coupon Rates
Summary
The discussion diagnoses a municipal bond yield calculation that differs substantially from a listed yield. The bond schedule and day-count setup are shown, but the key issue is the coupon input convention: QuantLib expects rates in decimal form rather than percentage points. Entering 5.0 therefore represents a 500% coupon, not a 5% coupon.
Changing the coupon input to 0.05 produces a yield close to the comparison figure. The example shows how a unit mismatch can distort bond pricing outputs even when the calculation structure appears reasonable. It focuses on the coupon-rate scale; it does not establish that the other bond conventions or market data are appropriate for every municipal bond, so those still need to be checked in a real valuation.
Key ideas
- QuantLib represents coupon rates as decimals rather than percentage-point values.
- A coupon input of 5.0 is interpreted as a 500% rate.
- Using 0.05 for a 5% coupon brings the calculated yield close to the cited comparison.
- Check rate units before investigating more complex bond-model differences.
Tags
Full text
# Price and Yield Calculations for Municipal Bonds with QuantLib
# Price and Yield Calculations for Municipal Bonds with QuantLib
I'm currently trying to calculate yield to maturity for a given municipal bond using quantlib for maven, and am comparing the result to the calculated yield listed on EMMA. However, I keep ending up with a substantially-different yield than expected (in this case, I got `3.639%`, as opposed to `2.895%`).
I've extracted the code from my microservice and have defined each of the variables directly as to maximize comprehension:
```
Double price = 106.365;
Schedule schedule = new MakeSchedule()
.from(new Date(
15,
Month.swigToEnum(01),
2022
)) // 2022-01-15 -> quantlib date
.to(new Date(
15,
Month.swigToEnum(07),
2028
)) // 2028-07-15 -> quantlib date
.withFrequency(Frequency.Semiannual)
// TODO: sifma calendar?
.withCalendar(new UnitedStates(UnitedStates.Market.GovernmentBond))
.withConvention(BusinessDayConvention.Following)
.schedule(); // build final schedule
DoubleVector fixedRateCoupons = new DoubleVector();
fixedRateCoupons.add(5.0);
Bond givenBond = new FixedRateBond(
1,
100.0,
schedule,
fixedRateCoupons,
new Thirty360(Thirty360.Convention.USA)
);
public Double getYield(Double price, Date evaluationDate) {
return BondFunctions.yield(
givenBond,
price,
new Thirty360(Thirty360.Convention.USA),
Compounding.Compounded,
Frequency.Semiannual,
new Date(
07,
Month.swigToEnum(05),
2025
) // 2025-05-07 -> quantlib date
);
}
public Double getYieldToMaturity(Double price) {
return getYield(price, Date.todaysDate());
}
```
I don't have a background in finance, so it's possible I'm misunderstanding something. Any help would be sincerely appreciated.
## Answer by Luigi Ballabio (score 3, accepted)
https://quant.stackexchange.com/a/82453
QuantLib specifies rates in decimal format, not as percentages. By writing `fixedRateCoupons.add(5.0);` you're not using a 5% coupon, but a 500% one, and you're getting back a 363% yield.
You need to use 0.05 for the coupon instead, which will give you a yield of 0.02898, or 2.898%.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.