Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Public Types | Public Member Functions | List of all members
InfJyBuilder Class Reference

#include <ored/model/inflation/infjybuilder.hpp>

+ Inheritance diagram for InfJyBuilder:
+ Collaboration diagram for InfJyBuilder:

Public Types

using Helpers = std::vector< QuantLib::ext::shared_ptr< QuantLib::CalibrationHelper > >
 

Public Member Functions

 InfJyBuilder (const QuantLib::ext::shared_ptr< Market > &market, const QuantLib::ext::shared_ptr< InfJyData > &data, const std::string &configuration=Market::defaultConfiguration, const std::string &referenceCalibrationGrid="", const bool donCalibrate=false)
 
Inspectors
std::string inflationIndex () const
 
QuantLib::ext::shared_ptr< QuantExt::InfJyParameterizationparameterization () const
 
Helpers realRateBasket () const
 
Helpers indexBasket () const
 
- Public Member Functions inherited from ModelBuilder
void recalibrate () const
 
virtual void forceRecalculate ()
 
virtual bool requiresRecalibration () const=0
 

Private Member Functions

LazyObject interface
void performCalculations () const override
 
void buildCalibrationBaskets () const
 Build any calibration baskets requested by the configuration i.e. via the data_ member. More...
 
Helpers buildCalibrationBasket (const CalibrationBasket &cb, std::vector< bool > &active, QuantLib::Array &expiries, bool forRealRateReversion=false) const
 Build the calibration basket. More...
 
Helpers buildCpiCapFloorBasket (const CalibrationBasket &cb, std::vector< bool > &active, QuantLib::Array &expiries) const
 Build a CPI cap floor calibration basket. More...
 
Helpers buildYoYCapFloorBasket (const CalibrationBasket &cb, std::vector< bool > &active, QuantLib::Array &expiries) const
 Build a YoY cap floor calibration basket. More...
 
Helpers buildYoYSwapBasket (const CalibrationBasket &cb, std::vector< bool > &active, QuantLib::Array &expiries, bool forRealRateReversion=false) const
 Build a YoY swap calibration basket. More...
 
const CalibrationBasketcalibrationBasket (const std::string &parameter) const
 Find calibration basket with parameter value equal to parameter. More...
 
QuantLib::ext::shared_ptr< QuantExt::Lgm1fParametrization< ZeroInflationTermStructure > > createRealRateParam () const
 Create the real rate parameterisation. More...
 
QuantLib::ext::shared_ptr< QuantExt::FxBsParametrizationcreateIndexParam () const
 Create the inflation index parameterisation. More...
 
void setupParams (const ModelParameter &param, QuantLib::Array &times, QuantLib::Array &values, const QuantLib::Array &expiries, const std::string &paramName) const
 
std::vector< QuantLib::Date > referenceCalibrationDates () const
 Create the reference calibration dates. More...
 
void initialiseMarket ()
 Attempt to initialise market data members that may be needed for building calibration instruments. More...
 
bool pricesChanged (bool updateCache) const
 
QuantLib::Real marketPrice (const QuantLib::ext::shared_ptr< QuantLib::CalibrationHelper > &helper) const
 Return the market value of the given calibration helper. More...
 

ModelBuilder interface

QuantLib::ext::shared_ptr< Marketmarket_
 
std::string configuration_
 
QuantLib::ext::shared_ptr< InfJyDatadata_
 
std::string referenceCalibrationGrid_
 
bool dontCalibrate_
 
QuantLib::ext::shared_ptr< QuantExt::InfJyParameterizationparameterization_
 
QuantLib::ext::shared_ptr< QuantExt::MarketObservermarketObserver_
 
Handle< YieldTermStructure > rateCurve_
 
QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex > zeroInflationIndex_
 
QuantLib::Handle< QuantLib::CPIVolatilitySurface > cpiVolatility_
 
QuantLib::ext::shared_ptr< QuantLib::YoYInflationIndex > yoyInflationIndex_
 
QuantLib::Handle< QuantLib::YoYOptionletVolatilitySurface > yoyVolatility_
 
bool forceCalibration_ = false
 
Helpers realRateBasket_
 
std::vector< boolrrInstActive_
 
QuantLib::Array rrInstExpiries_
 
Helpers indexBasket_
 
std::vector< boolindexInstActive_
 
QuantLib::Array indexInstExpiries_
 
std::vector< QuantLib::Real > priceCache_
 Cache the prices of all of the active calibration helper instruments. More...
 
void forceRecalculate () override
 
bool requiresRecalibration () const override
 
void setCalibrationDone () const
 

Detailed Description

Builder for a Jarrow Yildrim inflation model component

This class is a utility to turn a Jarrow Yildrim inflation model component description into an inflation model parameterization which can be used to instantiate a CrossAssetModel.

Definition at line 42 of file infjybuilder.hpp.

Member Typedef Documentation

◆ Helpers

using Helpers = std::vector<QuantLib::ext::shared_ptr<QuantLib::CalibrationHelper> >

Definition at line 54 of file infjybuilder.hpp.

Constructor & Destructor Documentation

◆ InfJyBuilder()

InfJyBuilder ( const QuantLib::ext::shared_ptr< Market > &  market,
const QuantLib::ext::shared_ptr< InfJyData > &  data,
const std::string &  configuration = Market::defaultConfiguration,
const std::string &  referenceCalibrationGrid = "",
const bool  donCalibrate = false 
)

Constructor

Parameters
marketMarket object
dataJarrow Yildrim inflation model description
configurationMarket configuration to use
referenceCalibrationGridThe reference calibration grid

Definition at line 77 of file infjybuilder.cpp.

80 : market_(market), configuration_(configuration), data_(data), referenceCalibrationGrid_(referenceCalibrationGrid),
81 dontCalibrate_(dontCalibrate), marketObserver_(QuantLib::ext::make_shared<MarketObserver>()),
82 zeroInflationIndex_(*market_->zeroInflationIndex(data_->index(), configuration_)) {
83
84 LOG("InfJyBuilder: building model for inflation index " << data_->index());
85
86 // Get rate curve
87 rateCurve_ = market_->discountCurve(zeroInflationIndex_->currency().code(), configuration_);
88
89 // Register with market observables except volatilities
91 marketObserver_->registerWith(rateCurve_);
93
94 // Register the model builder with the market observer
95 registerWith(marketObserver_);
96
97 // Notify observers of all market data changes, not only when not calculated
98 alwaysForwardNotifications();
99
100 // Build the calibration instruments
102
103 // Create the JY parameterisation.
104 parameterization_ = QuantLib::ext::make_shared<QuantExt::InfJyParameterization>(
106}
QuantLib::ext::shared_ptr< QuantLib::ZeroInflationIndex > zeroInflationIndex_
std::string referenceCalibrationGrid_
QuantLib::ext::shared_ptr< Market > market_
QuantLib::ext::shared_ptr< QuantExt::MarketObserver > marketObserver_
void initialiseMarket()
Attempt to initialise market data members that may be needed for building calibration instruments.
QuantLib::ext::shared_ptr< InfJyData > data_
QuantLib::ext::shared_ptr< QuantExt::Lgm1fParametrization< ZeroInflationTermStructure > > createRealRateParam() const
Create the real rate parameterisation.
Handle< YieldTermStructure > rateCurve_
void buildCalibrationBaskets() const
Build any calibration baskets requested by the configuration i.e. via the data_ member.
QuantLib::ext::shared_ptr< QuantExt::FxBsParametrization > createIndexParam() const
Create the inflation index parameterisation.
QuantLib::ext::shared_ptr< QuantExt::InfJyParameterization > parameterization_
#define LOG(text)
Logging Macro (Level = Notice)
Definition: log.hpp:552
+ Here is the call graph for this function:

Member Function Documentation

◆ inflationIndex()

string inflationIndex ( ) const

Definition at line 108 of file infjybuilder.cpp.

108 {
109 return data_->index();
110}
+ Here is the caller graph for this function:

◆ parameterization()

QuantLib::ext::shared_ptr< QuantExt::InfJyParameterization > parameterization ( ) const

Definition at line 112 of file infjybuilder.cpp.

112 {
113 calculate();
114 return parameterization_;
115}

◆ realRateBasket()

Helpers realRateBasket ( ) const

Definition at line 117 of file infjybuilder.cpp.

117 {
118 calculate();
119 return realRateBasket_;
120}

◆ indexBasket()

Helpers indexBasket ( ) const

Definition at line 122 of file infjybuilder.cpp.

122 {
123 calculate();
124 return indexBasket_;
125}

◆ forceRecalculate()

void forceRecalculate ( )
overridevirtual

Reimplemented from ModelBuilder.

Definition at line 144 of file infjybuilder.cpp.

144 {
145 forceCalibration_ = true;
147 forceCalibration_ = false;
148}
virtual void forceRecalculate()
+ Here is the call graph for this function:

◆ requiresRecalibration()

bool requiresRecalibration ( ) const
overridevirtual

Implements ModelBuilder.

Definition at line 127 of file infjybuilder.cpp.

127 {
128 return (data_->realRateVolatility().calibrate() || data_->realRateReversion().calibrate() ||
129 data_->indexVolatility().calibrate()) &&
130 (marketObserver_->hasUpdated(false) || forceCalibration_ || pricesChanged(false));
131}
bool pricesChanged(bool updateCache) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setCalibrationDone()

void setCalibrationDone ( ) const

Definition at line 139 of file infjybuilder.cpp.

139 {
140 marketObserver_->hasUpdated(true);
141 pricesChanged(true);
142}
+ Here is the call graph for this function:

◆ performCalculations()

void performCalculations ( ) const
overrideprivate

Definition at line 133 of file infjybuilder.cpp.

133 {
134 if (requiresRecalibration()) {
136 }
137}
bool requiresRecalibration() const override
+ Here is the call graph for this function:

◆ buildCalibrationBaskets()

void buildCalibrationBaskets ( ) const
private

Build any calibration baskets requested by the configuration i.e. via the data_ member.

Definition at line 150 of file infjybuilder.cpp.

150 {
151
152 // If calibration type is None, don't build any baskets.
153 if (data_->calibrationType() == CalibrationType::None) {
154 DLOG("InfJyBuilder: calibration type is None so no calibration baskets built.");
155 return;
156 }
157
158 const auto& cbs = data_->calibrationBaskets();
159
160 // If calibration type is BestFit, check that we have at least one calibration basket. Build up to a maximum of
161 // two calibration baskets. Log a warning if more than two are given. Arbitrarily assign the built baskets to
162 // the realRateBasket_ and indexBasket_ members. They will be combined again in any case for BestFit calibration.
163 if (data_->calibrationType() == CalibrationType::BestFit) {
164 QL_REQUIRE(cbs.size() > 0, "InfJyBuilder: calibration type is BestFit but no calibration baskets provided.");
165 rrInstActive_ = vector<bool>(cbs[0].instruments().size(), false);
167 if (cbs.size() > 1) {
168 indexInstActive_ = vector<bool>(cbs[1].instruments().size(), false);
170 }
171 if (cbs.size() > 2)
172 WLOG("InfJyBuilder: only 2 calibration baskets can be processed but " << cbs.size() <<
173 " were supplied. The extra baskets are ignored.");
174 return;
175 }
176
177 // Make sure that the calibration type is now Bootstrap.
178 QL_REQUIRE(data_->calibrationType() == CalibrationType::Bootstrap, "InfJyBuilder: expected the calibration " <<
179 "type to be one of None, BestFit or Bootstrap.");
180
181 const VolatilityParameter& idxVolatility = data_->indexVolatility();
182 const ReversionParameter& rrReversion = data_->realRateReversion();
183 const VolatilityParameter& rrVolatility = data_->realRateVolatility();
184
185 // Firstly, look at the inflation index portion i.e. are we calibrating it.
186 if (idxVolatility.calibrate()) {
187
188 DLOG("InfJyBuilder: building calibration basket for JY index bootstrap calibration.");
189
190 // If we are not calibrating the real rate portion, then we expect exactly one calibration basket. Otherwise
191 // we need to find a basket with the 'Index' parameter.
192 if (!rrReversion.calibrate() && !rrVolatility.calibrate()) {
193 QL_REQUIRE(cbs.size() == 1, "InfJyBuilder: calibrating only JY index volatility using Bootstrap so " <<
194 "expected exactly one basket but got " << cbs.size() << ".");
195 const auto& cb = cbs[0];
196 if (!cb.parameter().empty() && cb.parameter() != "Index") {
197 WLOG("InfJyBuilder: calibrating only JY index volatility using Bootstrap so expected the " <<
198 "calibration basket parameter to be 'Index' but got '" << cb.parameter() << "'.");
199 }
200 indexInstActive_ = vector<bool>(cb.instruments().size(), false);
202 } else {
203 DLOG("InfJyBuilder: need a calibration basket with parameter equal to 'Index'.");
204 const auto& cb = calibrationBasket("Index");
205 indexInstActive_ = vector<bool>(cb.instruments().size(), false);
207 }
208 }
209
210 // Secondly, look at the real rate portion i.e. are we calibrating it.
211 if (rrReversion.calibrate() || rrVolatility.calibrate()) {
212
213 DLOG("InfJyBuilder: building calibration basket for JY real rate bootstrap calibration.");
214 QL_REQUIRE(!(rrReversion.calibrate() && rrVolatility.calibrate()), "InfJyBuilder: calibrating both the " <<
215 "real rate reversion and real rate volatility using Bootstrap is not supported.");
216
217 // If we are not calibrating the index portion, then we expect exactly one calibration basket. Otherwise
218 // we need to find a basket with the 'RealRate' parameter.
219 if (!idxVolatility.calibrate()) {
220 QL_REQUIRE(cbs.size() == 1, "InfJyBuilder: calibrating only JY real rate using Bootstrap so " <<
221 "expected exactly one basket but got " << cbs.size() << ".");
222 const auto& cb = cbs[0];
223 if (!cb.parameter().empty() && cb.parameter() != "RealRate") {
224 WLOG("InfJyBuilder: calibrating only JY real rate using Bootstrap so expected the " <<
225 "calibration basket parameter to be 'RealRate' but got '" << cb.parameter() << "'.");
226 }
227 rrInstActive_ = vector<bool>(cb.instruments().size(), false);
229 } else {
230 DLOG("InfJyBuilder: need a calibration basket with parameter equal to 'RealRate'.");
231 const auto& cb = calibrationBasket("RealRate");
232 rrInstActive_ = vector<bool>(cb.instruments().size(), false);
234 }
235 }
236
237}
Helpers buildCalibrationBasket(const CalibrationBasket &cb, std::vector< bool > &active, QuantLib::Array &expiries, bool forRealRateReversion=false) const
Build the calibration basket.
const CalibrationBasket & calibrationBasket(const std::string &parameter) const
Find calibration basket with parameter value equal to parameter.
QuantLib::Array indexInstExpiries_
std::vector< bool > rrInstActive_
QuantLib::Array rrInstExpiries_
std::vector< bool > indexInstActive_
#define DLOG(text)
Logging Macro (Level = Debug)
Definition: log.hpp:554
#define WLOG(text)
Logging Macro (Level = Warning)
Definition: log.hpp:550
Size size(const ValueType &v)
Definition: value.cpp:145
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildCalibrationBasket()

Helpers buildCalibrationBasket ( const CalibrationBasket cb,
std::vector< bool > &  active,
QuantLib::Array &  expiries,
bool  forRealRateReversion = false 
) const
private

Build the calibration basket.

Definition at line 239 of file infjybuilder.cpp.

240 {
241
242 QL_REQUIRE(!cb.empty(), "InfJyBuilder: calibration basket should not be empty.");
243
244 const auto& ci = cb.instruments();
245 QL_REQUIRE(ci.size() == active.size(), "InfJyBuilder: expected the active instruments vector " <<
246 "size to equal the number of calibration instruments");
247 fill(active.begin(), active.end(), false);
248
249 if (cb.instrumentType() == "CpiCapFloor") {
250 return buildCpiCapFloorBasket(cb, active, expiries);
251 } else if (cb.instrumentType() == "YoYCapFloor") {
252 return buildYoYCapFloorBasket(cb, active, expiries);
253 } else if (cb.instrumentType() == "YoYSwap") {
254 return buildYoYSwapBasket(cb, active, expiries, forRealRateReversion);
255 } else {
256 QL_FAIL("InfJyBuilder: expected calibration instrument to be one of CpiCapFloor, YoYCapFloor or YoYSwap");
257 }
258}
Helpers buildYoYSwapBasket(const CalibrationBasket &cb, std::vector< bool > &active, QuantLib::Array &expiries, bool forRealRateReversion=false) const
Build a YoY swap calibration basket.
Helpers buildYoYCapFloorBasket(const CalibrationBasket &cb, std::vector< bool > &active, QuantLib::Array &expiries) const
Build a YoY cap floor calibration basket.
Helpers buildCpiCapFloorBasket(const CalibrationBasket &cb, std::vector< bool > &active, QuantLib::Array &expiries) const
Build a CPI cap floor calibration basket.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildCpiCapFloorBasket()

Helpers buildCpiCapFloorBasket ( const CalibrationBasket cb,
std::vector< bool > &  active,
QuantLib::Array &  expiries 
) const
private

Build a CPI cap floor calibration basket.

Definition at line 260 of file infjybuilder.cpp.

261 {
262
263 DLOG("InfJyBuilder: start building the CPI cap floor calibration basket.");
264
265 QL_REQUIRE(!cpiVolatility_.empty(), "InfJyBuilder: need a non-empty CPI cap floor volatility structure " <<
266 "to build a CPI cap floor calibration basket.");
267
268 // Procedure is to create a CPI cap floor as described by each instrument in the calibration basket. We then value
269 // each of the CPI cap floor instruments using market data and an engine and pass the NPV as the market premium to
270 // helper that we create.
271
272 Helpers helpers;
273
274 // Create the engine
275 auto zts = zeroInflationIndex_->zeroInflationTermStructure();
276
277 QuantLib::ext::shared_ptr<QuantExt::CPICapFloorEngine> engine;
278 bool isLogNormalVol = QuantExt::ZeroInflation::isCPIVolSurfaceLogNormal(cpiVolatility_.currentLink());
279 if (isLogNormalVol) {
280 engine = QuantLib::ext::make_shared<QuantExt::CPIBlackCapFloorEngine>(rateCurve_, cpiVolatility_);
281 } else {
282 engine = QuantLib::ext::make_shared<QuantExt::CPIBachelierCapFloorEngine>(rateCurve_, cpiVolatility_);
283 }
284 // CPI cap floor calibration instrument details. Assumed to equal those from the index and market structures.
285 // Some of these should possibly come from conventions.
286 // Also some variables used in the loop below.
287 auto calendar = zeroInflationIndex_->fixingCalendar();
288 auto baseDate = zts->baseDate();
289 auto baseCpi = dontCalibrate_ ? 100.0 : zeroInflationIndex_->fixing(baseDate);
290 auto bdc = cpiVolatility_->businessDayConvention();
291 auto obsLag = cpiVolatility_->observationLag();
292
293 Handle<ZeroInflationIndex> inflationIndex(zeroInflationIndex_);
294 Date today = Settings::instance().evaluationDate();
295 Real nominal = 1.0;
296
297 // Avoid instruments with duplicate expiry times in the loop below
298 set<Time, CloseCmp> expiryTimes;
299
300 // Reference calibration dates if any. If they are given, we only include one calibration instrument from each
301 // period in the grid. Logic copied from other builders.
302 auto rcDates = referenceCalibrationDates();
303 auto prevRcDate = Date::minDate();
304
305 // Add calibration instruments to the helpers vector.
306 const auto& ci = cb.instruments();
307
308 auto observationInterpolation = cpiVolatility_->indexIsInterpolated() ? CPI::Linear : CPI::Flat;
309
310 for (Size i = 0; i < ci.size(); ++i) {
311
312 auto cpiCapFloor = QuantLib::ext::dynamic_pointer_cast<CpiCapFloor>(ci[i]);
313 QL_REQUIRE(cpiCapFloor, "InfJyBuilder: expected CpiCapFloor calibration instrument.");
314 auto maturity = optionMaturity(cpiCapFloor->maturity(), calendar);
315
316 // Deal with reference calibration date grid stuff.
317 auto rcDate = lower_bound(rcDates.begin(), rcDates.end(), maturity);
318 if (!(rcDate == rcDates.end() || *rcDate > prevRcDate)) {
319 active[i] = false;
320 continue;
321 }
322
323 if (rcDate != rcDates.end())
324 prevRcDate = *rcDate;
325
326 // Build the CPI calibration instrument in order to calculate its NPV.
327
328 /* FIXME - the maturity date is not adjusted on eval date changes even if given as a tenor
329 - if the strike is atm, the value will not be updated on eval date changes */
330 Real strikeValue =
331 cpiCapFloorStrikeValue(cpiCapFloor->strike(), *zeroInflationIndex_->zeroInflationTermStructure(), maturity);
332 Option::Type capfloor = cpiCapFloor->type() == CapFloor::Cap ? Option::Call : Option::Put;
333 auto inst = QuantLib::ext::make_shared<CPICapFloor>(capfloor, nominal, today, baseCpi, maturity, calendar, bdc, calendar, bdc,
334 strikeValue, zeroInflationIndex_, obsLag, observationInterpolation);
335 inst->setPricingEngine(engine);
336
337 auto fixingDate = inst->fixingDate();
338 auto t = inflationTime(fixingDate, *zts, false);
339
340 // Build the helper using the NPV as the premium.
341 Real premium;
343 premium = 0.01;
344 else if(t <= 0.0)
345 premium = 0.0;
346 else
347 premium = inst->NPV();
348
349 auto helper = QuantLib::ext::make_shared<CpiCapFloorHelper>(capfloor, baseCpi, maturity, calendar, bdc, calendar, bdc,
350 strikeValue, inflationIndex, obsLag, premium,
351 observationInterpolation);
352
353 // if time is not positive or market prem is zero deactivate helper
354 if (t < 0.0 || QuantLib::close_enough(t, 0.0) || QuantLib::close_enough(premium, 0.0)) {
355 active[i] = false;
356 continue;
357 }
358
359 auto p = expiryTimes.insert(t);
360 QL_REQUIRE(data_->ignoreDuplicateCalibrationExpiryTimes() || p.second,
361 "InfJyBuilder: a CPI cap floor calibration "
362 << "instrument with the expiry time, " << t << ", was already added.");
363
364 if(p.second)
365 helpers.push_back(helper);
366
367 TLOG("InfJyBuilder: " << (p.second ?
368 "added CPICapFloor helper" :
369 "skipped CPICapFloor helper due to duplicate expiry time (" + std::to_string(t) + ")") <<
370 ": index = " << data_->index() <<
371 ", type = " << cpiCapFloor->type() <<
372 ", expiry = " << io::iso_date(maturity) <<
373 ", base CPI = " << baseCpi <<
374 ", strike = " << strikeValue <<
375 ", obs lag = " << obsLag <<
376 ", market premium = " << premium);
377 }
378
379 // Populate the expiry times array with the unique sorted expiry times.
380 expiries = Array(expiryTimes.begin(), expiryTimes.end());
381
382 DLOG("InfJyBuilder: finished building the CPI cap floor calibration basket.");
383
384 return helpers;
385}
std::vector< QuantLib::ext::shared_ptr< QuantLib::CalibrationHelper > > Helpers
std::vector< QuantLib::Date > referenceCalibrationDates() const
Create the reference calibration dates.
std::string inflationIndex() const
QuantLib::Handle< QuantLib::CPIVolatilitySurface > cpiVolatility_
#define TLOG(text)
Logging Macro (Level = Data)
Definition: log.hpp:556
Time maturity
Definition: utilities.cpp:66
Calendar calendar
Definition: utilities.cpp:441
QuantLib::Date fixingDate(const QuantLib::Date &d, const QuantLib::Period obsLag, const QuantLib::Frequency freq, bool interpolated)
bool isCPIVolSurfaceLogNormal(const boost::shared_ptr< QuantLib::CPIVolatilitySurface > &surface)
Time inflationTime(const Date &date, const boost::shared_ptr< InflationTermStructure > &inflationTs, bool indexIsInterpolated, const DayCounter &dayCounter)
Date optionMaturity(const boost::variant< Date, Period > &maturity, const QuantLib::Calendar &calendar, const QuantLib::Date &referenceDate)
Definition: utilities.cpp:447
Real cpiCapFloorStrikeValue(const QuantLib::ext::shared_ptr< BaseStrike > &strike, const QuantLib::ext::shared_ptr< ZeroInflationTermStructure > &curve, const QuantLib::Date &optionMaturityDate)
Return a cpi cap/floor strike value, the input strike can be of type absolute or atm forward.
Definition: utilities.cpp:453
QuantLib::BootstrapHelper< QuantLib::OptionletVolatilityStructure > helper
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildYoYCapFloorBasket()

Helpers buildYoYCapFloorBasket ( const CalibrationBasket cb,
std::vector< bool > &  active,
QuantLib::Array &  expiries 
) const
private

Build a YoY cap floor calibration basket.

Definition at line 387 of file infjybuilder.cpp.

387 {
388
389 DLOG("InfJyBuilder: start building the YoY cap floor calibration basket.");
390
391 // Initial checks.
392 QL_REQUIRE(yoyInflationIndex_, "InfJyBuilder: need a valid year on year inflation index "
393 << "to build a year on year cap floor calibration basket.");
394 auto yoyTs = yoyInflationIndex_->yoyInflationTermStructure();
395 QL_REQUIRE(!yoyTs.empty(), "InfJyBuilder: need a valid year on year term structure "
396 << "to build a year on year cap floor calibration basket.");
397 QL_REQUIRE(!yoyVolatility_.empty(), "InfJyBuilder: need a valid year on year volatility "
398 << "structure to build a year on year cap floor calibration basket.");
399
400 // Procedure is to create a YoY cap floor as described by each instrument in the calibration basket. We then value
401 // each of the YoY cap floor instruments using market data and an engine and pass the NPV as the market premium to
402 // helper that we create.
403
404 Helpers helpers;
405
406 // Create the engine which depends on the type of the YoY volatility and the shift.
407 QuantLib::ext::shared_ptr<PricingEngine> engine;
408 auto ovsType = yoyVolatility_->volatilityType();
409 if (ovsType == Normal)
410 engine = QuantLib::ext::make_shared<YoYInflationBachelierCapFloorEngine>(yoyInflationIndex_, yoyVolatility_, rateCurve_);
411 else if (ovsType == ShiftedLognormal && close(yoyVolatility_->displacement(), 0.0))
412 engine = QuantLib::ext::make_shared<YoYInflationBlackCapFloorEngine>(yoyInflationIndex_, yoyVolatility_, rateCurve_);
413 else if (ovsType == ShiftedLognormal)
414 engine =
415 QuantLib::ext::make_shared<YoYInflationUnitDisplacedBlackCapFloorEngine>(yoyInflationIndex_, yoyVolatility_, rateCurve_);
416 else
417 QL_FAIL("InfJyBuilder: can't create engine with yoy volatility type, " << ovsType << ".");
418
419 // YoY cap floor calibration instrument details. Assumed to equal those from the index and market structures.
420 // Some of these should possibly come from conventions. Also some variables used in the loop below.
421 Natural settlementDays = 2;
422 auto calendar = yoyInflationIndex_->fixingCalendar();
423 DayCounter dc = Thirty360(Thirty360::BondBasis);
424 auto bdc = Following;
425 auto obsLag = yoyVolatility_->observationLag();
426
427 // Avoid instruments with duplicate expiry times in the loop below
428 set<Time, CloseCmp> expiryTimes;
429
430 // Reference calibration dates if any. If they are given, we only include one calibration instrument from each
431 // period in the grid. Logic copied from other builders.
432 auto rcDates = referenceCalibrationDates();
433 auto prevRcDate = Date::minDate();
434
435 // Add calibration instruments to the helpers vector.
436 const auto& ci = cb.instruments();
437 for (Size i = 0; i < ci.size(); ++i) {
438
439 auto yoyCapFloor = QuantLib::ext::dynamic_pointer_cast<YoYCapFloor>(ci[i]);
440 QL_REQUIRE(yoyCapFloor, "InfJyBuilder: expected YoYCapFloor calibration instrument.");
441
442 /*! Get the configured strike.
443 FIXME If the strike is atm, the value will not be updated on evaluation date changes */
444 Date today = Settings::instance().evaluationDate();
445 Date maturityDate = calendar.advance(calendar.advance(today, settlementDays * Days), yoyCapFloor->tenor(), bdc);
446 Real strikeValue = yoyCapFloorStrikeValue(yoyCapFloor->strike(), *yoyTs, maturityDate);
447
448 // Build the YoY cap floor helper.
449 auto quote = QuantLib::ext::make_shared<SimpleQuote>(0.01);
450 auto helper = QuantLib::ext::make_shared<YoYCapFloorHelper>(Handle<Quote>(quote), yoyCapFloor->type(), strikeValue,
451 settlementDays, yoyCapFloor->tenor(), yoyInflationIndex_, obsLag, calendar, bdc, dc, calendar, bdc);
452
453 // Deal with reference calibration date grid stuff based on maturity of helper instrument.
454 auto helperInst = helper->yoyCapFloor();
455 auto maturity = helperInst->maturityDate();
456 auto rcDate = lower_bound(rcDates.begin(), rcDates.end(), maturity);
457 if (!(rcDate == rcDates.end() || *rcDate > prevRcDate)) {
458 active[i] = false;
459 continue;
460 }
461
462 if (rcDate != rcDates.end())
463 prevRcDate = *rcDate;
464
465 // Price the underlying helper instrument to get its fair premium.
466 helperInst->setPricingEngine(engine);
467
468 // Update the helper's market quote with the fair rate.
469 quote->setValue(dontCalibrate_ ? 0.1 : helperInst->NPV());
470
471 // Add the helper's time to expiry.
472 auto fixingDate = helperInst->lastYoYInflationCoupon()->fixingDate();
473 auto t = inflationTime(fixingDate, *yoyTs, yoyInflationIndex_->interpolated());
474
475 // if time is not positive deactivate helper
476 if (t < 0.0 || QuantLib::close_enough(t, 0.0)) {
477 active[i] = false;
478 continue;
479 }
480
481 auto p = expiryTimes.insert(t);
482 QL_REQUIRE(data_->ignoreDuplicateCalibrationExpiryTimes() || p.second,
483 "InfJyBuilder: a YoY cap floor calibration "
484 << "instrument with the expiry time, " << t << ", was already added.");
485
486 // Add the helper to the calibration helpers.
487 if(p.second)
488 helpers.push_back(helper);
489
490 TLOG("InfJyBuilder: " << (p.second ?
491 "added YoYCapFloor helper" :
492 "skipped YoYCapFloor helper due to duplicate expiry time (" + std::to_string(t) + ")") <<
493 ": index = " << data_->index() <<
494 ", type = " << yoyCapFloor->type() <<
495 ", expiry = " << io::iso_date(maturity) <<
496 ", strike = " << strikeValue <<
497 ", obs lag = " << obsLag <<
498 ", market premium = " << quote->value());
499 }
500
501 // Populate the expiry times array with the unique sorted expiry times.
502 expiries = Array(expiryTimes.begin(), expiryTimes.end());
503
504 DLOG("InfJyBuilder: finished building the YoY cap floor calibration basket.");
505
506 return helpers;
507}
QuantLib::Handle< QuantLib::YoYOptionletVolatilitySurface > yoyVolatility_
QuantLib::ext::shared_ptr< QuantLib::YoYInflationIndex > yoyInflationIndex_
Real yoyCapFloorStrikeValue(const QuantLib::ext::shared_ptr< BaseStrike > &strike, const QuantLib::ext::shared_ptr< YoYInflationTermStructure > &curve, const QuantLib::Date &optionMaturityDate)
Return a yoy cap/floor strike value, the input strike can be of type absolute or atm forward.
Definition: utilities.cpp:468
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildYoYSwapBasket()

Helpers buildYoYSwapBasket ( const CalibrationBasket cb,
std::vector< bool > &  active,
QuantLib::Array &  expiries,
bool  forRealRateReversion = false 
) const
private

Build a YoY swap calibration basket.

Definition at line 509 of file infjybuilder.cpp.

510 {
511
512 DLOG("InfJyBuilder: start building the YoY swap calibration basket.");
513
514 // Initial checks.
515 QL_REQUIRE(yoyInflationIndex_, "InfJyBuilder: need a valid year on year inflation index " <<
516 "to build a year on year swap calibration basket.");
517 auto yoyTs = yoyInflationIndex_->yoyInflationTermStructure();
518 QL_REQUIRE(!yoyTs.empty(), "InfJyBuilder: need a valid year on year term structure " <<
519 "to build a year on year swap calibration basket.");
520
521 // Procedure is to create a YoY cap floor as described by each instrument in the calibration basket. We then value
522 // each of the YoY cap floor instruments using market data and an engine and pass the NPV as the market premium to
523 // helper that we create.
524
525 Helpers helpers;
526
527 // Create the engine
528 auto engine = QuantLib::ext::make_shared<DiscountingSwapEngine>(rateCurve_);
529
530 // YoY swap calibration instrument details. Assumed to equal those from the index and market structures.
531 // Some of these should possibly come from conventions. Hardcoded some common values here.
532 // Also some variables used in the loop below.
533 Natural settlementDays = 2;
534 auto calendar = yoyInflationIndex_->fixingCalendar();
535 auto dc = Thirty360(Thirty360::BondBasis);
536 auto bdc = Following;
537 auto obsLag = yoyTs->observationLag();
538
539 // Avoid instruments with duplicate expiry times in the loop below
540 set<Time, CloseCmp> expiryTimes;
541
542 // Reference calibration dates if any. If they are given, we only include one calibration instrument from each
543 // period in the grid. Logic copied from other builders.
544 auto rcDates = referenceCalibrationDates();
545 auto prevRcDate = Date::minDate();
546
547 // Add calibration instruments to the helpers vector.
548 const auto& ci = cb.instruments();
549 for (Size i = 0; i < ci.size(); ++i) {
550
551 auto yoySwap = QuantLib::ext::dynamic_pointer_cast<YoYSwap>(ci[i]);
552 QL_REQUIRE(yoySwap, "InfJyBuilder: expected YoYSwap calibration instrument.");
553
554 // Build the YoY helper.
555 auto quote = QuantLib::ext::make_shared<SimpleQuote>(0.01);
556 auto helper = QuantLib::ext::make_shared<YoYSwapHelper>(Handle<Quote>(quote), settlementDays, yoySwap->tenor(),
557 yoyInflationIndex_, rateCurve_, obsLag, calendar, bdc, dc,
558 calendar, bdc, dc, calendar, bdc);
559
560 // Deal with reference calibration date grid stuff based on maturity of helper instrument.
561 auto helperInst = helper->yoySwap();
562 auto maturity = helperInst->maturityDate();
563 auto rcDate = lower_bound(rcDates.begin(), rcDates.end(), maturity);
564 if (!(rcDate == rcDates.end() || *rcDate > prevRcDate)) {
565 active[i] = false;
566 continue;
567 }
568
569 if (rcDate != rcDates.end())
570 prevRcDate = *rcDate;
571
572 // Price the underlying helper instrument to get its fair rate.
573 helperInst->setPricingEngine(engine);
574
575 // Update the helper's market quote with the fair rate.
576 quote->setValue(helperInst->fairRate());
577
578 // For JY calibration to YoY swaps, the parameter's time depends on whether you are calibrating the real rate
579 // reversion or the real rate volatility (probably don't want to calibrate the inflation index vol to YoY
580 // swaps as it only shows up via the drift). If you are calibrating to real rate reversion, you want the time
581 // to the numerator index fixing date on the last YoY swaplet on the YoY leg. If you are calibrating to real
582 // rate volatility, you want the time to the denominator index fixing date on the last YoY swaplet on the YoY
583 // leg. We use numerator fixing date - 1 * Years here for this. You can see this from the parameter
584 // dependencies in the YoY swaplet formula in Section 13 of the book (i.e. T vs. S).
585 // If t is not positive, we log a message and skip this helper.
586 Time t = 0.0;
587 QL_REQUIRE(!helperInst->yoyLeg().empty(), "InfJyBuilder: expected YoYSwap to have non-empty YoY leg.");
588 auto finalYoYCoupon = QuantLib::ext::dynamic_pointer_cast<YoYInflationCoupon>(helperInst->yoyLeg().back());
589 Date numFixingDate = finalYoYCoupon->fixingDate();
590 if (forRealRateReversion) {
591 t = inflationTime(numFixingDate, *yoyTs, yoyInflationIndex_->interpolated());
592 } else {
593 auto denFixingDate = numFixingDate - 1 * Years;
594 t = inflationTime(denFixingDate, *yoyTs, yoyInflationIndex_->interpolated());
595 }
596
597 if (t < 0 || close_enough(t, 0.0)) {
598 DLOG("The year on year swap with maturity tenor, " << yoySwap->tenor() << ", and date, " << maturity <<
599 ", has a non-positive parameter time, " << t << ", so skipping this as a calibration instrument.");
600 continue;
601 }
602
603 // Add the helper to the calibration helpers.
604 helpers.push_back(helper);
605
606 auto p = expiryTimes.insert(t);
607 QL_REQUIRE(p.second, "InfJyBuilder: a YoY swap calibration instrument with the expiry " <<
608 "time, " << t << ", was already added.");
609
610 TLOG("InfJyBuilder: added year on year swap helper" <<
611 ": index = " << data_->index() <<
612 ", maturity = " << io::iso_date(maturity) <<
613 ", obs lag = " << obsLag <<
614 ", market rate = " << quote->value());
615 }
616
617 // Populate the expiry times array with the unique sorted expiry times.
618 expiries = Array(expiryTimes.begin(), expiryTimes.end());
619
620 DLOG("InfJyBuilder: finished building the YoY swap calibration basket.");
621
622 return helpers;
623}
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calibrationBasket()

const CalibrationBasket & calibrationBasket ( const std::string &  parameter) const
private

Find calibration basket with parameter value equal to parameter.

Definition at line 625 of file infjybuilder.cpp.

625 {
626
627 for (const auto& cb : data_->calibrationBaskets()) {
628 if (cb.parameter() == parameter) {
629 return cb;
630 }
631 }
632
633 QL_FAIL("InfJyBuilder: unable to find calibration basket with parameter value equal to '" << parameter << "'.");
634}
+ Here is the caller graph for this function:

◆ createRealRateParam()

QuantLib::ext::shared_ptr< Lgm1fParametrization< ZeroInflationTermStructure > > createRealRateParam ( ) const
private

Create the real rate parameterisation.

Definition at line 636 of file infjybuilder.cpp.

636 {
637
638 DLOG("InfJyBuilder: start creating the real rate parameterisation.");
639
640 // Initial parameter setup as provided by the data_.
641 const ReversionParameter& rrReversion = data_->realRateReversion();
642 const VolatilityParameter& rrVolatility = data_->realRateVolatility();
643 Array rrVolatilityTimes(rrVolatility.times().begin(), rrVolatility.times().end());
644 Array rrVolatilityValues(rrVolatility.values().begin(), rrVolatility.values().end());
645 Array rrReversionTimes(rrReversion.times().begin(), rrReversion.times().end());
646 Array rrReversionValues(rrReversion.values().begin(), rrReversion.values().end());
647
648 // Perform checks and in the event of bootstrap calibration, may need to restructure the parameters.
649 setupParams(rrReversion, rrReversionTimes, rrReversionValues, rrInstExpiries_, "RealRate reversion");
650 setupParams(rrVolatility, rrVolatilityTimes, rrVolatilityValues, rrInstExpiries_, "RealRate volatility");
651
652 // Create the JY parameterization.
653 using RT = LgmData::ReversionType;
654 using VT = LgmData::VolatilityType;
655
656 // Real rate parameter constraints
657 const auto& cc = data_->calibrationConfiguration();
658 auto rrVolConstraint = cc.constraint("RealRateVolatility");
659 auto rrRevConstraint = cc.constraint("RealRateReversion");
660
661 // Create the real rate portion of the parameterization
662 using QuantLib::ZeroInflationTermStructure;
663 QuantLib::ext::shared_ptr<QuantExt::Lgm1fParametrization<ZeroInflationTermStructure>> realRateParam;
664 if (rrReversion.reversionType() == RT::HullWhite && rrVolatility.volatilityType() == VT::HullWhite) {
666 DLOG("InfJyBuilder: real rate parameterization is Lgm1fPiecewiseConstantHullWhiteAdaptor");
667 realRateParam = QuantLib::ext::make_shared<Lgm1fPiecewiseConstantHullWhiteAdaptor<ZeroInflationTermStructure>>(
668 zeroInflationIndex_->currency(), zeroInflationIndex_->zeroInflationTermStructure(), rrVolatilityTimes,
669 rrVolatilityValues, rrReversionTimes, rrReversionValues, data_->index(), rrVolConstraint, rrRevConstraint);
670 } else if (rrReversion.reversionType() == RT::HullWhite && rrVolatility.volatilityType() == VT::Hagan) {
672 DLOG("InfJyBuilder: real rate parameterization is Lgm1fPiecewiseConstantParametrization");
673 realRateParam = QuantLib::ext::make_shared<Lgm1fPiecewiseConstantParametrization<ZeroInflationTermStructure>>(
674 zeroInflationIndex_->currency(), zeroInflationIndex_->zeroInflationTermStructure(), rrVolatilityTimes,
675 rrVolatilityValues, rrReversionTimes, rrReversionValues, data_->index(), rrVolConstraint, rrRevConstraint);
676 } else if (rrReversion.reversionType() == RT::Hagan && rrVolatility.volatilityType() == VT::Hagan) {
678 DLOG("InfJyBuilder: real rate parameterization is Lgm1fPiecewiseLinearParametrization");
679 realRateParam = QuantLib::ext::make_shared<Lgm1fPiecewiseLinearParametrization<ZeroInflationTermStructure>>(
680 zeroInflationIndex_->currency(), zeroInflationIndex_->zeroInflationTermStructure(), rrVolatilityTimes,
681 rrVolatilityValues, rrReversionTimes, rrReversionValues, data_->index(), rrVolConstraint, rrRevConstraint);
682 } else {
683 QL_FAIL("InfJyBuilder: reversion type Hagan and volatility type HullWhite not supported.");
684 }
685
686 Time horizon = data_->reversionTransformation().horizon();
687 if (horizon >= 0.0) {
688 DLOG("InfJyBuilder: apply shift horizon " << horizon << " to the JY real rate parameterisation for index " <<
689 data_->index() << ".");
690 realRateParam->shift() = horizon;
691 } else {
692 WLOG("InfJyBuilder: ignoring negative horizon, " << horizon <<
693 ", passed to the JY real rate parameterisation for index " << data_->index() << ".");
694 }
695
696 Real scaling = data_->reversionTransformation().scaling();
697 if (scaling > 0.0) {
698 DLOG("InfJyBuilder: apply scaling " << scaling << " to the JY real rate parameterisation for index " <<
699 data_->index() << ".");
700 realRateParam->scaling() = scaling;
701 } else {
702 WLOG("Ignoring non-positive scaling, " << scaling <<
703 ", passed to the JY real rate parameterisation for index " << data_->index() << ".");
704 }
705
706 DLOG("InfJyBuilder: finished creating the real rate parameterisation.");
707
708 return realRateParam;
709}
void setupParams(const ModelParameter &param, QuantLib::Array &times, QuantLib::Array &values, const QuantLib::Array &expiries, const std::string &paramName) const
ReversionType
Supported mean reversion types.
Definition: lgmdata.hpp:56
VolatilityType
Supported volatility types.
Definition: lgmdata.hpp:67
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ createIndexParam()

QuantLib::ext::shared_ptr< FxBsParametrization > createIndexParam ( ) const
private

Create the inflation index parameterisation.

Definition at line 711 of file infjybuilder.cpp.

711 {
712
713 DLOG("InfJyBuilder: start creating the index parameterisation.");
714
715 // Initial parameter setup as provided by the data_.
716 const VolatilityParameter& idxVolatility = data_->indexVolatility();
717 Array idxVolatilityTimes(idxVolatility.times().begin(), idxVolatility.times().end());
718 Array idxVolatilityValues(idxVolatility.values().begin(), idxVolatility.values().end());
719
720 // Perform checks and in the event of bootstrap calibration, may need to restructure the parameters.
721 setupParams(idxVolatility, idxVolatilityTimes, idxVolatilityValues, indexInstExpiries_, "Index volatility");
722
723 // Create the index portion of the parameterization
724 QuantLib::ext::shared_ptr<QuantExt::FxBsParametrization> indexParam;
725
726 Handle<Quote> baseCpiQuote(QuantLib::ext::make_shared<SimpleQuote>(
727 dontCalibrate_ ? 100
728 : zeroInflationIndex_->fixing(zeroInflationIndex_->zeroInflationTermStructure()->baseDate())));
729
730 // Index volatility parameter constraints
731 const auto& cc = data_->calibrationConfiguration();
732 auto idxVolConstraint = cc.constraint("IndexVolatility");
733
734 if (idxVolatility.type() == ParamType::Piecewise) {
736 DLOG("InfJyBuilder: index volatility parameterization is FxBsPiecewiseConstantParametrization");
737 indexParam = QuantLib::ext::make_shared<FxBsPiecewiseConstantParametrization>(
738 zeroInflationIndex_->currency(), baseCpiQuote, idxVolatilityTimes, idxVolatilityValues, idxVolConstraint);
739 } else if (idxVolatility.type() == ParamType::Constant) {
741 DLOG("InfJyBuilder: index volatility parameterization is FxBsConstantParametrization");
742 indexParam = QuantLib::ext::make_shared<FxBsConstantParametrization>(
743 zeroInflationIndex_->currency(), baseCpiQuote, idxVolatilityValues[0]);
744 } else {
745 QL_FAIL("InfJyBuilder: index volatility parameterization needs to be Piecewise or Constant.");
746 }
747
748 DLOG("InfJyBuilder: finished creating the index parameterisation.");
749
750 return indexParam;
751}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setupParams()

void setupParams ( const ModelParameter param,
QuantLib::Array &  times,
QuantLib::Array &  values,
const QuantLib::Array &  expiries,
const std::string &  paramName 
) const
private

Perform checks and possibly adjust the times and values array depending on calibration configuration.

Definition at line 753 of file infjybuilder.cpp.

754 {
755
756 DLOG("InfJyBuilder: start setting up parameters for " << paramName);
757
758 if (param.type() == ParamType::Constant) {
759 QL_REQUIRE(param.times().size() == 0, "InfJyBuilder: parameter is constant so empty times expected");
760 QL_REQUIRE(param.values().size() == 1, "InfJyBuilder: parameter is constant so initial value array " <<
761 "should have 1 element.");
762 } else if (param.type() == ParamType::Piecewise) {
763
764 if (param.calibrate() && data_->calibrationType() == CalibrationType::Bootstrap) {
765 QL_REQUIRE(!expiries.empty(), "InfJyBuilder: calibration instrument expiries are empty.");
766 QL_REQUIRE(!values.empty(), "InfJyBuilder: expected at least one initial value.");
767 DLOG("InfJyBuilder: overriding initial times " << times << " with option calibration instrument " <<
768 "expiries " << expiries << ".");
769 times = Array(expiries.begin(), expiries.end() - 1);
770 values = Array(times.size() + 1, values[0]);
771 } else {
772 QL_REQUIRE(values.size() == times.size() + 1, "InfJyBuilder: size of values grid, " << values.size() <<
773 ", should be 1 greater than the size of the times grid, " << times.size() << ".");
774 }
775
776 } else {
777 QL_FAIL("Expected " << paramName << " parameter to be Constant or Piecewise.");
778 }
779
780 DLOG("InfJyBuilder: finished setting up parameters for " << paramName);
781}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ referenceCalibrationDates()

vector< Date > referenceCalibrationDates ( ) const
private

Create the reference calibration dates.

Definition at line 783 of file infjybuilder.cpp.

783 {
784
785 TLOG("InfJyBuilder: start building reference date grid '" << referenceCalibrationGrid_ << "'.");
786
787 vector<Date> res;
788 if (!referenceCalibrationGrid_.empty())
789 res = DateGrid(referenceCalibrationGrid_).dates();
790
791 TLOG("InfJyBuilder: finished building reference date grid.");
792
793 return res;
794}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ initialiseMarket()

void initialiseMarket ( )
private

Attempt to initialise market data members that may be needed for building calibration instruments.

Definition at line 796 of file infjybuilder.cpp.

796 {
797
798 TLOG("InfJyBuilder: start initialising market data members.");
799
800 // Try catches are not nice but Market does not have a method for checking if a structure exists so it is
801 // unfortunately necessary.
802 try {
803 cpiVolatility_ = market_->cpiInflationCapFloorVolatilitySurface(data_->index(), configuration_);
804 } catch (...) {
805 DLOG("InfJyBuilder: the market does not have a CPI cap floor volatility surface.");
806 }
807
808 try {
809 yoyInflationIndex_ = *market_->yoyInflationIndex(data_->index(), configuration_);
810 marketObserver_->registerWith(yoyInflationIndex_);
811 } catch (...) {
812 DLOG("InfJyBuilder: the market does not have a YoY inflation index.");
813 }
814
815 try {
816 yoyVolatility_ = market_->yoyCapFloorVol(data_->index(), configuration_);
817 } catch (...) {
818 DLOG("InfJyBuilder: the market does not have a YoY cap floor volatility surface.");
819 }
820
821 TLOG("InfJyBuilder: finished initialising market data members.");
822}
+ Here is the caller graph for this function:

◆ pricesChanged()

bool pricesChanged ( bool  updateCache) const
private

Returns true if the market value of any of the calibration helpers has changed. If updateCache is true, the cached prices are updated if they have changed.

Definition at line 824 of file infjybuilder.cpp.

824 {
826 return false;
827
828 // Build the calibration instruments again before checking the market price below.
829 // Don't need to do this if updateCache is true, because only called above after buildCalibrationBaskets().
830 if (!updateCache)
832
833 // Resize the cache to match the number of calibration instruments
834 auto numInsts = realRateBasket_.size() + indexBasket_.size();
835 if (priceCache_.size() != numInsts)
836 priceCache_ = vector<Real>(numInsts, Null<Real>());
837
838 // Check if any market prices have changed. Return true if they have and false if they have not.
839 // If asked to update the cached prices, via updateCache being true, update the prices, if necessary.
840 bool result = false;
841 Size ctr = 0;
842 for (const auto& ci : boost::range::join(realRateBasket_, indexBasket_)) {
843 auto mp = marketPrice(ci);
844 if (!close_enough(priceCache_[ctr], mp)) {
845 if (updateCache)
846 priceCache_[ctr] = mp;
847 result = true;
848 }
849 ctr++;
850 }
851
852 return result;
853}
std::vector< QuantLib::Real > priceCache_
Cache the prices of all of the active calibration helper instruments.
QuantLib::Real marketPrice(const QuantLib::ext::shared_ptr< QuantLib::CalibrationHelper > &helper) const
Return the market value of the given calibration helper.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ marketPrice()

Real marketPrice ( const QuantLib::ext::shared_ptr< QuantLib::CalibrationHelper > &  helper) const
private

Return the market value of the given calibration helper.

Definition at line 855 of file infjybuilder.cpp.

855 {
856
857 if (auto h = QuantLib::ext::dynamic_pointer_cast<CpiCapFloorHelper>(helper)) {
858 return h->marketValue();
859 }
860
861 if (auto h = QuantLib::ext::dynamic_pointer_cast<YoYCapFloorHelper>(helper)) {
862 return h->marketValue();
863 }
864
865 if (QuantLib::ext::shared_ptr<YoYSwapHelper> h = QuantLib::ext::dynamic_pointer_cast<YoYSwapHelper>(helper)) {
866 return h->marketRate();
867 }
868
869 QL_FAIL("InfJyBuilder: unrecognised calibration instrument for JY calibration.");
870}
+ Here is the caller graph for this function:

Member Data Documentation

◆ market_

QuantLib::ext::shared_ptr<Market> market_
private

Definition at line 73 of file infjybuilder.hpp.

◆ configuration_

std::string configuration_
private

Definition at line 74 of file infjybuilder.hpp.

◆ data_

QuantLib::ext::shared_ptr<InfJyData> data_
private

Definition at line 75 of file infjybuilder.hpp.

◆ referenceCalibrationGrid_

std::string referenceCalibrationGrid_
private

Definition at line 76 of file infjybuilder.hpp.

◆ dontCalibrate_

bool dontCalibrate_
private

Definition at line 77 of file infjybuilder.hpp.

◆ parameterization_

QuantLib::ext::shared_ptr<QuantExt::InfJyParameterization> parameterization_
private

Definition at line 79 of file infjybuilder.hpp.

◆ marketObserver_

QuantLib::ext::shared_ptr<QuantExt::MarketObserver> marketObserver_
private

Definition at line 80 of file infjybuilder.hpp.

◆ rateCurve_

Handle<YieldTermStructure> rateCurve_
private

Definition at line 83 of file infjybuilder.hpp.

◆ zeroInflationIndex_

QuantLib::ext::shared_ptr<QuantLib::ZeroInflationIndex> zeroInflationIndex_
private

Definition at line 86 of file infjybuilder.hpp.

◆ cpiVolatility_

QuantLib::Handle<QuantLib::CPIVolatilitySurface> cpiVolatility_
private

Definition at line 89 of file infjybuilder.hpp.

◆ yoyInflationIndex_

QuantLib::ext::shared_ptr<QuantLib::YoYInflationIndex> yoyInflationIndex_
private

Definition at line 90 of file infjybuilder.hpp.

◆ yoyVolatility_

QuantLib::Handle<QuantLib::YoYOptionletVolatilitySurface> yoyVolatility_
private

Definition at line 91 of file infjybuilder.hpp.

◆ forceCalibration_

bool forceCalibration_ = false
private

Definition at line 94 of file infjybuilder.hpp.

◆ realRateBasket_

Helpers realRateBasket_
mutableprivate

Calibration instruments to use for calibrating the real rate portion of the JY model. The basket is empty if we are not calibrating the real rate portion of the JY model. Depending on the calibration configuration, either the real rate reversion parameter or the real rate volatility parameter will be adjusted in order to match these instruments.

Definition at line 101 of file infjybuilder.hpp.

◆ rrInstActive_

std::vector<bool> rrInstActive_
mutableprivate

Definition at line 102 of file infjybuilder.hpp.

◆ rrInstExpiries_

QuantLib::Array rrInstExpiries_
mutableprivate

Definition at line 103 of file infjybuilder.hpp.

◆ indexBasket_

Helpers indexBasket_
mutableprivate

Calibration instruments to use for calibrating the inflation index portion of the JY model. The basket is empty if we are not calibrating the inflation index portion of the JY model.

Definition at line 108 of file infjybuilder.hpp.

◆ indexInstActive_

std::vector<bool> indexInstActive_
mutableprivate

Definition at line 109 of file infjybuilder.hpp.

◆ indexInstExpiries_

QuantLib::Array indexInstExpiries_
mutableprivate

Definition at line 110 of file infjybuilder.hpp.

◆ priceCache_

std::vector<QuantLib::Real> priceCache_
mutableprivate

Cache the prices of all of the active calibration helper instruments.

Definition at line 113 of file infjybuilder.hpp.