Why QuantLib CPI Bonds Need an Inflation Forecast Curve
Summary
This exchange explains why calculating a CPI bond yield in QuantLib can fail with an empty-handle error, even when the bond has a base CPI, coupon, price, and current reference CPI. The key issue is that the inflation index needs a forecast curve to determine CPI fixings on future dates. Adding fixings directly to the index supplies observations for past dates, but does not provide forecasts for future cash flows.
The example concerns a UK RPI-linked bond with dummy index values and a call to the bond yield method. The accepted answer identifies the missing forecast input and points to inflation curves as the relevant concept. It does not give implementation steps or establish a street-convention yield calculation, so readers would need additional documentation to build and attach the curve correctly.
Key ideas
- Inflation index fixings represent observed values for past dates.
- A CPI bond requires a forecast curve to estimate future index values.
- Supplying dummy fixings does not replace a zero-inflation term structure for future dates.
- The empty-handle error reflects a missing inflation forecast dependency.
Tags
Full text
# building a CPI Bond in quantlib
# building a CPI Bond in quantlib
I am building a CPIBond in quantlib and trying to call the .bondYield method. I am getting a RuntimeError saying that the empty Handle cannot be dereferenced. Why is this happening? Isn't all I need to get the bondYield the baseCPI, the coupon rate, the clean price, and the current ref CPI? For context, I am feeding it dummy CPI values just as I am trying to fix this error. Also, this works just fine if I am building a standard FixedRateBond.
All I want is to build a basic CPI bond object and have it get the accurate bondYield according to street convention using the .bondYield method. I have read that it may have something to do with attaching a ZeroInflationTermStructure but I'm not sure what that is or why I would need it.
The code is below:
```
from prompt_toolkit.key_binding.bindings.named_commands import get_by_name
from ustbas_quantlib_helper import *
from bond_helper import BondHelperClass_AvkQuantLib
from bond_object_class import BondObjectClass_AvkQuantLib, BillObjectClass_AvkQuantLib, TipsObjectClass_AvkQuantLib
from builder_wrapper_bond_object import BuilderBondObject
def main():
calendar = UnitedKingdom()
today = Date(5,3,2008)
evalDate = calendar.adjust(today)
issue_date = calendar.advance(evalDate,-1,Years)
mat_date = Date(2,9,2052)
settlementDays = 3
notional = 1000000
growthOnly = False
baseCPI = 206.1
contractObservationLag = Period(3, Months)
inflatinoIndex = UKRPI()
obsInterpolation = CPI.Flat
fixedSchedule = MakeSchedule(issue_date, mat_date, Period(Semiannual))
fixedRates = [0.1]
fixedDayCounter = ActualActual(ActualActual.ISDA)
fixedPaymentConvention = ModifiedFollowing
for j in range(2007,2060):
for i in range(1,13):
fixing_date = Date(1, i, j)
inflatinoIndex.addFixing(fixing_date, 208)
bond = CPIBond(settlementDays, notional, growthOnly, baseCPI, contractObservationLag, inflatinoIndex, obsInterpolation, fixedSchedule, fixedRates, fixedDayCounter, fixedPaymentConvention)
print(bond)
settles_clean_price = 99
day_counter = ActualActual(ActualActual.ISDA)
compounding_rule = SimpleThenCompounded
frequency = Semiannual
settlement_date = today + 1
_YIELD_PRECISION = 1.0e-11
_MAX_ITERATIONS = 100000
print(bond.bondYield(settles_clean_price, day_counter, compounding_rule, frequency,
settlement_date,
_YIELD_PRECISION,
_MAX_ITERATIONS) * 1.0)
if __name__ == "__main__":
main()
```
## Answer by Luigi Ballabio (score 1, accepted)
https://quant.stackexchange.com/a/83740
Adding fixings to the inflation index only works for dates in the past, not in the future. The library expects the inflation index to be given a forecast curve for determining future CPI fixings. See https://www.quantlibguide.com/Inflation%20indexes%20and%20curves.html.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.