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

Cross Asset Model Builder. More...

#include <ored/model/crossassetmodelbuilder.hpp>

+ Inheritance diagram for CrossAssetModelBuilder:
+ Collaboration diagram for CrossAssetModelBuilder:

Public Member Functions

 CrossAssetModelBuilder (const QuantLib::ext::shared_ptr< Market > &market, const QuantLib::ext::shared_ptr< CrossAssetModelData > &config, const std::string &configurationLgmCalibration=Market::defaultConfiguration, const std::string &configurationFxCalibration=Market::defaultConfiguration, const std::string &configurationEqCalibration=Market::defaultConfiguration, const std::string &configurationInfCalibration=Market::defaultConfiguration, const std::string &configurationCrCalibration=Market::defaultConfiguration, const std::string &configurationFinalModel=Market::defaultConfiguration, const bool dontCalibrate=false, const bool continueOnError=false, const std::string &referenceCalibrationGrid_="", const SalvagingAlgorithm::Type salvaging=SalvagingAlgorithm::None, const std::string &id="unknown")
 
 ~CrossAssetModelBuilder ()
 Default destructor. More...
 
Handle< QuantExt::CrossAssetModelmodel () const
 return the model More...
 
Inspectors
const std::vector< Real > & swaptionCalibrationErrors ()
 
const std::vector< Real > & fxOptionCalibrationErrors ()
 
const std::vector< Real > & eqOptionCalibrationErrors ()
 
const std::vector< Real > & inflationCalibrationErrors ()
 
const std::vector< Real > & comOptionCalibrationErrors ()
 
- Public Member Functions inherited from ModelBuilder
void recalibrate () const
 
virtual void forceRecalculate ()
 
virtual bool requiresRecalibration () const=0
 

ModelBuilder interface

std::vector< std::vector< QuantLib::ext::shared_ptr< BlackCalibrationHelper > > > swaptionBaskets_
 
std::vector< std::vector< QuantLib::ext::shared_ptr< BlackCalibrationHelper > > > fxOptionBaskets_
 
std::vector< std::vector< QuantLib::ext::shared_ptr< BlackCalibrationHelper > > > eqOptionBaskets_
 
std::vector< std::vector< QuantLib::ext::shared_ptr< BlackCalibrationHelper > > > comOptionBaskets_
 
std::vector< Array > optionExpiries_
 
std::vector< Array > swaptionMaturities_
 
std::vector< Array > fxOptionExpiries_
 
std::vector< Array > eqOptionExpiries_
 
std::vector< Array > comOptionExpiries_
 
std::vector< Real > swaptionCalibrationErrors_
 
std::vector< Real > fxOptionCalibrationErrors_
 
std::vector< Real > eqOptionCalibrationErrors_
 
std::vector< Real > inflationCalibrationErrors_
 
std::vector< Real > comOptionCalibrationErrors_
 
std::map< QuantExt::CrossAssetModel::AssetType, std::map< QuantLib::Size, QuantLib::ext::shared_ptr< QuantExt::ModelBuilder > > > subBuilders_
 Store model builders for each asset under each asset type. More...
 
Array params_
 
const QuantLib::ext::shared_ptr< ore::data::Marketmarket_
 
const QuantLib::ext::shared_ptr< CrossAssetModelDataconfig_
 
const std::string configurationLgmCalibration_
 
const std::string configurationFxCalibration_
 
const std::string configurationEqCalibration_
 
const std::string configurationInfCalibration_
 
const std::string configurationCrCalibration_
 
const std::string configurationComCalibration_
 
const std::string configurationFinalModel_
 
const bool dontCalibrate_
 
const bool continueOnError_
 
const std::string referenceCalibrationGrid_
 
const SalvagingAlgorithm::Type salvaging_
 
const std::string id_
 
QuantLib::ext::shared_ptr< OptimizationMethodoptimizationMethod_
 
EndCriteria endCriteria_
 
bool forceCalibration_ = false
 
QuantLib::ext::shared_ptr< QuantExt::MarketObservermarketObserver_
 
RelinkableHandle< QuantExt::CrossAssetModelmodel_
 
void forceRecalculate () override
 
bool requiresRecalibration () const override
 
void performCalculations () const override
 
void buildModel () const
 
void resetModelParams (const CrossAssetModel::AssetType t, const Size param, const Size index, const Size i) const
 
void copyModelParams (const CrossAssetModel::AssetType t0, const Size param0, const Size index0, const Size i0, const CrossAssetModel::AssetType t1, const Size param1, const Size index1, const Size i1, const Real mult) const
 
void calibrateInflation (const InfDkData &data, QuantLib::Size modelIdx, const std::vector< QuantLib::ext::shared_ptr< QuantLib::BlackCalibrationHelper > > &calibrationBasket, const QuantLib::ext::shared_ptr< QuantExt::InfDkParametrization > &inflationParam) const
 
void calibrateInflation (const InfJyData &data, QuantLib::Size modelIdx, const QuantLib::ext::shared_ptr< InfJyBuilder > &jyBuilder, const QuantLib::ext::shared_ptr< QuantExt::InfJyParameterization > &inflationParam) const
 
void setJyPricingEngine (QuantLib::Size modelIdx, const std::vector< QuantLib::ext::shared_ptr< QuantLib::CalibrationHelper > > &calibrationBasket, bool indexIsInterpolated) const
 

Detailed Description

Cross Asset Model Builder.

CrossAssetModelBuilder takes a market snapshot, market conventions (the latter two passed to the constructor), and a model configuration (passed to the "build" member function) to build and calibrate a cross asset model.

Definition at line 55 of file crossassetmodelbuilder.hpp.

Constructor & Destructor Documentation

◆ CrossAssetModelBuilder()

CrossAssetModelBuilder ( const QuantLib::ext::shared_ptr< Market > &  market,
const QuantLib::ext::shared_ptr< CrossAssetModelData > &  config,
const std::string &  configurationLgmCalibration = Market::defaultConfiguration,
const std::string &  configurationFxCalibration = Market::defaultConfiguration,
const std::string &  configurationEqCalibration = Market::defaultConfiguration,
const std::string &  configurationInfCalibration = Market::defaultConfiguration,
const std::string &  configurationCrCalibration = Market::defaultConfiguration,
const std::string &  configurationFinalModel = Market::defaultConfiguration,
const bool  dontCalibrate = false,
const bool  continueOnError = false,
const std::string &  referenceCalibrationGrid_ = "",
const SalvagingAlgorithm::Type  salvaging = SalvagingAlgorithm::None,
const std::string &  id = "unknown" 
)

The market for the calibration can possibly be different from the final market defining the curves attached to the marginal LGM models; for example domestic OIS curves may be used for the in currency swaption calibration while the global model is operated under FX basis consistent discounting curves relative to the collateral OIS curve.

Parameters
marketMarket object
configcam configuration
configurationLgmCalibrationMarket configuration for interest rate model calibration
configurationFxCalibrationMarket configuration for FX model calibration
configurationEqCalibrationMarket configuration for EQ model calibration
configurationInfCalibrationMarket configuration for INF model calibration
configurationCrCalibrationMarket configuration for CR model calibration
configurationFinalModelMarket configuration for simulation
dontCalibratecalibrate the model?
continueOnErrorcontinue if bootstrap error exceeds tolerance
referenceCalibrationGrid_reference calibration grid
salvagingsalvaging algorithm to apply to correlation matrix
idid of the builder

Definition at line 78 of file crossassetmodelbuilder.cpp.

85 : market_(market), config_(config), configurationLgmCalibration_(configurationLgmCalibration),
86 configurationFxCalibration_(configurationFxCalibration), configurationEqCalibration_(configurationEqCalibration),
87 configurationInfCalibration_(configurationInfCalibration),
88 configurationCrCalibration_(configurationCrCalibration),
90 dontCalibrate_(dontCalibrate), continueOnError_(continueOnError),
91 referenceCalibrationGrid_(referenceCalibrationGrid), salvaging_(salvaging), id_(id),
92 optimizationMethod_(QuantLib::ext::shared_ptr<OptimizationMethod>(new LevenbergMarquardt(1E-8, 1E-8, 1E-8))),
93 endCriteria_(EndCriteria(1000, 500, 1E-8, 1E-8, 1E-8)) {
94 buildModel();
95 // register with sub builders
96 for (auto okv : subBuilders_)
97 for (auto ikv : okv.second) {
98 registerWith(ikv.second);
99 }
100 // register market observer with correlations
101 marketObserver_ = QuantLib::ext::make_shared<MarketObserver>();
102 for (auto const& c : config->correlations())
103 marketObserver_->addObservable(c.second);
104 // reset market observer's updated flag
105 marketObserver_->hasUpdated(true);
106 // register with market observer
107 registerWith(marketObserver_);
108}
const SalvagingAlgorithm::Type salvaging_
QuantLib::ext::shared_ptr< QuantExt::MarketObserver > marketObserver_
std::map< QuantExt::CrossAssetModel::AssetType, std::map< QuantLib::Size, QuantLib::ext::shared_ptr< QuantExt::ModelBuilder > > > subBuilders_
Store model builders for each asset under each asset type.
const QuantLib::ext::shared_ptr< ore::data::Market > market_
QuantLib::ext::shared_ptr< OptimizationMethod > optimizationMethod_
const QuantLib::ext::shared_ptr< CrossAssetModelData > config_
static const string defaultConfiguration
Default configuration label.
Definition: market.hpp:296
+ Here is the call graph for this function:

◆ ~CrossAssetModelBuilder()

Default destructor.

Definition at line 90 of file crossassetmodelbuilder.hpp.

90{}

Member Function Documentation

◆ model()

Handle< QuantExt::CrossAssetModel > model ( ) const

return the model

Definition at line 110 of file crossassetmodelbuilder.cpp.

110 {
111 calculate();
112 return model_;
113}
RelinkableHandle< QuantExt::CrossAssetModel > model_

◆ swaptionCalibrationErrors()

const std::vector< Real > & swaptionCalibrationErrors ( )

Definition at line 115 of file crossassetmodelbuilder.cpp.

115 {
116 calculate();
118}

◆ fxOptionCalibrationErrors()

const std::vector< Real > & fxOptionCalibrationErrors ( )

Definition at line 119 of file crossassetmodelbuilder.cpp.

119 {
120 calculate();
122}

◆ eqOptionCalibrationErrors()

const std::vector< Real > & eqOptionCalibrationErrors ( )

Definition at line 123 of file crossassetmodelbuilder.cpp.

123 {
124 calculate();
126}

◆ inflationCalibrationErrors()

const std::vector< Real > & inflationCalibrationErrors ( )

Definition at line 127 of file crossassetmodelbuilder.cpp.

127 {
128 calculate();
130}

◆ comOptionCalibrationErrors()

const std::vector< Real > & comOptionCalibrationErrors ( )

Definition at line 131 of file crossassetmodelbuilder.cpp.

131 {
132 calculate();
134}

◆ forceRecalculate()

void forceRecalculate ( )
overridevirtual

Reimplemented from ModelBuilder.

Definition at line 792 of file crossassetmodelbuilder.cpp.

+ Here is the call graph for this function:

◆ requiresRecalibration()

bool requiresRecalibration ( ) const
overridevirtual

Implements ModelBuilder.

Definition at line 136 of file crossassetmodelbuilder.cpp.

136 {
137 for (auto okv : subBuilders_)
138 for (auto ikv : okv.second)
139 if (ikv.second->requiresRecalibration())
140 return true;
141
142 return marketObserver_->hasUpdated(false);
143}
+ Here is the caller graph for this function:

◆ performCalculations()

void performCalculations ( ) const
overrideprivate

Definition at line 145 of file crossassetmodelbuilder.cpp.

145 {
146 // if any of the sub models requires a recalibration, we rebuilt the model
147 // TODO we could do this more selectively
149 // reset market observer update flag
150 marketObserver_->hasUpdated(true);
151 buildModel();
152 }
153}
+ Here is the call graph for this function:

◆ buildModel()

void buildModel ( ) const
private

Definition at line 194 of file crossassetmodelbuilder.cpp.

194 {
195
196 LOG("Start building CrossAssetModel");
197
198 QL_REQUIRE(market_ != NULL, "CrossAssetModelBuilder: no market given");
199
200 DLOG("configurations: LgmCalibration "
201 << configurationLgmCalibration_ << ", FxCalibration " << configurationFxCalibration_ << ", EqCalibration "
202 << configurationEqCalibration_ << ", InfCalibration " << configurationInfCalibration_ << ", CrCalibration"
203 << configurationCrCalibration_ << ", ComCalibration" << configurationComCalibration_ << ", FinalModel "
205
206 if (dontCalibrate_) {
207 DLOG("Calibration of the model is disabled.");
208 }
209
210 bool buildersAreInitialized = !subBuilders_.empty();
211
212 if (!buildersAreInitialized) {
213 QL_REQUIRE(config_->irConfigs().size() > 0, "missing IR configurations");
214 QL_REQUIRE(config_->irConfigs().size() == config_->fxConfigs().size() + 1,
215 "FX configuration size " << config_->fxConfigs().size()
216 << " inconsistent with IR configuration size "
217 << config_->irConfigs().size());
218
219 swaptionBaskets_.resize(config_->irConfigs().size());
220 optionExpiries_.resize(config_->irConfigs().size());
221 swaptionMaturities_.resize(config_->irConfigs().size());
222 swaptionCalibrationErrors_.resize(config_->irConfigs().size());
223 fxOptionBaskets_.resize(config_->fxConfigs().size());
224 fxOptionExpiries_.resize(config_->fxConfigs().size());
225 fxOptionCalibrationErrors_.resize(config_->fxConfigs().size());
226 eqOptionBaskets_.resize(config_->eqConfigs().size());
227 eqOptionExpiries_.resize(config_->eqConfigs().size());
228 eqOptionCalibrationErrors_.resize(config_->eqConfigs().size());
229 inflationCalibrationErrors_.resize(config_->infConfigs().size());
230 comOptionBaskets_.resize(config_->comConfigs().size());
231 comOptionExpiries_.resize(config_->comConfigs().size());
232 comOptionCalibrationErrors_.resize(config_->comConfigs().size());
233 }
234
235 // Store information on the number of factors for each process. This is used when requesting a correlation matrix
236 // from the CorrelationMatrixBuilder below.
238
239 // Set the measure
240 IrModel::Measure measure = IrModel::Measure::LGM;
241 if (config_->measure() == "BA") {
242 measure = IrModel::Measure::BA;
243 DLOG("Setting measure to BA");
244 } else if (config_->measure() == "LGM") {
245 measure = IrModel::Measure::LGM;
246 DLOG("Setting measure to LGM");
247 } else if (config_->measure() == "") {
248 DLOG("Defaulting to LGM measure");
249 } else {
250 QL_FAIL("Measure " << config_->measure() << " not recognized");
251 }
252
253 /*******************************************************
254 * Build the IR parametrizations and calibration baskets
255 */
256 std::vector<QuantLib::ext::shared_ptr<QuantExt::Parametrization>> irParametrizations;
257 std::vector<RelinkableHandle<YieldTermStructure>> irDiscountCurves;
258 std::vector<std::string> currencies, regions, crNames, eqNames, infIndices, comNames;
259 std::vector<QuantLib::ext::shared_ptr<LgmBuilder>> lgmBuilder;
260 std::vector<QuantLib::ext::shared_ptr<HwBuilder>> hwBuilder;
261 std::vector<QuantLib::ext::shared_ptr<FxBsBuilder>> fxBuilder;
262 std::vector<QuantLib::ext::shared_ptr<EqBsBuilder>> eqBuilder;
263 std::vector<QuantLib::ext::shared_ptr<CommoditySchwartzModelBuilder>> csBuilder;
264
265 std::set<std::string> recalibratedCurrencies;
266 for (Size i = 0; i < config_->irConfigs().size(); i++) {
267 auto irConfig = config_->irConfigs()[i];
268 DLOG("IR Parametrization " << i << " qualifier " << irConfig->qualifier());
269
270 if (auto ir = QuantLib::ext::dynamic_pointer_cast<IrLgmData>(irConfig)) {
271 if (!buildersAreInitialized) {
272 subBuilders_[CrossAssetModel::AssetType::IR][i] = QuantLib::ext::make_shared<LgmBuilder>(
275 }
276 auto builder = QuantLib::ext::dynamic_pointer_cast<LgmBuilder>(subBuilders_[CrossAssetModel::AssetType::IR][i]);
277 lgmBuilder.push_back(builder);
278 if (dontCalibrate_) {
279 builder->freeze();
280 }
281 if (builder->requiresRecalibration())
282 recalibratedCurrencies.insert(builder->parametrization()->currency().code());
283 auto parametrization = builder->parametrization();
284 swaptionBaskets_[i] = builder->swaptionBasket();
285 QL_REQUIRE(std::find(currencies.begin(), currencies.end(), parametrization->currency().code()) ==
286 currencies.end(),
287 "Duplicate IR parameterization for currency "
288 << parametrization->currency().code()
289 << " - are there maybe two indices with the same currency in CrossAssetModelData?");
290 currencies.push_back(parametrization->currency().code());
291 irParametrizations.push_back(parametrization);
292 irDiscountCurves.push_back(builder->discountCurve());
293 processInfo[CrossAssetModel::AssetType::IR].emplace_back(ir->ccy(), 1);
294 } else if (auto ir = QuantLib::ext::dynamic_pointer_cast<HwModelData>(irConfig)) {
295 bool evaluateBankAccount = true; // updated in cross asset model for non-base ccys
296 bool setCalibrationInfo = false;
297 HwModel::Discretization discr = HwModel::Discretization::Euler;
298 if (!buildersAreInitialized) {
299 subBuilders_[CrossAssetModel::AssetType::IR][i] = QuantLib::ext::make_shared<HwBuilder>(
300 market_, ir, measure, discr, evaluateBankAccount, configurationLgmCalibration_,
301 config_->bootstrapTolerance(), continueOnError_, referenceCalibrationGrid_, setCalibrationInfo);
302 }
303 auto builder = QuantLib::ext::dynamic_pointer_cast<HwBuilder>(subBuilders_[CrossAssetModel::AssetType::IR][i]);
304 hwBuilder.push_back(builder);
305 if (builder->requiresRecalibration())
306 recalibratedCurrencies.insert(builder->parametrization()->currency().code());
307 auto parametrization = builder->parametrization();
308 if (dontCalibrate_)
309 builder->freeze();
310 swaptionBaskets_[i] = builder->swaptionBasket();
311 QL_REQUIRE(std::find(currencies.begin(), currencies.end(), parametrization->currency().code()) ==
312 currencies.end(),
313 "Duplicate IR parameterization for currency "
314 << parametrization->currency().code()
315 << " - are there maybe two indices with the same currency in CrossAssetModelData?");
316 currencies.push_back(parametrization->currency().code());
317 irParametrizations.push_back(parametrization);
318 irDiscountCurves.push_back(builder->discountCurve());
319 processInfo[CrossAssetModel::AssetType::IR].emplace_back(ir->ccy(), parametrization->m());
320 }
321 }
322
323 QL_REQUIRE(irParametrizations.size() > 0, "missing IR parametrizations");
324
325 QuantLib::Currency domesticCcy = irParametrizations[0]->currency();
326
327 /*******************************************************
328 * Build the FX parametrizations and calibration baskets
329 */
330 std::vector<QuantLib::ext::shared_ptr<QuantExt::FxBsParametrization>> fxParametrizations;
331 for (Size i = 0; i < config_->fxConfigs().size(); i++) {
332 DLOG("FX Parametrization " << i);
333 QuantLib::ext::shared_ptr<FxBsData> fx = config_->fxConfigs()[i];
334 QuantLib::Currency ccy = ore::data::parseCurrency(fx->foreignCcy());
335 QuantLib::Currency domCcy = ore::data::parseCurrency(fx->domesticCcy());
336
337 QL_REQUIRE(ccy.code() == irParametrizations[i + 1]->currency().code(),
338 "FX parametrization currency[" << i << "]=" << ccy << " does not match IR currency[" << i + 1
339 << "]=" << irParametrizations[i + 1]->currency().code());
340
341 QL_REQUIRE(domCcy == domesticCcy, "FX parametrization [" << i << "]=" << ccy << "/" << domCcy
342 << " does not match domestic ccy " << domesticCcy);
343
344 if (!buildersAreInitialized) {
345 subBuilders_[CrossAssetModel::AssetType::FX][i] =
346 QuantLib::ext::make_shared<FxBsBuilder>(market_, fx, configurationFxCalibration_, referenceCalibrationGrid_);
347 }
348 auto builder = QuantLib::ext::dynamic_pointer_cast<FxBsBuilder>(subBuilders_[CrossAssetModel::AssetType::FX][i]);
349 fxBuilder.push_back(builder);
350
351 QuantLib::ext::shared_ptr<QuantExt::FxBsParametrization> parametrization = builder->parametrization();
352
353 fxOptionBaskets_[i] = builder->optionBasket();
354 fxParametrizations.push_back(parametrization);
355 processInfo[CrossAssetModel::AssetType::FX].emplace_back(ccy.code() + domCcy.code(), 1);
356 }
357
358 /*******************************************************
359 * Build the EQ parametrizations and calibration baskets
360 */
361 std::vector<QuantLib::ext::shared_ptr<QuantExt::EqBsParametrization>> eqParametrizations;
362 for (Size i = 0; i < config_->eqConfigs().size(); i++) {
363 DLOG("EQ Parametrization " << i);
364 QuantLib::ext::shared_ptr<EqBsData> eq = config_->eqConfigs()[i];
365 string eqName = eq->eqName();
366 QuantLib::Currency eqCcy = ore::data::parseCurrency(eq->currency());
367 QL_REQUIRE(std::find(currencies.begin(), currencies.end(), eqCcy.code()) != currencies.end(),
368 "Currency (" << eqCcy << ") for equity " << eqName << " not covered by CrossAssetModelData");
369 if (!buildersAreInitialized) {
370 subBuilders_[CrossAssetModel::AssetType::EQ][i] = QuantLib::ext::make_shared<EqBsBuilder>(
372 }
373 QuantLib::ext::shared_ptr<EqBsBuilder> builder =
374 QuantLib::ext::dynamic_pointer_cast<EqBsBuilder>(subBuilders_[CrossAssetModel::AssetType::EQ][i]);
375 eqBuilder.push_back(builder);
376 QuantLib::ext::shared_ptr<QuantExt::EqBsParametrization> parametrization = builder->parametrization();
377 eqOptionBaskets_[i] = builder->optionBasket();
378 eqParametrizations.push_back(parametrization);
379 eqNames.push_back(eqName);
380 processInfo[CrossAssetModel::AssetType::EQ].emplace_back(eqName, 1);
381 }
382
383 /*******************************************************
384 * Build the INF parametrizations and calibration baskets
385 */
386 vector<QuantLib::ext::shared_ptr<Parametrization>> infParameterizations;
387 for (Size i = 0; i < config_->infConfigs().size(); i++) {
388 QuantLib::ext::shared_ptr<InflationModelData> imData = config_->infConfigs()[i];
389 DLOG("Inflation parameterisation (" << i << ") for index " << imData->index());
390 if (auto dkData = QuantLib::ext::dynamic_pointer_cast<InfDkData>(imData)) {
391 if (!buildersAreInitialized) {
392 subBuilders_[CrossAssetModel::AssetType::INF][i] = QuantLib::ext::make_shared<InfDkBuilder>(
394 }
395 QuantLib::ext::shared_ptr<InfDkBuilder> builder =
396 QuantLib::ext::dynamic_pointer_cast<InfDkBuilder>(subBuilders_[CrossAssetModel::AssetType::INF][i]);
397 infParameterizations.push_back(builder->parametrization());
398 processInfo[CrossAssetModel::AssetType::INF].emplace_back(dkData->index(), 1);
399 } else if (auto jyData = QuantLib::ext::dynamic_pointer_cast<InfJyData>(imData)) {
400 if (!buildersAreInitialized) {
401 // for linked real rate params we have to resize the real rate params here again, because their time grid
402 // might have been overwritten in the ir calibration step
403 if (jyData->linkRealRateParamsToNominalRateParams()) {
404 Size ccyIndex = std::distance(currencies.begin(),
405 std::find(currencies.begin(), currencies.end(), jyData->currency()));
406 VolatilityParameter rrVol = jyData->realRateVolatility();
407 ReversionParameter rrRev = jyData->realRateReversion();
408 rrVol.setCalibrate(false);
409 rrRev.setCalibrate(false);
410 auto volTimes = irParametrizations[ccyIndex]->parameterTimes(0);
411 auto volValues = irParametrizations[ccyIndex]->parameterValues(0);
412 auto revTimes = irParametrizations[ccyIndex]->parameterTimes(1);
413 auto revValues = irParametrizations[ccyIndex]->parameterValues(1);
414 rrVol.setTimes(std::vector<Real>(volTimes.begin(), volTimes.end()));
415 rrRev.setTimes(std::vector<Real>(revTimes.begin(), revTimes.end()));
416 rrVol.setValues(std::vector<Real>(volValues.begin(), volValues.end()));
417 rrRev.setValues(std::vector<Real>(revValues.begin(), revValues.end()));
418 rrVol. mult(jyData->linkedRealRateVolatilityScaling());
419 jyData->setRealRateReversion(rrRev);
420 jyData->setRealRateVolatility(rrVol);
421 }
422 subBuilders_[CrossAssetModel::AssetType::INF][i] = QuantLib::ext::make_shared<InfJyBuilder>(
424 }
425 auto builder = QuantLib::ext::dynamic_pointer_cast<InfJyBuilder>(subBuilders_[CrossAssetModel::AssetType::INF][i]);
426 infParameterizations.push_back(builder->parameterization());
427 processInfo[CrossAssetModel::AssetType::INF].emplace_back(jyData->index(), 2);
428 } else {
429 QL_FAIL("CrossAssetModelBuilder expects either DK or JY inflation model data.");
430 }
431 infIndices.push_back(imData->index());
432 }
433
434 /*******************************************************
435 * Build the CR parametrizations and calibration baskets
436 */
437 // LGM (if any)
438 std::vector<QuantLib::ext::shared_ptr<QuantExt::CrLgm1fParametrization>> crLgmParametrizations;
439 for (Size i = 0; i < config_->crLgmConfigs().size(); ++i) {
440 LOG("CR LGM Parametrization " << i);
441 QuantLib::ext::shared_ptr<CrLgmData> cr = config_->crLgmConfigs()[i];
442 string crName = cr->name();
443 if (!buildersAreInitialized) {
444 subBuilders_[CrossAssetModel::AssetType::CR][i] =
445 QuantLib::ext::make_shared<CrLgmBuilder>(market_, cr, configurationCrCalibration_);
446 }
447 auto builder = QuantLib::ext::dynamic_pointer_cast<CrLgmBuilder>(subBuilders_[CrossAssetModel::AssetType::CR][i]);
448 QuantLib::ext::shared_ptr<QuantExt::CrLgm1fParametrization> parametrization = builder->parametrization();
449 crLgmParametrizations.push_back(parametrization);
450 crNames.push_back(crName);
451 processInfo[CrossAssetModel::AssetType::CR].emplace_back(crName, 1);
452 }
453
454 // CIR (if any)
455 std::vector<QuantLib::ext::shared_ptr<QuantExt::CrCirppParametrization>> crCirParametrizations;
456 for (Size i = 0; i < config_->crCirConfigs().size(); ++i) {
457 LOG("CR CIR Parametrization " << i);
458 QuantLib::ext::shared_ptr<CrCirData> cr = config_->crCirConfigs()[i];
459 string crName = cr->name();
460 if (!buildersAreInitialized) {
461 subBuilders_[CrossAssetModel::AssetType::CR][i] =
462 QuantLib::ext::make_shared<CrCirBuilder>(market_, cr, configurationCrCalibration_);
463 }
464 auto builder = QuantLib::ext::dynamic_pointer_cast<CrCirBuilder>(subBuilders_[CrossAssetModel::AssetType::CR][i]);
465 QuantLib::ext::shared_ptr<QuantExt::CrCirppParametrization> parametrization = builder->parametrization();
466 crCirParametrizations.push_back(parametrization);
467 crNames.push_back(crName);
468 processInfo[CrossAssetModel::AssetType::CR].emplace_back(crName, 1);
469 }
470
471 /*******************************************************
472 * Build the COM parametrizations and calibration baskets
473 */
474 std::vector<QuantLib::ext::shared_ptr<QuantExt::CommoditySchwartzParametrization>> comParametrizations;
475 for (Size i = 0; i < config_->comConfigs().size(); i++) {
476 DLOG("COM Parametrization " << i);
477 QuantLib::ext::shared_ptr<CommoditySchwartzData> com = config_->comConfigs()[i];
478 string comName = com->name();
479 QuantLib::Currency comCcy = ore::data::parseCurrency(com->currency());
480 QL_REQUIRE(std::find(currencies.begin(), currencies.end(), comCcy.code()) != currencies.end(),
481 "Currency (" << comCcy << ") for commodity " << comName << " not covered by CrossAssetModelData");
482 if (!buildersAreInitialized) {
483 subBuilders_[CrossAssetModel::AssetType::COM][i] = QuantLib::ext::make_shared<CommoditySchwartzModelBuilder>(
485 }
486 auto builder = QuantLib::ext::dynamic_pointer_cast<CommoditySchwartzModelBuilder>(
487 subBuilders_[CrossAssetModel::AssetType::COM][i]);
488 if (dontCalibrate_)
489 builder->freeze();
490 csBuilder.push_back(builder);
491 QuantLib::ext::shared_ptr<QuantExt::CommoditySchwartzParametrization> parametrization = builder->parametrization();
492 comOptionBaskets_[i] = builder->optionBasket();
493 comParametrizations.push_back(parametrization);
494 comNames.push_back(comName);
495 processInfo[CrossAssetModel::AssetType::COM].emplace_back(comName, 1);
496 }
497
498 /*******************************************************
499 * Build the CrState parametrizations
500 */
501 std::vector<QuantLib::ext::shared_ptr<QuantExt::CrStateParametrization>> crStateParametrizations;
502 for (Size i = 0; i < config_->numberOfCreditStates(); i++) {
503 DLOG("CrState Parametrization " << i);
504 crStateParametrizations.push_back(QuantLib::ext::make_shared<QuantExt::CrStateParametrization>(i));
505 processInfo[CrossAssetModel::AssetType::CrState].emplace_back(std::to_string(i), 1);
506 }
507
508 std::vector<QuantLib::ext::shared_ptr<QuantExt::Parametrization>> parametrizations;
509 for (Size i = 0; i < irParametrizations.size(); i++)
510 parametrizations.push_back(irParametrizations[i]);
511 for (Size i = 0; i < fxParametrizations.size(); i++)
512 parametrizations.push_back(fxParametrizations[i]);
513 for (Size i = 0; i < eqParametrizations.size(); i++)
514 parametrizations.push_back(eqParametrizations[i]);
515 parametrizations.insert(parametrizations.end(), infParameterizations.begin(), infParameterizations.end());
516 for (Size i = 0; i < crLgmParametrizations.size(); i++)
517 parametrizations.push_back(crLgmParametrizations[i]);
518 for (Size i = 0; i < crCirParametrizations.size(); i++)
519 parametrizations.push_back(crCirParametrizations[i]);
520 for (Size i = 0; i < comParametrizations.size(); i++)
521 parametrizations.push_back(comParametrizations[i]);
522 for (Size i = 0; i < crStateParametrizations.size(); i++)
523 parametrizations.push_back(crStateParametrizations[i]);
524
525 QL_REQUIRE(fxParametrizations.size() == irParametrizations.size() - 1, "mismatch in IR/FX parametrization sizes");
526
527 /******************************
528 * Build the correlation matrix
529 */
530 DLOG("CrossAssetModelBuilder: adding correlations.");
531 CorrelationMatrixBuilder cmb;
532
533 for (auto it = config_->correlations().begin(); it != config_->correlations().end(); it++) {
534 cmb.addCorrelation(it->first.first, it->first.second, it->second);
535 }
536
537 Matrix corrMatrix = cmb.correlationMatrix(processInfo);
538
539 TLOG("CAM correlation matrix:");
540 TLOGGERSTREAM(corrMatrix);
541
542 /*****************************
543 * Build the cross asset model
544 */
545
546 model_.linkTo(QuantLib::ext::make_shared<QuantExt::CrossAssetModel>(parametrizations, corrMatrix, salvaging_, measure,
547 config_->discretization()));
548
549 /* Store initial params to ensure identical start values when recalibrating a component.
550 This is only used for fx, eq, inf, cr, com, for ir this is handled in LgmBuilder directly.
551 Therefore it does not matter that the IR parameters are calibrated at this point already. */
552
553 if (!buildersAreInitialized) {
554 params_ = model_->params();
555 }
556
557 /*************************
558 * Calibrate IR components
559 */
560
561 for (Size i = 0; i < lgmBuilder.size(); i++) {
562 DLOG("IR Calibration " << i);
563 swaptionCalibrationErrors_[i] = lgmBuilder[i]->error();
564 }
565
566 for (Size i = 0; i < hwBuilder.size(); i++) {
567 DLOG("IR Calibration " << i);
568 swaptionCalibrationErrors_[i] = hwBuilder[i]->error();
569 }
570
571 /*************************
572 * Relink LGM discount curves to curves used for FX calibration
573 */
574
575 for (Size i = 0; i < irParametrizations.size(); i++) {
576 auto p = irParametrizations[i];
577 irDiscountCurves[i].linkTo(*market_->discountCurve(p->currency().code(), configurationFxCalibration_));
578 DLOG("Relinked discounting curve for " << p->currency().code() << " for FX calibration");
579 }
580
581 /*************************
582 * Calibrate FX components
583 */
584
585 for (Size i = 0; i < fxParametrizations.size(); i++) {
586 QuantLib::ext::shared_ptr<FxBsData> fx = config_->fxConfigs()[i];
587
588 if (fx->calibrationType() == CalibrationType::None || !fx->calibrateSigma()) {
589 DLOG("FX Calibration " << i << " skipped");
590 continue;
591 }
592
593 if (!fxBuilder[i]->requiresRecalibration() &&
594 recalibratedCurrencies.find(fx->foreignCcy()) == recalibratedCurrencies.end() &&
595 recalibratedCurrencies.find(fx->domesticCcy()) == recalibratedCurrencies.end()) {
596 DLOG("FX Calibration "
597 << i << " skipped, since neither fx builder nor ir models in dom / for ccy were recalibrated.");
598 continue;
599 }
600
601 DLOG("FX Calibration " << i);
602
603 // attach pricing engines to helpers
604 QuantLib::ext::shared_ptr<QuantExt::AnalyticCcLgmFxOptionEngine> engine =
605 QuantLib::ext::make_shared<QuantExt::AnalyticCcLgmFxOptionEngine>(*model_, i);
606 // enable caching for calibration
607 // TODO: review this
608 engine->cache(true);
609 for (Size j = 0; j < fxOptionBaskets_[i].size(); j++)
610 fxOptionBaskets_[i][j]->setPricingEngine(engine);
611
612 if (!dontCalibrate_) {
613
614 // reset to initial params to ensure identical calibration outcomes for identical baskets
615 resetModelParams(CrossAssetModel::AssetType::FX, 0, i, Null<Size>());
616
617 if (fx->calibrationType() == CalibrationType::Bootstrap && fx->sigmaParamType() == ParamType::Piecewise)
618 model_->calibrateBsVolatilitiesIterative(CrossAssetModel::AssetType::FX, i, fxOptionBaskets_[i],
620 else
621 model_->calibrateBsVolatilitiesGlobal(CrossAssetModel::AssetType::FX, i, fxOptionBaskets_[i],
623
624 DLOG("FX " << fx->foreignCcy() << " calibration errors:");
626 if (fx->calibrationType() == CalibrationType::Bootstrap) {
627 if (fabs(fxOptionCalibrationErrors_[i]) < config_->bootstrapTolerance()) {
628 TLOGGERSTREAM("Calibration details:");
630 getCalibrationDetails(fxOptionBaskets_[i], fxParametrizations[i], irParametrizations[0]));
632 } else {
633 std::string exceptionMessage = "FX BS " + std::to_string(i) + " calibration error " +
634 std::to_string(fxOptionCalibrationErrors_[i]) +
635 " exceeds tolerance " +
636 std::to_string(config_->bootstrapTolerance());
637 StructuredModelWarningMessage("Failed to calibrate FX BS Model", exceptionMessage, id_).log();
638 WLOGGERSTREAM("Calibration details:");
640 getCalibrationDetails(fxOptionBaskets_[i], fxParametrizations[i], irParametrizations[0]));
642 if (!continueOnError_)
643 QL_FAIL(exceptionMessage);
644 }
645 }
646 }
647 fxBuilder[i]->setCalibrationDone();
648 }
649
650 /*************************
651 * Relink LGM discount curves to curves used for EQ calibration
652 */
653
654 for (Size i = 0; i < irParametrizations.size(); i++) {
655 auto p = irParametrizations[i];
656 irDiscountCurves[i].linkTo(*market_->discountCurve(p->currency().code(), configurationEqCalibration_));
657 DLOG("Relinked discounting curve for " << p->currency().code() << " for EQ calibration");
658 }
659
660 /*************************
661 * Calibrate EQ components
662 */
663
664 for (Size i = 0; i < eqParametrizations.size(); i++) {
665 QuantLib::ext::shared_ptr<EqBsData> eq = config_->eqConfigs()[i];
666 if (!eq->calibrateSigma()) {
667 DLOG("EQ Calibration " << i << " skipped");
668 continue;
669 }
670
671 if (!eqBuilder[i]->requiresRecalibration() &&
672 recalibratedCurrencies.find(eq->currency()) == recalibratedCurrencies.end()) {
673 DLOG("EQ Calibration " << i
674 << " skipped, since neither eq builder nor ir model in eq ccy were recalibrated.");
675 continue;
676 }
677
678 DLOG("EQ Calibration " << i);
679 // attach pricing engines to helpers
680 Currency eqCcy = eqParametrizations[i]->currency();
681 Size eqCcyIdx = model_->ccyIndex(eqCcy);
682 QuantLib::ext::shared_ptr<QuantExt::AnalyticXAssetLgmEquityOptionEngine> engine =
683 QuantLib::ext::make_shared<QuantExt::AnalyticXAssetLgmEquityOptionEngine>(*model_, i, eqCcyIdx);
684 for (Size j = 0; j < eqOptionBaskets_[i].size(); j++)
685 eqOptionBaskets_[i][j]->setPricingEngine(engine);
686
687 if (!dontCalibrate_) {
688
689 // reset to initial params to ensure identical calibration outcomes for identical baskets
690 resetModelParams(CrossAssetModel::AssetType::EQ, 0, i, Null<Size>());
691
692 if (eq->calibrationType() == CalibrationType::Bootstrap && eq->sigmaParamType() == ParamType::Piecewise)
693 model_->calibrateBsVolatilitiesIterative(CrossAssetModel::AssetType::EQ, i, eqOptionBaskets_[i],
695 else
696 model_->calibrateBsVolatilitiesGlobal(CrossAssetModel::AssetType::EQ, i, eqOptionBaskets_[i],
698 DLOG("EQ " << eq->eqName() << " calibration errors:");
700 if (eq->calibrationType() == CalibrationType::Bootstrap) {
701 if (fabs(eqOptionCalibrationErrors_[i]) < config_->bootstrapTolerance()) {
702 TLOGGERSTREAM("Calibration details:");
704 getCalibrationDetails(eqOptionBaskets_[i], eqParametrizations[i], irParametrizations[0]));
706 } else {
707 std::string exceptionMessage = "EQ BS " + std::to_string(i) + " calibration error " +
708 std::to_string(eqOptionCalibrationErrors_[i]) +
709 " exceeds tolerance " +
710 std::to_string(config_->bootstrapTolerance());
711 StructuredModelWarningMessage("Failed to calibrate EQ BS Model", exceptionMessage, id_).log();
712 WLOGGERSTREAM("Calibration details:");
714 getCalibrationDetails(eqOptionBaskets_[i], eqParametrizations[i], irParametrizations[0]));
716 if (!continueOnError_)
717 QL_FAIL(exceptionMessage);
718 }
719 }
720 }
721 eqBuilder[i]->setCalibrationDone();
722 }
723
724 /*************************
725 * Calibrate COM components
726 */
727
728 for (Size i = 0; i < csBuilder.size(); i++) {
729 DLOG("COM Calibration " << i);
730 comOptionCalibrationErrors_[i] = csBuilder[i]->error();
731 }
732
733 /*************************
734 * Relink LGM discount curves to curves used for INF calibration
735 */
736
737 for (Size i = 0; i < irParametrizations.size(); i++) {
738 auto p = irParametrizations[i];
739 irDiscountCurves[i].linkTo(*market_->discountCurve(p->currency().code(), configurationInfCalibration_));
740 DLOG("Relinked discounting curve for " << p->currency().code() << " for INF calibration");
741 }
742
743 // Calibrate INF components
744 for (Size i = 0; i < infParameterizations.size(); i++) {
745 QuantLib::ext::shared_ptr<InflationModelData> imData = config_->infConfigs()[i];
746 if (auto dkData = QuantLib::ext::dynamic_pointer_cast<InfDkData>(imData)) {
747 auto dkParam = QuantLib::ext::dynamic_pointer_cast<InfDkParametrization>(infParameterizations[i]);
748 QL_REQUIRE(dkParam, "Expected DK model data to have given a DK parameterisation.");
749 const auto& builder = subBuilders_.at(CrossAssetModel::AssetType::INF).at(i);
750 const auto& dkBuilder = QuantLib::ext::dynamic_pointer_cast<InfDkBuilder>(builder);
751 if (!dkBuilder->requiresRecalibration() &&
752 recalibratedCurrencies.find(infParameterizations[i]->currency().code()) ==
753 recalibratedCurrencies.end()) {
754 DLOG("Skipping inf dk calibration "
755 << i << " since neither inf builder nor ir model in inf ccy were recalibrated.");
756 continue;
757 }
758 calibrateInflation(*dkData, i, dkBuilder->optionBasket(), dkParam);
759 dkBuilder->setCalibrationDone();
760 } else if (auto jyData = QuantLib::ext::dynamic_pointer_cast<InfJyData>(imData)) {
761 auto jyParam = QuantLib::ext::dynamic_pointer_cast<InfJyParameterization>(infParameterizations[i]);
762 QL_REQUIRE(jyParam, "Expected JY model data to have given a JY parameterisation.");
763 const auto& builder = subBuilders_.at(CrossAssetModel::AssetType::INF).at(i);
764 const auto& jyBuilder = QuantLib::ext::dynamic_pointer_cast<InfJyBuilder>(builder);
765 if (!jyBuilder->requiresRecalibration() &&
766 recalibratedCurrencies.find(infParameterizations[i]->currency().code()) ==
767 recalibratedCurrencies.end()) {
768 DLOG("Skipping inf jy calibration "
769 << i << " since neither inf builder nor ir model in inf ccy were recalibrated.");
770 continue;
771 }
772 calibrateInflation(*jyData, i, jyBuilder, jyParam);
773 jyBuilder->setCalibrationDone();
774 } else {
775 QL_FAIL("CrossAssetModelBuilder expects either DK or JY inflation model data.");
776 }
777 }
778
779 /*************************
780 * Relink LGM discount curves to final model curves
781 */
782
783 for (Size i = 0; i < irParametrizations.size(); i++) {
784 auto p = irParametrizations[i];
785 irDiscountCurves[i].linkTo(*market_->discountCurve(p->currency().code(), configurationFinalModel_));
786 DLOG("Relinked discounting curve for " << p->currency().code() << " as final model curves");
787 }
788
789 DLOG("Building CrossAssetModel done");
790}
std::map< QuantExt::CrossAssetModel::AssetType, std::vector< std::pair< std::string, QuantLib::Size > > > ProcessInfo
std::vector< std::vector< QuantLib::ext::shared_ptr< BlackCalibrationHelper > > > swaptionBaskets_
void calibrateInflation(const InfDkData &data, QuantLib::Size modelIdx, const std::vector< QuantLib::ext::shared_ptr< QuantLib::BlackCalibrationHelper > > &calibrationBasket, const QuantLib::ext::shared_ptr< QuantExt::InfDkParametrization > &inflationParam) const
std::vector< std::vector< QuantLib::ext::shared_ptr< BlackCalibrationHelper > > > comOptionBaskets_
std::vector< std::vector< QuantLib::ext::shared_ptr< BlackCalibrationHelper > > > eqOptionBaskets_
std::vector< std::vector< QuantLib::ext::shared_ptr< BlackCalibrationHelper > > > fxOptionBaskets_
void resetModelParams(const CrossAssetModel::AssetType t, const Size param, const Size index, const Size i) const
Currency parseCurrency(const string &s)
Convert text to QuantLib::Currency.
Definition: parsers.cpp:290
#define WLOGGERSTREAM(text)
Definition: log.hpp:630
#define LOG(text)
Logging Macro (Level = Notice)
Definition: log.hpp:552
#define DLOG(text)
Logging Macro (Level = Debug)
Definition: log.hpp:554
#define TLOGGERSTREAM(text)
Definition: log.hpp:633
#define TLOG(text)
Logging Macro (Level = Data)
Definition: log.hpp:556
Real getCalibrationError(const std::vector< QuantLib::ext::shared_ptr< Helper > > &basket)
Definition: utilities.hpp:47
Size size(const ValueType &v)
Definition: value.cpp:145
std::string getCalibrationDetails(LgmCalibrationInfo &info, const std::vector< QuantLib::ext::shared_ptr< BlackCalibrationHelper > > &basket, const QuantLib::ext::shared_ptr< IrLgm1fParametrization > &parametrization)
Definition: utilities.cpp:125
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ resetModelParams()

void resetModelParams ( const CrossAssetModel::AssetType  t,
const Size  param,
const Size  index,
const Size  i 
) const
private

Definition at line 155 of file crossassetmodelbuilder.cpp.

156 {
157 auto mp = model_->MoveParameter(t, param, index, i);
158 for (Size idx = 0; idx < mp.size(); ++idx) {
159 if (!mp[idx]) {
160 model_->setParam(idx, params_[idx]);
161 }
162 }
163}
+ Here is the caller graph for this function:

◆ copyModelParams()

void copyModelParams ( const CrossAssetModel::AssetType  t0,
const Size  param0,
const Size  index0,
const Size  i0,
const CrossAssetModel::AssetType  t1,
const Size  param1,
const Size  index1,
const Size  i1,
const Real  mult 
) const
private

Definition at line 165 of file crossassetmodelbuilder.cpp.

167 {
168 auto mp0 = model_->MoveParameter(t0, param0, index0, i0);
169 auto mp1 = model_->MoveParameter(t1, param1, index1, i1);
170 auto s0 = 0, s1 = 0;
171 for (Size i = 0; i < mp0.size(); ++i)
172 if (!mp0[i])
173 s0++;
174 for (Size i = 0; i < mp1.size(); ++i)
175 if (!mp1[i])
176 s1++;
177 QL_REQUIRE(s0 == s1, "CrossAssetModelBuilder::copyModelParams(): source range size ("
178 << s0 << ") does not match target range size (" << s1 << ") when copying (" << t0 << ","
179 << param0 << "," << index0 << "," << i0 << ") -> (" << t1 << "," << param1 << "," << index1
180 << "," << i1 << ")");
181 std::vector<Real> sourceValues(s0);
182 for (Size idx0 = 0, count = 0; idx0 < mp0.size(); ++idx0) {
183 if (!mp0[idx0]) {
184 sourceValues[count++] = params_[idx0];
185 }
186 }
187 for (Size idx1 = 0, count = 0; idx1 < mp1.size(); ++idx1) {
188 if (!mp1[idx1]) {
189 model_->setParam(idx1, sourceValues[count++] * mult);
190 }
191 }
192}
std::size_t count

◆ calibrateInflation() [1/2]

void calibrateInflation ( const InfDkData data,
QuantLib::Size  modelIdx,
const std::vector< QuantLib::ext::shared_ptr< QuantLib::BlackCalibrationHelper > > &  calibrationBasket,
const QuantLib::ext::shared_ptr< QuantExt::InfDkParametrization > &  inflationParam 
) const
private
+ Here is the caller graph for this function:

◆ calibrateInflation() [2/2]

void calibrateInflation ( const InfJyData data,
QuantLib::Size  modelIdx,
const QuantLib::ext::shared_ptr< InfJyBuilder > &  jyBuilder,
const QuantLib::ext::shared_ptr< QuantExt::InfJyParameterization > &  inflationParam 
) const
private

◆ setJyPricingEngine()

void setJyPricingEngine ( QuantLib::Size  modelIdx,
const std::vector< QuantLib::ext::shared_ptr< QuantLib::CalibrationHelper > > &  calibrationBasket,
bool  indexIsInterpolated 
) const
private

Definition at line 1036 of file crossassetmodelbuilder.cpp.

1038 {
1039
1040 DLOG("Start setting pricing engines on JY calibration instruments.");
1041
1042 // JY supports three types of calibration helpers. Generally, all of the calibration instruments in a basket will
1043 // be of the same type but we support all three here.
1044 QuantLib::ext::shared_ptr<PricingEngine> cpiCapFloorEngine;
1045 QuantLib::ext::shared_ptr<PricingEngine> yoyCapFloorEngine;
1046 QuantLib::ext::shared_ptr<PricingEngine> yoySwapEngine;
1047 QuantLib::ext::shared_ptr<InflationCouponPricer> yoyCouponPricer;
1048
1049 for (auto& ci : calibrationBasket) {
1050
1051 if (QuantLib::ext::shared_ptr<CpiCapFloorHelper> h = QuantLib::ext::dynamic_pointer_cast<CpiCapFloorHelper>(ci)) {
1052 if (!cpiCapFloorEngine) {
1053 cpiCapFloorEngine = QuantLib::ext::make_shared<AnalyticJyCpiCapFloorEngine>(*model_, modelIdx);
1054 }
1055 h->setPricingEngine(cpiCapFloorEngine);
1056 continue;
1057 }
1058
1059 if (QuantLib::ext::shared_ptr<YoYCapFloorHelper> h = QuantLib::ext::dynamic_pointer_cast<YoYCapFloorHelper>(ci)) {
1060 if (!yoyCapFloorEngine) {
1061 yoyCapFloorEngine =
1062 QuantLib::ext::make_shared<AnalyticJyYoYCapFloorEngine>(*model_, modelIdx, indexIsInterpolated);
1063 }
1064 h->setPricingEngine(yoyCapFloorEngine);
1065 continue;
1066 }
1067
1068 if (QuantLib::ext::shared_ptr<YoYSwapHelper> h = QuantLib::ext::dynamic_pointer_cast<YoYSwapHelper>(ci)) {
1069 // Here we need to attach the coupon pricer to all the YoY coupons and then the generic discounting swap
1070 // engine to the helper.
1071 if (!yoyCouponPricer) {
1072 yoyCouponPricer = QuantLib::ext::make_shared<JyYoYInflationCouponPricer>(*model_, modelIdx);
1073
1074 Size irIdx = model_->ccyIndex(model_->infjy(modelIdx)->currency());
1075 auto yts = model_->irlgm1f(irIdx)->termStructure();
1076 yoySwapEngine = QuantLib::ext::make_shared<DiscountingSwapEngine>(yts);
1077 }
1078
1079 const auto& yoyLeg = h->yoySwap()->yoyLeg();
1080 for (const auto& cf : yoyLeg) {
1081 if (auto yoyCoupon = QuantLib::ext::dynamic_pointer_cast<YoYInflationCoupon>(cf))
1082 yoyCoupon->setPricer(yoyCouponPricer);
1083 }
1084
1085 h->setPricingEngine(yoySwapEngine);
1086 continue;
1087 }
1088
1089 QL_FAIL("Only CPI cap floors, YoY cap floors and YoY swaps are supported for JY calibration.");
1090 }
1091
1092 DLOG("Finished setting pricing engines on JY calibration instruments.");
1093}

Member Data Documentation

◆ swaptionBaskets_

std::vector<std::vector<QuantLib::ext::shared_ptr<BlackCalibrationHelper> > > swaptionBaskets_
mutableprivate

Definition at line 118 of file crossassetmodelbuilder.hpp.

◆ fxOptionBaskets_

std::vector<std::vector<QuantLib::ext::shared_ptr<BlackCalibrationHelper> > > fxOptionBaskets_
mutableprivate

Definition at line 119 of file crossassetmodelbuilder.hpp.

◆ eqOptionBaskets_

std::vector<std::vector<QuantLib::ext::shared_ptr<BlackCalibrationHelper> > > eqOptionBaskets_
mutableprivate

Definition at line 120 of file crossassetmodelbuilder.hpp.

◆ comOptionBaskets_

std::vector<std::vector<QuantLib::ext::shared_ptr<BlackCalibrationHelper> > > comOptionBaskets_
mutableprivate

Definition at line 121 of file crossassetmodelbuilder.hpp.

◆ optionExpiries_

std::vector<Array> optionExpiries_
mutableprivate

Definition at line 122 of file crossassetmodelbuilder.hpp.

◆ swaptionMaturities_

std::vector<Array> swaptionMaturities_
mutableprivate

Definition at line 123 of file crossassetmodelbuilder.hpp.

◆ fxOptionExpiries_

std::vector<Array> fxOptionExpiries_
mutableprivate

Definition at line 124 of file crossassetmodelbuilder.hpp.

◆ eqOptionExpiries_

std::vector<Array> eqOptionExpiries_
mutableprivate

Definition at line 125 of file crossassetmodelbuilder.hpp.

◆ comOptionExpiries_

std::vector<Array> comOptionExpiries_
mutableprivate

Definition at line 126 of file crossassetmodelbuilder.hpp.

◆ swaptionCalibrationErrors_

std::vector<Real> swaptionCalibrationErrors_
mutableprivate

Definition at line 127 of file crossassetmodelbuilder.hpp.

◆ fxOptionCalibrationErrors_

std::vector<Real> fxOptionCalibrationErrors_
mutableprivate

Definition at line 128 of file crossassetmodelbuilder.hpp.

◆ eqOptionCalibrationErrors_

std::vector<Real> eqOptionCalibrationErrors_
mutableprivate

Definition at line 129 of file crossassetmodelbuilder.hpp.

◆ inflationCalibrationErrors_

std::vector<Real> inflationCalibrationErrors_
mutableprivate

Definition at line 130 of file crossassetmodelbuilder.hpp.

◆ comOptionCalibrationErrors_

std::vector<Real> comOptionCalibrationErrors_
mutableprivate

Definition at line 131 of file crossassetmodelbuilder.hpp.

◆ subBuilders_

std::map<QuantExt::CrossAssetModel::AssetType, std::map<QuantLib::Size, QuantLib::ext::shared_ptr<QuantExt::ModelBuilder> > > subBuilders_
mutableprivate

Store model builders for each asset under each asset type.

Definition at line 136 of file crossassetmodelbuilder.hpp.

◆ params_

Array params_
mutableprivate

Definition at line 137 of file crossassetmodelbuilder.hpp.

◆ market_

const QuantLib::ext::shared_ptr<ore::data::Market> market_
private

Definition at line 139 of file crossassetmodelbuilder.hpp.

◆ config_

const QuantLib::ext::shared_ptr<CrossAssetModelData> config_
private

Definition at line 140 of file crossassetmodelbuilder.hpp.

◆ configurationLgmCalibration_

const std::string configurationLgmCalibration_
private

Definition at line 141 of file crossassetmodelbuilder.hpp.

◆ configurationFxCalibration_

const std::string configurationFxCalibration_
private

Definition at line 141 of file crossassetmodelbuilder.hpp.

◆ configurationEqCalibration_

const std::string configurationEqCalibration_
private

Definition at line 141 of file crossassetmodelbuilder.hpp.

◆ configurationInfCalibration_

const std::string configurationInfCalibration_
private

Definition at line 142 of file crossassetmodelbuilder.hpp.

◆ configurationCrCalibration_

const std::string configurationCrCalibration_
private

Definition at line 142 of file crossassetmodelbuilder.hpp.

◆ configurationComCalibration_

const std::string configurationComCalibration_
private

Definition at line 142 of file crossassetmodelbuilder.hpp.

◆ configurationFinalModel_

const std::string configurationFinalModel_
private

Definition at line 142 of file crossassetmodelbuilder.hpp.

◆ dontCalibrate_

const bool dontCalibrate_
private

Definition at line 143 of file crossassetmodelbuilder.hpp.

◆ continueOnError_

const bool continueOnError_
private

Definition at line 144 of file crossassetmodelbuilder.hpp.

◆ referenceCalibrationGrid_

const std::string referenceCalibrationGrid_
private

Definition at line 145 of file crossassetmodelbuilder.hpp.

◆ salvaging_

const SalvagingAlgorithm::Type salvaging_
private

Definition at line 146 of file crossassetmodelbuilder.hpp.

◆ id_

const std::string id_
private

Definition at line 147 of file crossassetmodelbuilder.hpp.

◆ optimizationMethod_

QuantLib::ext::shared_ptr<OptimizationMethod> optimizationMethod_
private

Definition at line 150 of file crossassetmodelbuilder.hpp.

◆ endCriteria_

EndCriteria endCriteria_
private

Definition at line 151 of file crossassetmodelbuilder.hpp.

◆ forceCalibration_

bool forceCalibration_ = false
private

Definition at line 154 of file crossassetmodelbuilder.hpp.

◆ marketObserver_

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

Definition at line 157 of file crossassetmodelbuilder.hpp.

◆ model_

RelinkableHandle<QuantExt::CrossAssetModel> model_
mutableprivate

Definition at line 160 of file crossassetmodelbuilder.hpp.