Skip to content
All library documents

Bond Pricing: Simple Versus Compounded Yield Discounting in QuantLib

Article Quant Q&A · Author: supermastercode

Summary

The document diagnoses a small discrepancy between a fixed-rate bond price from QuantLib and prices obtained from a spreadsheet or another pricer. The example specifies a semiannual coupon bond, an evaluation date, a yield, and an Actual/Actual day-count convention. The reported QuantLib dirty price is slightly below the expected result when the yield is supplied with simple compounding.

The answer identifies the compounding convention as the source of the difference. Simple discounting uses a factor based on one plus yield times the period, while compounded discounting uses a power of one plus yield. Changing the QuantLib call to compounded semiannual yield discounting reproduces the stated comparison price. The example shows why yield frequency and compounding conventions must match across pricing tools; it does not address other sources of bond-price differences or generalize beyond the supplied conventions.

Key ideas

  • Bond prices depend on the yield compounding convention used to discount cash flows.
  • The example's simple compounding convention produces a price below the stated comparison price.
  • Using compounded semiannual discounting matches the stated price in this case.
  • Pricing comparisons require consistent day-count and yield-frequency conventions.

Tags

Full text
# Fixed rate bond pricing issue in Quantlib


# Fixed rate bond pricing issue in Quantlib












I cannot retrieve the same price for a fixed bond using quantlib.

```
faceValue = 100.
couponType = ql.Semiannual
issueDate = ql.Date(19, 4, 2019)
EvalDate = ql.Date(24, 5, 2019)
Maturity = ql.Date(19, 4, 2022)
quotedYield = 3.69
couponRate = 3.84
calendar = ql.NullCalendar()
settlementDays = 0
businessConventions = ql.Following
Datesgeneration = ql.DateGeneration.Forward
period= ql.Period(ql.Semiannual)
monthEnd = False

B1 = Bond(faceValue, couponType, EvalDate, issueDate, Maturity, quotedYield, couponRate, calendar)

ql.Settings.instance().evaluationDate = EvalDate

schedule = ql.Schedule(issueDate, Maturity, period, calendar, businessConventions, businessConventions, Datesgeneration, monthEnd)

bond = ql.FixedRateBond(settlementDays, faceValue, schedule, [couponRate/100.], ql.ActualActual(ql.ActualActual.ISMA))

print("QuantLib: ", bond.dirtyPrice(quotedYield/100., ql.ActualActual(ql.ActualActual.ISMA), ql.Simple, ql.Semiannual))
```

I should have got 100.774 when rounded to 3 decimals but i got 100.771. 100.774 is similar to Bloomberg pricer or excel using the classical discounted cashflow method to compute the price.

Can you help me?

Thanks Is there something wrong ?

## Answer by David Duarte (score 1)

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

Well, you are fetching the dirty price by discounting the cashflows with a simple rate instead of compounded rate which is not really the most common way. Not sure if this is what you want.

You are essentially using the discount factors as:

$$DF_i = \frac{1}{(1+r_i * n)}$$

instead of

$$DF_i = \frac{1}{(1+r_i)^n}$$

If you change the last line to:

```
print("QuantLib: ", bond.dirtyPrice(quotedYield/100., ql.ActualActual(ql.ActualActual.ISMA), ql.Compounded, ql.Semiannual))
```

The output price will be 100.774

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.