CPI bonds¶
CpiBond in Rust, CPIBond in Python and Session.NewCPIBond in Go construct
plain CPI-indexed coupon bonds. The C ABI entry point is itofin_cpi_bond_new.
This is the modern, explicit-base-CPI construction path, not the deprecated
growthOnly overload.
Cash flows and price units¶
- Each coupon pays face amount times its fixed annual coupon rate, accrual fraction and observed CPI divided by the explicit base CPI.
- Terminal principal pays the full face amount times observed CPI/base CPI. It is a live, fixing-dependent cash flow, not an ordinary fixed redemption.
- CPI observations use the unadjusted accrual end or schedule maturity with the supplied observation lag. Flat and Linear conventions are supported.
- Accrued interest observes CPI at the requested accrual date. Ex-coupon accrued interest can be negative.
- Dirty/clean prices and accrued interest are per 100 of original outstanding face amount. They are not divided by inflation-adjusted principal.
- Contractual maturity is schedule end. The final payment may be adjusted to
a different date. Outstanding notional is the face amount strictly before
the adjusted terminal payment day, and zero on that day and afterwards,
regardless of
includeReferenceDateEvents. Instrument expiry can still differ on that payment day when the event-inclusion setting changes.
Inputs and retained dependencies¶
Provide a positive finite face amount and base CPI, an explicit inflation index, observation lag, interpolation convention, increasing schedule of at least two valid dates, nonempty finite coupon-rate vector, accrual day counter and the same Settings used by the index. Short coupon vectors repeat their final rate.
Payment convention defaults to Modified Following. The payment calendar defaults to the schedule calendar. Optional issue date and ex-coupon conventions follow the common bond interface. The bounded constructor does not expose growth-only principal, amortization, capped/floored CPI coupons, a separate first-period day counter, or a one-date zero-coupon schedule.
Use the existing DiscountingBondEngine with the same Settings. CPI forecasting
uses the inflation curve linked to the index; discounting uses the engine's
nominal curve. The instrument retains both dependency graphs. Quote changes,
index fixing additions, inflation-curve relinks and evaluation-date changes
invalidate pricing through the existing observer graph. Construction is lazy:
missing fixings or a forecast curve are reported when an amount or valuation
actually requires them.
Python objects are thread-confined retained Rust objects. Go objects belong to one Session, retain native dependencies after wrapper Close, and must be closed explicitly. Mixed-session inputs are rejected. Different Settings identities are rejected even when their evaluation dates happen to be equal.
Supported operations and boundaries¶
The resulting object exposes Bond valuation, cash-flow inspection, settlement,
notional, flat-yield duration/convexity/BPV and lifecycle operations. The inherited
coupon BPS-from-curve/yield and ATM-rate-from-curve/price methods reject CPI bonds:
the generic coupon weights omit the CPI ratio and must not be interpreted as
sensitivity to the raw contractual CPI coupon rate. No core formula is changed. The native proof in
sdk/go/testdata/cpi-bond-coupon-risk.json, reproduced by
scripts/generate_cpi_bond_coupon_risk_oracle.py, contrasts generic BPS with an
actual one-basis-point contractual-rate bump and generic ATM with the raw rate. Date-only inspection
must not evaluate CPI amounts. Retained cash-flow and redemption wrappers remain
index-dependent, including after the original bond wrapper is dropped or closed.
Extracted CPI legs retain the original Settings identity for NPV and spread-NPV
queries, reject mixed Settings, and reject nonfinite aggregate results.
The existing bounded AssetSwap and BondForward facades continue to accept
only their documented fixed/zero plain-bond scope. They reject CPI bonds before
trying to resolve CPI fixings. This release does not extend those consumers to
indexed bonds or add CPI optionality to the bond.
All additions preserve existing bond constructors and signatures.
Numerical reference¶
Tests use independently generated QuantLib 1.43 wheel results in
sdk/go/testdata/cpi-oracle-bonds.json, with shared inputs and provenance in
cpi-oracle-inputs.json. Reproduction is in scripts/generate_cpi_oracle.py.
The supplemental cpi-bond-preceding.json fixture and
scripts/generate_cpi_bond_preceding_oracle.py cover adjusted principal payment
before contractual maturity, terminal notional shutdown and event inclusion.
The source reference is QuantLib revision
9863b578af0caa4cecabf697196533e84a8308b6,
ql/instruments/bonds/cpibond.{hpp,cpp}. The wheel is not claimed to have been
built from that source revision.
Coverage includes Flat/Linear observations, per-100 clean/dirty/accrued units, full indexed principal, live discount changes, inflation relinks, historical fixing changes, adjusted final payment dates, negative ex-coupon accrual and missing-fixing errors. This bounded comparison is not a full QuantLib parity claim.