@@ -72,7 +72,7 @@ namespace data {
7272
7373QuantLib::ext::shared_ptr<PricingEngine>
7474EuropeanSwaptionEngineBuilder::engineImpl (const string& id, const string& key, const std::vector<Date>& dates,
75- const Date& maturity , const std::vector<Real>& strikes, const bool isAmerican,
75+ const std::vector< Date>& maturities , const std::vector<Real>& strikes, const bool isAmerican,
7676 const std::string& discountCurve, const std::string& securitySpread) {
7777 QuantLib::ext::shared_ptr<IborIndex> index;
7878 string ccyCode = tryParseIborIndex (key, index) ? index->currency ().code () : key;
@@ -88,7 +88,7 @@ EuropeanSwaptionEngineBuilder::engineImpl(const string& id, const string& key, c
8888
8989QuantLib::ext::shared_ptr<QuantExt::LGM> LGMSwaptionEngineBuilder::model (const string& id, const string& key,
9090 const std::vector<Date>& expiries,
91- const Date& maturity , const std::vector<Real>& strikes,
91+ const std::vector< Date>& maturities , const std::vector<Real>& strikes,
9292 const bool isAmerican) {
9393 QuantLib::ext::shared_ptr<IborIndex> index;
9494 std::string ccy = tryParseIborIndex (key, index) ? index->currency ().code () : key;
@@ -118,6 +118,7 @@ QuantLib::ext::shared_ptr<QuantExt::LGM> LGMSwaptionEngineBuilder::model(const s
118118 std::vector<std::pair<CalibrationType, CalibrationStrategy>> validCalPairs = {
119119 {CalibrationType::None, CalibrationStrategy::None},
120120 {CalibrationType::Bootstrap, CalibrationStrategy::CoterminalATM},
121+ {CalibrationType::Bootstrap, CalibrationStrategy::DeltaGammaAdjusted},
121122 {CalibrationType::Bootstrap, CalibrationStrategy::CoterminalDealStrike},
122123 {CalibrationType::BestFit, CalibrationStrategy::CoterminalATM},
123124 {CalibrationType::BestFit, CalibrationStrategy::CoterminalDealStrike}};
@@ -130,7 +131,7 @@ QuantLib::ext::shared_ptr<QuantExt::LGM> LGMSwaptionEngineBuilder::model(const s
130131 // compute horizon shift
131132 Real shiftHorizon = parseReal (modelParameter (" ShiftHorizon" , {}, false , " 0.5" ));
132133 Date today = Settings::instance ().evaluationDate ();
133- shiftHorizon = ActualActual (ActualActual::ISDA).yearFraction (today, maturity ) * shiftHorizon;
134+ shiftHorizon = ActualActual (ActualActual::ISDA).yearFraction (today, maturities. back () ) * shiftHorizon;
134135
135136 // Default: no calibration, constant lambda and sigma from engine configuration
136137 data->reset ();
@@ -150,18 +151,24 @@ QuantLib::ext::shared_ptr<QuantExt::LGM> LGMSwaptionEngineBuilder::model(const s
150151
151152 std::vector<Date> effExpiries;
152153 std::vector<Real> effStrikes;
154+ std::vector<Date> effMaturities;
155+
153156 if (!isAmerican) {
154157 effExpiries = expiries;
155158 effStrikes = strikes;
159+ effMaturities = maturities;
156160 } else {
157- QL_REQUIRE (expiries.size () == 2 && strikes.size () == 2 ,
161+ QL_REQUIRE (expiries.size () == 2 && strikes.size () == 2 && maturities. size () == 2 ,
158162 " LGMBermudanAmericanSwaptionEngineBuilder::model(): expected 2 expiries and strikes for exercise "
159163 " style 'American', got "
160164 << expiries.size () << " expiries and " << strikes.size () << " strikes." );
161165 // keep one calibration instrument per reference grid interval
162166 DateGrid grid (referenceCalibrationGrid);
163167 std::copy_if (grid.dates ().begin (), grid.dates ().end (), std::back_inserter (effExpiries),
164168 [&expiries](const Date& d) { return d >= expiries[0 ] && d < expiries[1 ]; });
169+
170+ effMaturities.resize (effExpiries.size (), maturities.back ());
171+
165172 // simple linear interpolation of calibration strikes between endpoints, this can be refined obviously // TODO
166173 effStrikes.resize (effExpiries.size (), Null<Real>());
167174 if (strikes[0 ] != Null<Real>() && strikes[1 ] != Null<Real>()) {
@@ -175,17 +182,20 @@ QuantLib::ext::shared_ptr<QuantExt::LGM> LGMSwaptionEngineBuilder::model(const s
175182 }
176183
177184 if (calibrationStrategy == CalibrationStrategy::CoterminalATM ||
178- calibrationStrategy == CalibrationStrategy::CoterminalDealStrike) {
185+ calibrationStrategy == CalibrationStrategy::CoterminalDealStrike ||
186+ calibrationStrategy == CalibrationStrategy::DeltaGammaAdjusted) {
179187 DLOG (" Build LgmData for co-terminal specification" );
188+
180189 vector<string> expiryDates, termDates;
181190 for (Size i = 0 ; i < effExpiries.size (); ++i) {
182191 expiryDates.push_back (to_string (effExpiries[i]));
183- termDates.push_back (to_string (maturity ));
192+ termDates.push_back (to_string (effMaturities[i] ));
184193 }
185194 data->optionExpiries () = expiryDates;
186195 data->optionTerms () = termDates;
187196 data->optionStrikes ().resize (expiryDates.size (), " ATM" );
188- if (calibrationStrategy == CalibrationStrategy::CoterminalDealStrike) {
197+ if (calibrationStrategy == CalibrationStrategy::CoterminalDealStrike ||
198+ calibrationStrategy == CalibrationStrategy::DeltaGammaAdjusted) {
189199 for (Size i = 0 ; i < effExpiries.size (); ++i) {
190200 if (effStrikes[i] != Null<Real>())
191201 data->optionStrikes ()[i] = std::to_string (effStrikes[i]);
@@ -249,11 +259,11 @@ QuantLib::ext::shared_ptr<QuantExt::LGM> LGMSwaptionEngineBuilder::model(const s
249259
250260QuantLib::ext::shared_ptr<PricingEngine>
251261LGMGridSwaptionEngineBuilder::engineImpl (const string& id, const string& key, const std::vector<Date>& expiries,
252- const Date& maturity , const std::vector<Real>& strikes, const bool isAmerican,
262+ const std::vector< Date>& maturities , const std::vector<Real>& strikes, const bool isAmerican,
253263 const std::string& discountCurve, const std::string& securitySpread) {
254264 DLOG (" Building LGM Grid Bermudan/American Swaption engine for trade " << id);
255265
256- QuantLib::ext::shared_ptr<QuantExt::LGM> lgm = model (id, key, expiries, maturity , strikes, isAmerican);
266+ QuantLib::ext::shared_ptr<QuantExt::LGM> lgm = model (id, key, expiries, maturities , strikes, isAmerican);
257267
258268 DLOG (" Get engine data" );
259269 Real sy = parseReal (engineParameter (" sy" ));
@@ -277,19 +287,19 @@ LGMGridSwaptionEngineBuilder::engineImpl(const string& id, const string& key, co
277287
278288QuantLib::ext::shared_ptr<PricingEngine>
279289LGMFDSwaptionEngineBuilder::engineImpl (const string& id, const string& key, const std::vector<Date>& expiries,
280- const Date& maturity , const std::vector<Real>& strikes, const bool isAmerican,
290+ const std::vector< Date>& maturities , const std::vector<Real>& strikes, const bool isAmerican,
281291 const std::string& discountCurve, const std::string& securitySpread) {
282292 DLOG (" Building LGM FD Bermudan/American Swaption engine for trade " << id);
283293
284- QuantLib::ext::shared_ptr<QuantExt::LGM> lgm = model (id, key, expiries, maturity , strikes, isAmerican);
294+ QuantLib::ext::shared_ptr<QuantExt::LGM> lgm = model (id, key, expiries, maturities , strikes, isAmerican);
285295
286296 DLOG (" Get engine data" );
287297 QuantLib::FdmSchemeDesc scheme = parseFdmSchemeDesc (engineParameter (" Scheme" ));
288298 Size stateGridPoints = parseInteger (engineParameter (" StateGridPoints" ));
289299 Size timeStepsPerYear = parseInteger (engineParameter (" TimeStepsPerYear" ));
290300 Real mesherEpsilon = parseReal (engineParameter (" MesherEpsilon" ));
291301
292- Real maxTime = lgm->termStructure ()->timeFromReference (maturity);
302+ Real maxTime = lgm->termStructure ()->timeFromReference (maturities. back ());
293303
294304 DLOG (" Build engine (configuration " << configuration (MarketContext::pricing) << " )" );
295305 QuantLib::ext::shared_ptr<IborIndex> index;
@@ -307,11 +317,11 @@ LGMFDSwaptionEngineBuilder::engineImpl(const string& id, const string& key, cons
307317
308318QuantLib::ext::shared_ptr<PricingEngine>
309319LGMMCSwaptionEngineBuilder::engineImpl (const string& id, const string& key, const std::vector<Date>& expiries,
310- const Date& maturity , const std::vector<Real>& strikes, const bool isAmerican,
320+ const std::vector< Date>& maturities , const std::vector<Real>& strikes, const bool isAmerican,
311321 const std::string& discountCurve, const std::string& securitySpread) {
312322 DLOG (" Building MC Bermudan/American Swaption engine for trade " << id);
313323
314- auto lgm = model (id, key, expiries, maturity , strikes, isAmerican);
324+ auto lgm = model (id, key, expiries, maturities , strikes, isAmerican);
315325
316326 // Build engine
317327 DLOG (" Build engine (configuration " << configuration (MarketContext::pricing) << " )" );
@@ -330,7 +340,7 @@ LGMMCSwaptionEngineBuilder::engineImpl(const string& id, const string& key, cons
330340
331341QuantLib::ext::shared_ptr<PricingEngine>
332342LGMAmcSwaptionEngineBuilder::engineImpl (const string& id, const string& key, const std::vector<Date>& expiries,
333- const Date& maturity , const std::vector<Real>& strikes, const bool isAmerican,
343+ const std::vector< Date>& maturities , const std::vector<Real>& strikes, const bool isAmerican,
334344 const std::string& discountCurve, const std::string& securitySpread) {
335345 QuantLib::ext::shared_ptr<IborIndex> index;
336346 std::string ccy = tryParseIborIndex (key, index) ? index->currency ().code () : key;
@@ -357,7 +367,7 @@ LGMAmcSwaptionEngineBuilder::engineImpl(const string& id, const string& key, con
357367
358368QuantLib::ext::shared_ptr<PricingEngine>
359369AmcCgSwaptionEngineBuilder::engineImpl (const string& id, const string& key, const std::vector<Date>& dates,
360- const Date& maturity , const std::vector<Real>& strikes, const bool isAmerican,
370+ const std::vector< Date>& maturities , const std::vector<Real>& strikes, const bool isAmerican,
361371 const std::string& discountCurve, const std::string& securitySpread) {
362372 QL_REQUIRE (modelCg_ != nullptr , " AmcCgSwapEngineBuilder::engineImpl: modelcg is null" );
363373 QuantLib::ext::shared_ptr<IborIndex> index;
0 commit comments