Skip to content

Commit c3c0f5b

Browse files
pcaspersjenkins
authored andcommitted
QPR-12329 fixes for inflation, freeze lgm builder early
1 parent ee9497b commit c3c0f5b

5 files changed

Lines changed: 44 additions & 37 deletions

File tree

OREData/ored/model/crossassetmodelbuilder.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,11 +246,12 @@ void CrossAssetModelBuilder::buildModel() const {
246246
}
247247
auto builder = boost::dynamic_pointer_cast<LgmBuilder>(subBuilders_[CrossAssetModel::AssetType::IR][i]);
248248
lgmBuilder.push_back(builder);
249+
if (dontCalibrate_) {
250+
builder->freeze();
251+
}
249252
if (builder->requiresRecalibration())
250253
recalibratedCurrencies.insert(builder->parametrization()->currency().code());
251254
auto parametrization = builder->parametrization();
252-
if (dontCalibrate_)
253-
builder->freeze();
254255
swaptionBaskets_[i] = builder->swaptionBasket();
255256
QL_REQUIRE(std::find(currencies.begin(), currencies.end(), parametrization->currency().code()) ==
256257
currencies.end(),
@@ -362,14 +363,12 @@ void CrossAssetModelBuilder::buildModel() const {
362363
}
363364
boost::shared_ptr<InfDkBuilder> builder =
364365
boost::dynamic_pointer_cast<InfDkBuilder>(subBuilders_[CrossAssetModel::AssetType::INF][i]);
365-
if (dontCalibrate_)
366-
builder->freeze();
367366
infParameterizations.push_back(builder->parametrization());
368367
processInfo[CrossAssetModel::AssetType::INF].emplace_back(dkData->index(), 1);
369368
} else if (auto jyData = boost::dynamic_pointer_cast<InfJyData>(imData)) {
370369
if (!buildersAreInitialized) {
371370
subBuilders_[CrossAssetModel::AssetType::INF][i] = boost::make_shared<InfJyBuilder>(
372-
market_, jyData, configurationInfCalibration_, referenceCalibrationGrid_);
371+
market_, jyData, configurationInfCalibration_, referenceCalibrationGrid_, dontCalibrate_);
373372
}
374373
auto builder = boost::dynamic_pointer_cast<InfJyBuilder>(subBuilders_[CrossAssetModel::AssetType::INF][i]);
375374
infParameterizations.push_back(builder->parameterization());
@@ -703,6 +702,7 @@ void CrossAssetModelBuilder::buildModel() const {
703702
continue;
704703
}
705704
calibrateInflation(*dkData, i, dkBuilder->optionBasket(), dkParam);
705+
dkBuilder->setCalibrationDone();
706706
} else if (auto jyData = boost::dynamic_pointer_cast<InfJyData>(imData)) {
707707
auto jyParam = boost::dynamic_pointer_cast<InfJyParameterization>(infParameterizations[i]);
708708
QL_REQUIRE(jyParam, "Expected JY model data to have given a JY parameterisation.");
@@ -716,6 +716,7 @@ void CrossAssetModelBuilder::buildModel() const {
716716
continue;
717717
}
718718
calibrateInflation(*jyData, i, jyBuilder, jyParam);
719+
jyBuilder->setCalibrationDone();
719720
} else {
720721
QL_FAIL("CrossAssetModelBuilder expects either DK or JY inflation model data.");
721722
}

OREData/ored/model/inflation/infdkbuilder.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,15 +180,18 @@ bool InfDkBuilder::requiresRecalibration() const {
180180

181181
void InfDkBuilder::performCalculations() const {
182182
if (requiresRecalibration()) {
183-
// reset market observer updated flag
184-
marketObserver_->hasUpdated(true);
185183
// build option basket
186184
buildCapFloorBasket();
187-
// update vol cache
188-
volSurfaceChanged(true);
189185
}
190186
}
191187

188+
void InfDkBuilder::setCalibrationDone() const {
189+
// reset market observer updated flag
190+
marketObserver_->hasUpdated(true);
191+
// update vol cache
192+
volSurfaceChanged(true);
193+
}
194+
192195
Date InfDkBuilder::optionMaturityDate(const Size j) const {
193196
Date today = Settings::instance().evaluationDate();
194197
const auto& ci = data_->calibrationBaskets()[0].instruments();
@@ -214,6 +217,8 @@ Real InfDkBuilder::optionStrikeValue(const Size j) const {
214217

215218
bool InfDkBuilder::volSurfaceChanged(const bool updateCache) const {
216219
bool hasUpdated = false;
220+
if(dontCalibrate_)
221+
return false;
217222

218223
boost::shared_ptr<QuantExt::CPICapFloorEngine> engine;
219224

OREData/ored/model/inflation/infdkbuilder.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ class InfDkBuilder : public QuantExt::ModelBuilder {
7171
bool requiresRecalibration() const override;
7272
//@}
7373

74+
void setCalibrationDone() const;
75+
7476
private:
7577
void performCalculations() const override;
7678
Real optionStrikeValue(const Size j) const;

OREData/ored/model/inflation/infjybuilder.cpp

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,12 @@ namespace data {
7474

7575
using Helpers = InfJyBuilder::Helpers;
7676

77-
InfJyBuilder::InfJyBuilder(
78-
const boost::shared_ptr<Market>& market,
79-
const boost::shared_ptr<InfJyData>& data,
80-
const string& configuration,
81-
const string& referenceCalibrationGrid)
82-
: market_(market),
83-
configuration_(configuration),
84-
data_(data),
85-
referenceCalibrationGrid_(referenceCalibrationGrid),
86-
marketObserver_(boost::make_shared<MarketObserver>()),
87-
zeroInflationIndex_(*market_->zeroInflationIndex(data_->index(), configuration_)) {
77+
InfJyBuilder::InfJyBuilder(const boost::shared_ptr<Market>& market, const boost::shared_ptr<InfJyData>& data,
78+
const string& configuration, const string& referenceCalibrationGrid,
79+
const bool dontCalibrate)
80+
: market_(market), configuration_(configuration), data_(data), referenceCalibrationGrid_(referenceCalibrationGrid),
81+
dontCalibrate_(dontCalibrate), marketObserver_(boost::make_shared<MarketObserver>()),
82+
zeroInflationIndex_(*market_->zeroInflationIndex(data_->index(), configuration_)) {
8883

8984
LOG("InfJyBuilder: building model for inflation index " << data_->index());
9085

@@ -130,22 +125,22 @@ Helpers InfJyBuilder::indexBasket() const {
130125
}
131126

132127
bool InfJyBuilder::requiresRecalibration() const {
133-
return (data_->realRateVolatility().calibrate() ||
134-
data_->realRateReversion().calibrate() ||
135-
data_->indexVolatility().calibrate()) &&
136-
(marketObserver_->hasUpdated(false) ||
137-
forceCalibration_ ||
138-
pricesChanged(false));
128+
return (data_->realRateVolatility().calibrate() || data_->realRateReversion().calibrate() ||
129+
data_->indexVolatility().calibrate()) &&
130+
(marketObserver_->hasUpdated(false) || forceCalibration_ || pricesChanged(false));
139131
}
140132

141133
void InfJyBuilder::performCalculations() const {
142134
if (requiresRecalibration()) {
143-
marketObserver_->hasUpdated(true);
144135
buildCalibrationBaskets();
145-
pricesChanged(true);
146136
}
147137
}
148138

139+
void InfJyBuilder::setCalibrationDone() const {
140+
marketObserver_->hasUpdated(true);
141+
pricesChanged(true);
142+
}
143+
149144
void InfJyBuilder::forceRecalculate() {
150145
forceCalibration_ = true;
151146
ModelBuilder::forceRecalculate();
@@ -291,7 +286,7 @@ Helpers InfJyBuilder::buildCpiCapFloorBasket(const CalibrationBasket& cb,
291286
// Also some variables used in the loop below.
292287
auto calendar = zeroInflationIndex_->fixingCalendar();
293288
auto baseDate = zts->baseDate();
294-
auto baseCpi = zeroInflationIndex_->fixing(baseDate);
289+
auto baseCpi = dontCalibrate_ ? 100.0 : zeroInflationIndex_->fixing(baseDate);
295290
auto bdc = cpiVolatility_->businessDayConvention();
296291
auto obsLag = cpiVolatility_->observationLag();
297292

@@ -340,7 +335,7 @@ Helpers InfJyBuilder::buildCpiCapFloorBasket(const CalibrationBasket& cb,
340335
inst->setPricingEngine(engine);
341336

342337
// Build the helper using the NPV as the premium.
343-
auto premium = inst->NPV();
338+
auto premium = dontCalibrate_ ? 0.01 : inst->NPV();
344339
auto helper = boost::make_shared<CpiCapFloorHelper>(capfloor, baseCpi, maturity, calendar, bdc, calendar, bdc,
345340
strikeValue, inflationIndex, obsLag, premium,
346341
observationInterpolation);
@@ -459,7 +454,7 @@ Helpers InfJyBuilder::buildYoYCapFloorBasket(const CalibrationBasket& cb, vector
459454
helperInst->setPricingEngine(engine);
460455

461456
// Update the helper's market quote with the fair rate.
462-
quote->setValue(helperInst->NPV());
457+
quote->setValue(dontCalibrate_ ? 0.1 : helperInst->NPV());
463458

464459
// Add the helper's time to expiry.
465460
auto fixingDate = helperInst->lastYoYInflationCoupon()->fixingDate();
@@ -710,7 +705,8 @@ boost::shared_ptr<FxBsParametrization> InfJyBuilder::createIndexParam() const {
710705
boost::shared_ptr<QuantExt::FxBsParametrization> indexParam;
711706

712707
Handle<Quote> baseCpiQuote(boost::make_shared<SimpleQuote>(
713-
zeroInflationIndex_->fixing(zeroInflationIndex_->zeroInflationTermStructure()->baseDate())));
708+
dontCalibrate_ ? 100
709+
: zeroInflationIndex_->fixing(zeroInflationIndex_->zeroInflationTermStructure()->baseDate())));
714710

715711
// Index volatility parameter constraints
716712
const auto& cc = data_->calibrationConfiguration();
@@ -807,6 +803,8 @@ void InfJyBuilder::initialiseMarket() {
807803
}
808804

809805
bool InfJyBuilder::pricesChanged(bool updateCache) const {
806+
if(dontCalibrate_)
807+
return false;
810808

811809
// Build the calibration instruments again before checking the market price below.
812810
// Don't need to do this if updateCache is true, because only called above after buildCalibrationBaskets().

OREData/ored/model/inflation/infjybuilder.hpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,9 @@ class InfJyBuilder : public QuantExt::ModelBuilder {
4747
\param configuration Market configuration to use
4848
\param referenceCalibrationGrid The reference calibration grid
4949
*/
50-
InfJyBuilder(
51-
const boost::shared_ptr<Market>& market,
52-
const boost::shared_ptr<InfJyData>& data,
53-
const std::string& configuration = Market::defaultConfiguration,
54-
const std::string& referenceCalibrationGrid = "");
50+
InfJyBuilder(const boost::shared_ptr<Market>& market, const boost::shared_ptr<InfJyData>& data,
51+
const std::string& configuration = Market::defaultConfiguration,
52+
const std::string& referenceCalibrationGrid = "", const bool donCalibrate = false);
5553

5654
using Helpers = std::vector<boost::shared_ptr<QuantLib::CalibrationHelper>>;
5755

@@ -69,11 +67,14 @@ class InfJyBuilder : public QuantExt::ModelBuilder {
6967
bool requiresRecalibration() const override;
7068
//@}
7169

70+
void setCalibrationDone() const;
71+
7272
private:
7373
boost::shared_ptr<Market> market_;
7474
std::string configuration_;
7575
boost::shared_ptr<InfJyData> data_;
7676
std::string referenceCalibrationGrid_;
77+
bool dontCalibrate_;
7778

7879
boost::shared_ptr<QuantExt::InfJyParameterization> parameterization_;
7980
boost::shared_ptr<QuantExt::MarketObserver> marketObserver_;

0 commit comments

Comments
 (0)