Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Functions
QuantExt::ZeroInflation Namespace Reference

Functions

QuantLib::Date lastAvailableFixing (const QuantLib::ZeroInflationIndex &index, const QuantLib::Date &asof)
 Check if today - availabilityLag is already known, otherwise return the fixingDate of the previous fixing. More...
 
QuantLib::Rate cpiFixing (const QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex > &index, const QuantLib::Date &maturity, const QuantLib::Period &obsLag, bool interpolated)
 Computes a CPI fixing giving an zeroIndex, with interpolation if needed. More...
 
QuantLib::Date curveBaseDate (const bool baseDateLastKnownFixing, const QuantLib::Date &refDate, const QuantLib::Period obsLagCurve, const QuantLib::Frequency curveFreq, const QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex > &index)
 derives the zero inflation curve base date based on the useLastKnownFixing rule More...
 
QuantLib::Date fixingDate (const QuantLib::Date &d, const QuantLib::Period obsLag, const QuantLib::Frequency freq, bool interpolated)
 
QuantLib::Rate guessCurveBaseRate (const bool baseDateLastKnownFixing, const QuantLib::Date &swapStart, const QuantLib::Date &asof, const QuantLib::Period &swapTenor, const QuantLib::DayCounter &swapZCLegDayCounter, const QuantLib::Period &swapObsLag, const QuantLib::Rate zeroCouponRate, const QuantLib::Period &curveObsLag, const QuantLib::DayCounter &curveDayCounter, const QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex > &index, const bool interpolated, const QuantLib::ext::shared_ptr< QuantLib::Seasonality > &seasonality)
 
bool isCPIVolSurfaceLogNormal (const QuantLib::ext::shared_ptr< QuantLib::CPIVolatilitySurface > &surface)
 

Function Documentation

◆ lastAvailableFixing()

QuantLib::Date lastAvailableFixing ( const QuantLib::ZeroInflationIndex &  index,
const QuantLib::Date &  asof 
)

Check if today - availabilityLag is already known, otherwise return the fixingDate of the previous fixing.

Definition at line 156 of file inflation.cpp.

156 {
157 Date availbilityLagFixingDate = inflationPeriod(asof - index.availabilityLag(), index.frequency()).first;
158 if (index.hasHistoricalFixing(availbilityLagFixingDate)) {
159 return availbilityLagFixingDate;
160 } else {
161 // The fixing for the inflation period before the availability lag should be there
162 return inflationPeriod(availbilityLagFixingDate - 1 * QuantLib::Days, index.frequency()).first;
163 }
164}
+ Here is the caller graph for this function:

◆ cpiFixing()

QuantLib::Rate cpiFixing ( const QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex > &  index,
const QuantLib::Date &  maturity,
const QuantLib::Period &  obsLag,
bool  interpolated 
)

Computes a CPI fixing giving an zeroIndex, with interpolation if needed.

Definition at line 166 of file inflation.cpp.

167 {
168 QuantLib::CPI::InterpolationType interpolation = interpolated ? QuantLib::CPI::Linear : QuantLib::CPI::Flat;
169 return QuantLib::CPI::laggedFixing(index, maturity, obsLag, interpolation);
170}
+ Here is the caller graph for this function:

◆ curveBaseDate()

QuantLib::Date curveBaseDate ( const bool  baseDateLastKnownFixing,
const QuantLib::Date &  refDate,
const QuantLib::Period  obsLagCurve,
const QuantLib::Frequency  curveFreq,
const QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex > &  index 
)

derives the zero inflation curve base date based on the useLastKnownFixing rule

Definition at line 172 of file inflation.cpp.

174 {
175 if (baseDateLastKnownFixing) {
176 QL_REQUIRE(index, "can not compute curve base date based on the last known index fixing if no index provided");
177 return lastAvailableFixing(*index, refDate);
178 } else {
179 return QuantLib::inflationPeriod(refDate - obsLagCurve, curveFreq).first;
180 }
181}
QuantLib::Date lastAvailableFixing(const QuantLib::ZeroInflationIndex &index, const QuantLib::Date &asof)
Check if today - availabilityLag is already known, otherwise return the fixingDate of the previous fi...
Definition: inflation.cpp:156
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fixingDate()

QuantLib::Date fixingDate ( const QuantLib::Date &  d,
const QuantLib::Period  obsLag,
const QuantLib::Frequency  ,
bool  interpolated 
)

computes the fixingDate for ZC CPI Swap following the rule for an interpolated index it is d - obsLag but for an interpolated index the fixing date is per definition on the start of the inflation period in which d - obsLag falls

Definition at line 183 of file inflation.cpp.

184 {
185 Date obsDate = d - obsLag;
186 if (!interpolated)
187 obsDate = QuantLib::inflationPeriod(obsDate, freq).first;
188 return obsDate;
189}
+ Here is the caller graph for this function:

◆ guessCurveBaseRate()

QuantLib::Rate guessCurveBaseRate ( const bool  baseDateLastKnownFixing,
const QuantLib::Date &  swapStart,
const QuantLib::Date &  asof,
const QuantLib::Period &  swapTenor,
const QuantLib::DayCounter &  swapZCLegDayCounter,
const QuantLib::Period &  swapObsLag,
const QuantLib::Rate  zeroCouponRate,
const QuantLib::Period &  curveObsLag,
const QuantLib::DayCounter &  curveDayCounter,
const QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex > &  index,
const bool  interpolated,
const QuantLib::ext::shared_ptr< QuantLib::Seasonality > &  seasonality = nullptr 
)

Computes the base rate for curve construction so that zero inflation rate is constant up to the first pillar Accounts for the acctual accrued inflation between the ZCIIS base date and the curve base date (e.g. last published fixing date) If curve base date and ZCIIS are the same, then the base rate is the ZCIIS rate

Definition at line 191 of file inflation.cpp.

197 {
198 QuantLib::ext::shared_ptr<QuantLib::MultiplicativePriceSeasonality> multiplicativeSeasonality =
199 seasonality ? QuantLib::ext::dynamic_pointer_cast<QuantLib::MultiplicativePriceSeasonality>(seasonality) : nullptr;
200
201 QL_REQUIRE(seasonality == nullptr || multiplicativeSeasonality,
202 "Only multiplicative seasonality supported at the moment");
203
204 Date swapBaseDate = ZeroInflation::fixingDate(swapStart, swapObsLag, index->frequency(), interpolated);
205
206 Date curveBaseDate =
207 ZeroInflation::curveBaseDate(baseDateLastKnownFixing, asof, curveObsLag, index->frequency(), index);
208
209 // If the baseDate in Curve is today - obsLag then the quoted zeroRate should be used
210 if (!baseDateLastKnownFixing && swapBaseDate == curveBaseDate)
211 return zeroCouponRate;
212
213 QL_REQUIRE(index, "can not compute base cpi of the zero coupon swap");
214 // Otherwise we need to take into account the accrued inflation between rate helper base date and curve base date
215 // Check if historical fixings available
216 try {
217 checkIfFixingAvailable(swapStart, swapObsLag, interpolated, *index);
218 } catch (const std::exception& e) {
219 QL_FAIL("Can not estimate the curve base date, got " << e.what());
220 }
221
222 Date swapMaturity = swapStart + swapTenor;
223 Date swapObservationDate = ZeroInflation::fixingDate(swapMaturity, swapObsLag, index->frequency(), interpolated);
224
225 // TODO check historical fixings available
226 Rate instrumentBaseCPI = cpiFixing(index, swapStart, swapObsLag, interpolated);
227 Time timeFromSwapBase =
228 inflationYearFraction(index->frequency(), interpolated, swapZCLegDayCounter, swapBaseDate, swapObservationDate);
229
230 auto fwdCPI = instrumentBaseCPI * std::pow(1 + zeroCouponRate, timeFromSwapBase);
231
232 double curveBaseFixing = index->fixing(curveBaseDate);
233
234 if (!interpolated) {
235 Time timeFromCurveBase = inflationYearFraction(index->frequency(), interpolated, curveDayCounter, curveBaseDate,
236 swapObservationDate);
237 double rateWithSeasonality = std::pow(fwdCPI / curveBaseFixing, 1.0 / timeFromCurveBase) - 1.0;
238
239 if (multiplicativeSeasonality) {
240 double factorAt = multiplicativeSeasonality->seasonalityFactor(swapObservationDate);
241 double factorBase = multiplicativeSeasonality->seasonalityFactor(curveBaseDate);
242 double seasonalityFactor = std::pow(factorAt / factorBase, 1.0 / timeFromCurveBase);
243 return (rateWithSeasonality + 1) / seasonalityFactor - 1;
244 } else {
245 return rateWithSeasonality;
246 }
247 } else {
248 // Compute the interpolated fixing of the ZCIIS at maturity
249 auto fixingPeriod = inflationPeriod(swapObservationDate, index->frequency());
250 auto paymentPeriod = inflationPeriod(swapMaturity, index->frequency());
251 // Fixing times from curve base date
252 Time timeToFixing1 =
253 inflationYearFraction(index->frequency(), false, curveDayCounter, curveBaseDate, fixingPeriod.first);
254 Time timeToFixing2 = inflationYearFraction(index->frequency(), false, curveDayCounter, curveBaseDate,
255 fixingPeriod.second + 1 * Days);
256
257 // Time interpolation
258 Time timeToPayment =
259 inflationYearFraction(index->frequency(), true, curveDayCounter, curveBaseDate, swapMaturity);
260 Time timeToStartPaymentPeriod =
261 inflationYearFraction(index->frequency(), false, curveDayCounter, curveBaseDate, paymentPeriod.first);
262 Time timeToEndPaymenetPeriod = inflationYearFraction(index->frequency(), false, curveDayCounter, curveBaseDate,
263 paymentPeriod.second + 1 * Days);
264 Time interpolationFactor =
265 (timeToPayment - timeToStartPaymentPeriod) / (timeToEndPaymenetPeriod - timeToStartPaymentPeriod);
266
267 // Root search for a constant rate that the interpolation of both cpi matches the forward cpi
268 Real target = fwdCPI / curveBaseFixing;
269
270 Real seasonalityFactor1 = 1.0;
271 Real seasonalityFactor2 = 1.0;
272
273 if (multiplicativeSeasonality) {
274 double factorAt1 = multiplicativeSeasonality->seasonalityFactor(fixingPeriod.first);
275 double factorAt2 = multiplicativeSeasonality->seasonalityFactor(fixingPeriod.second + 1 * Days);
276 double factorBase = multiplicativeSeasonality->seasonalityFactor(curveBaseDate);
277 seasonalityFactor1 = factorAt1 / factorBase;
278 seasonalityFactor2 = factorAt2 / factorBase;
279 }
280
281
282 std::function<double(double)> objectiveFunction = [&timeToFixing1, &timeToFixing2, &interpolationFactor,
283 &target, &seasonalityFactor1, &seasonalityFactor2](Rate r) {
284 return target - (std::pow(1 + r, timeToFixing1) * seasonalityFactor1 +
285 (std::pow(1 + r, timeToFixing2) * seasonalityFactor2 -
286 std::pow(1 + r, timeToFixing1) * seasonalityFactor1) *
287 interpolationFactor);
288 };
289
290 Rate guess = std::pow(fwdCPI / curveBaseFixing, 1.0 / timeToFixing2) - 1.0;
291 Rate r = guess;
292 try {
293 QuantLib::Brent solver;
294 r = solver.solve(objectiveFunction, 1e-8, guess, -0.1, 0.2);
295 } catch (...) {
296 r = guess;
297 }
298 return r;
299 }
300}
QuantLib::Date curveBaseDate(const bool baseDateLastKnownFixing, const QuantLib::Date &refDate, const QuantLib::Period obsLagCurve, const QuantLib::Frequency curveFreq, const QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex > &index)
derives the zero inflation curve base date based on the useLastKnownFixing rule
Definition: inflation.cpp:172
+ Here is the call graph for this function:

◆ isCPIVolSurfaceLogNormal()

bool isCPIVolSurfaceLogNormal ( const QuantLib::ext::shared_ptr< QuantLib::CPIVolatilitySurface > &  surface)

checks if the vols are normal or lognormal if the volsurface is not derived from QuantExt::CPIVolatilitySurface we default to lognormal vols

Definition at line 302 of file inflation.cpp.

302 {
303 if (auto qvs = QuantLib::ext::dynamic_pointer_cast<QuantExt::CPIVolatilitySurface>(surface)) {
304 return qvs->isLogNormal();
305 } else {
306 // QuantLib::CPIVolatilitySurface doesn't support volType so assume it's log normal
307 return true;
308 }
309}