Skip to content
All library documents

Matching QuantLib and Bloomberg Clean Bond Prices

Article Quant Q&A · Author: anothernickname

Summary

The document describes how to align a QuantLib fixed-rate bond valuation with a Bloomberg clean price. The example concerns a Polish government bond valued on a specified date at a given yield. The initial QuantLib calculation differs from Bloomberg by a small amount. The accepted answer attributes the discrepancy to date adjustment in the bond valuation and to how accrued interest is rounded.

The suggested adjustment is to set the bond’s payment date convention to unadjusted when constructing it, calculate the dirty price, and subtract accrued interest rounded to the precision used for the clean price comparison. Applying those conventions makes the example values agree at the displayed precision. This is a narrow implementation note, not a general claim that Bloomberg always uses these conventions for every instrument or market. Matching prices requires checking the bond’s schedule, settlement and valuation conventions, compounding assumptions, and rounding rules against the specific reference calculation.

Key ideas

  • Date adjustment conventions in bond construction can affect calculated present values.
  • The example matches the reference clean price by using unadjusted dates.
  • The suggested clean price calculation subtracts rounded accrued interest from dirty price.
  • Price agreement depends on matching instrument conventions and rounding precision.

Tags

Full text
# Quantlib match clean price with bbg clean price


# Quantlib match clean price with bbg clean price












I'm trying to match QL clean price with BBG clean price for POLGB 2.75 10/25/29 1029 priced for 15th of October 2021 for 2.5% yield. I'm not sure if my setup of bond is wrong or if there is a problem with precision of calculations.

```
import QuantLib as ql

todaysDate= ql.Date(15,10,2021)

ql.Settings.instance().setEvaluationDate(todaysDate)

issueDate = ql.Date(11, 2, 2019)
maturityDate = ql.Date(25, 10, 2029)
tenor = ql.Period(ql.Annual)
calendar = ql.Poland()
bussinessConvention = ql.Following
dateGeneration = ql.DateGeneration.Backward
monthEnd = False
schedule = ql.Schedule (ql.Date(25,10,2018), maturityDate, tenor, calendar, ql.Unadjusted,
                            ql.Unadjusted , dateGeneration, monthEnd)

dayCount = ql.ActualActual(ql.ActualActual.ISMA)
couponRate = .0275
coupons = [couponRate]

settlementDays = 0
faceValue = 100
fixedRateBond = ql.FixedRateBond(settlementDays, faceValue, schedule, coupons, dayCount)

print(round(fixedRateBond.cleanPrice(0.025,ql.ActualActual(ql.ActualActual.ISMA),ql.CompoundedThenSimple,ql.Annual),6))
```

QuantLib clean price = 101.796832 BBG clean price = 101.796834

## Answer by anothernickname (score 4, accepted)

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

BBG does not adjust dates when calculating NPV. To get the same result in QuantLib we need to add ql.Unadjusted to FixedRateBond parameter. Also to get exactly the same clean price we need to calculate dirty price and subtract rounded accrued amount.

```
fixedRateBond = ql.FixedRateBond(settlementDays, faceValue, schedule, coupons, dayCount, ql.Unadjusted)

print(round(fixedRateBond.dirtyPrice(0.025,ql.ActualActual(ql.ActualActual.ISMA),
ql.Compounded,ql.Annual),6)-round(fixedRateBond.accruedAmount(ql.Date(15,10,2021)),3))
```

Quantlib clean price = 101.796834

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.