Skip to content
All library documents

Setting CPI Bond Inflation Curves and Historical Fixings in QuantLib

Article Quant Q&A · Author: Thomas David

Summary

The document explains common date and fixing mistakes when building a CPI-linked bond in QuantLib with historical CPI observations and assumed zero future inflation. The answer clarifies that the inflation curve reference date should correspond to the appropriate base date, anchored to the latest CPI fixing actually available, rather than an arbitrary future date. It also distinguishes the valuation date from the base date when constructing the curve.

The example points out that inflation fixings are published with a lag, so recent calendar months may not yet have observed values. The last known fixing, rather than a not-yet-published month, should inform the base date and the historical fixing series. Correcting these choices is reported to resolve the code issue. The advice depends on current publication timing and a particular CPI index setup; it does not explain all CPI bond conventions or provide a general treatment of inflation curve construction.

Key ideas

  • Set the inflation curve base date using the latest CPI fixing available at the valuation date.
  • Account for publication lags before adding monthly CPI observations as historical fixings.
  • Keep the valuation date and the CPI base date distinct when constructing the inflation curve.
  • Correcting dates and fixings can resolve errors that otherwise produce uninformative messages.

Tags

Full text
# building a CPIBond with zero-inflation


# building a CPIBond with zero-inflation












I am trying to build a CPIBond object that has historical CPI fixings but assumes zero inflation from the current date onwards. My code is below and I am getting the following error:

```
from QuantLib import *

# make cpi index
ref_date = Date(1, 8, 2025)
start_date = Date.todaysDate()
end_date = start_date + Period(100, Years)

dates = [start_date, end_date]
rates=[0.0,0.0]
zero_inflation = ZeroInflationCurve(ref_date, dates, rates, Monthly, ActualActual(ActualActual.ISDA))
zero_inflation_ts_handle = ZeroInflationTermStructureHandle(zero_inflation)
cpi_index = USCPI(zero_inflation_ts_handle)

# add historical CPI fixings
cpi_vals = [315.664, 315.493, 315.605, 317.671, 319.082, 319.799, 320.795]
for i in range(1,8):
   cpi_index.addFixing(Date(1,i,2025), cpi_vals[i-1])
   

issue_date = Date(15, 4, 2025)
maturity_date = Date(15, 4, 2030)
tenor = Period(Semiannual)
calendar = UnitedStates(UnitedStates.NYSE)
business_convention = Following
date_generation = DateGeneration.Backward
month_end = False
schedule = Schedule (issue_date, maturity_date, tenor,
                    calendar, business_convention,
                    business_convention , date_generation,
                    month_end)

coupon_rate = .01625
coupons = [coupon_rate]
settlement_days = 0
face_value = 100
base_cpi = 318.32947

cpi_bond = CPIBond(settlement_days, face_value, False, base_cpi, Period(3, Months), cpi_index,
                  CPI.Linear, schedule, coupons, day_count)

cpi_bond.bondYield(100,ActualActual(ActualActual.ISDA),CompoundedThenSimple,Monthly)
```

## Answer by Luigi Ballabio (score 1, accepted)

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

I'm seeing a few things to fix in the code.

You're using today as evaluation date, July 11 as I write, and then you're using August 1st 2025 as "ref date". If you're meaning that as the base date for the inflation curve (that is, the date of the last known CPI value) this choice doesn't work, since August 1st is in the future.

Looking at the past CPI fixings for the index, I see you're adding fixings for January to July included. The last one puzzles me a bit. As of July 11th, the fixing for July can't possibly have been published; it will be published at some point in August. As I write this, I don't think the June inflation has been published either. The last fixing available should be the May fixing (that I don't see in your fixings; the last one, 320.795, is the April fixing, published in May). Assuming you also add the May fixing to the code, the base date should be May 1st. If you add the June fixing when it's published in a few days from now, the base date will be June 1st.

Finally, you're creating the inflation curve as

```
zero_inflation = ZeroInflationCurve(
    ref_date, [start_date, end_date], rates, Monthly, day_counter
)
```

or, giving dates different names to make them more clear,

```
zero_inflation = ZeroInflationCurve(
    base_date, [valuation_date, end_date], rates, Monthly,, day_counter
)
```

Instead, it should be

```
zero_inflation = ZeroInflationCurve(
    valuation_date, [base_date, end_date], rates, Monthly,, day_counter
)
```

Once you do these changes, the code works.

Unfortunately, the error message gives no hint that any of the above is going on...

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.