Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
flexiswap.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2018 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
20#include <qle/pricingengines/numericlgmflexiswapengine.hpp>
21
25
26#include <ql/pricingengines/swap/discountingswapengine.hpp>
27
28namespace ore {
29namespace data {
30
31QuantLib::ext::shared_ptr<QuantExt::LGM> FlexiSwapBGSLGMGridEngineBuilderBase::model(const string& id, const string& key,
32 const std::vector<Date>& expiries,
33 const Date& maturity,
34 const std::vector<Real>& strikes) {
35
36 // TODO this is the same as in LGMBermudanSwaptionEngineBuilder::model(), factor the model building out
37
38 DLOG("Get model data");
39 auto calibration = parseCalibrationType(modelParameter("Calibration"));
40 auto calibrationStrategy = parseCalibrationStrategy(modelParameter("CalibrationStrategy"));
41 std::string referenceCalibrationGrid = modelParameter("ReferenceCalibrationGrid", {}, false, "");
42 Real lambda = parseReal(modelParameter("Reversion"));
43 vector<Real> sigma = parseListOfValues<Real>(modelParameter("Volatility"), &parseReal);
44 vector<Real> sigmaTimes = parseListOfValues<Real>(modelParameter("VolatilityTimes", {}, false), &parseReal);
45 QL_REQUIRE(sigma.size() == sigmaTimes.size() + 1, "there must be n+1 volatilities (" << sigma.size()
46 << ") for n volatility times ("
47 << sigmaTimes.size() << ")");
48 Real tolerance = parseReal(modelParameter("Tolerance"));
49 auto reversionType = parseReversionType(modelParameter("ReversionType"));
50 auto volatilityType = parseVolatilityType(modelParameter("VolatilityType"));
51 bool continueOnCalibrationError = globalParameters_.count("ContinueOnCalibrationError") > 0 &&
52 parseBool(globalParameters_.at("ContinueOnCalibrationError"));
53
54 auto data = QuantLib::ext::make_shared<IrLgmData>();
55
56 // check for allowed calibration / bermudan strategy settings
57 std::vector<std::pair<CalibrationType, CalibrationStrategy>> validCalPairs = {
63
64 QL_REQUIRE(std::find(validCalPairs.begin(), validCalPairs.end(),
65 std::make_pair(calibration, calibrationStrategy)) != validCalPairs.end(),
66 "Calibration (" << calibration << ") and CalibrationStrategy (" << calibrationStrategy
67 << ") are not allowed in this combination");
68
69 // compute horizon shift
70 Real shiftHorizon = parseReal(modelParameter("ShiftHorizon", {}, false, "0.5"));
71 Date today = Settings::instance().evaluationDate();
72 shiftHorizon = ActualActual(ActualActual::ISDA).yearFraction(today, maturity) * shiftHorizon;
73
74 // Default: no calibration, constant lambda and sigma from engine configuration
75 data->reset();
76 data->qualifier() = key;
77 data->calibrateH() = false;
78 data->hParamType() = ParamType::Constant;
79 data->hValues() = {lambda};
80 data->reversionType() = reversionType;
81 data->calibrateA() = false;
82 data->aParamType() = ParamType::Piecewise;
83 data->aValues() = sigma;
84 data->aTimes() = sigmaTimes;
85 data->volatilityType() = volatilityType;
86 data->calibrationType() = calibration;
87 data->shiftHorizon() = shiftHorizon;
88
89 if (calibrationStrategy == CalibrationStrategy::CoterminalATM ||
90 calibrationStrategy == CalibrationStrategy::CoterminalDealStrike) {
91 DLOG("Build LgmData for co-terminal specification");
92 vector<string> expiryDates, termDates;
93 for (Size i = 0; i < expiries.size(); ++i) {
94 expiryDates.push_back(to_string(expiries[i]));
95 termDates.push_back(to_string(maturity));
96 }
97 data->optionExpiries() = expiryDates;
98 data->optionTerms() = termDates;
99 data->optionStrikes().resize(expiryDates.size(), "ATM");
100 if (calibrationStrategy == CalibrationStrategy::CoterminalDealStrike) {
101 for (Size i = 0; i < expiryDates.size(); ++i) {
102 if (strikes[i] != Null<Real>())
103 data->optionStrikes()[i] = std::to_string(strikes[i]);
104 }
105 }
106 if (calibration == CalibrationType::Bootstrap) {
107 DLOG("Calibrate piecewise alpha");
108 data->calibrationType() = CalibrationType::Bootstrap;
109 data->calibrateH() = false;
110 data->hParamType() = ParamType::Constant;
111 data->hValues() = {lambda};
112 data->calibrateA() = true;
113 data->aParamType() = ParamType::Piecewise;
114 data->aValues() = {sigma};
115 } else if (calibration == CalibrationType::BestFit) {
116 DLOG("Calibrate constant sigma");
117 data->calibrationType() = CalibrationType::BestFit;
118 data->calibrateH() = false;
119 data->hParamType() = ParamType::Constant;
120 data->hValues() = {lambda};
121 data->calibrateA() = true;
122 data->aParamType() = ParamType::Constant;
123 data->aValues() = {sigma};
124 } else
125 QL_FAIL("choice of calibration type invalid");
126 }
127
128 bool generateAdditionalResults = false;
129 auto p = globalParameters_.find("GenerateAdditionalResults");
130 if (p != globalParameters_.end()) {
131 generateAdditionalResults = parseBool(p->second);
132 }
133
134 // Build model
135 DLOG("Build LGM model");
136 QuantLib::ext::shared_ptr<LgmBuilder> calib = QuantLib::ext::make_shared<LgmBuilder>(
137 market_, data, configuration(MarketContext::irCalibration), tolerance, continueOnCalibrationError,
138 referenceCalibrationGrid, generateAdditionalResults, id);
139
140 // In some cases, we do not want to calibrate the model
141 QuantLib::ext::shared_ptr<QuantExt::LGM> model;
142 if (globalParameters_.count("Calibrate") == 0 || parseBool(globalParameters_.at("Calibrate"))) {
143 DLOG("Calibrate model (configuration " << configuration(MarketContext::irCalibration) << ")");
144 model = calib->model();
145 } else {
146 DLOG("Skip calibration of model based on global parameters");
147 calib->freeze();
148 model = calib->model();
149 calib->unfreeze();
150 }
151 modelBuilders_.insert(std::make_pair(id, calib));
152
153 return model;
154}
155
156QuantLib::ext::shared_ptr<PricingEngine> FlexiSwapLGMGridEngineBuilder::engineImpl(const string& id, const string& id2,
157 const string& key,
158 const std::vector<Date>& expiries,
159 const Date& maturity,
160 const std::vector<Real>& strikes) {
161 DLOG("Building LGM Grid Flexi Swap engine for trade " << id);
162
163 QuantLib::ext::shared_ptr<QuantExt::LGM> lgm = model(id, key, expiries, maturity, strikes);
164
165 DLOG("Get engine data");
166 Real sy = parseReal(engineParameter("sy"));
167 Size ny = parseInteger(engineParameter("ny"));
168 Real sx = parseReal(engineParameter("sx"));
169 Size nx = parseInteger(engineParameter("nx"));
170 QuantExt::NumericLgmFlexiSwapEngine::Method method;
171 if (engineParameter("method") == "SingleSwaptions")
172 method = QuantExt::NumericLgmFlexiSwapEngine::Method::SingleSwaptions;
173 else if (engineParameter("method") == "SwaptionArray")
174 method = QuantExt::NumericLgmFlexiSwapEngine::Method::SwaptionArray;
175 else if (engineParameter("method") == "Automatic")
176 method = QuantExt::NumericLgmFlexiSwapEngine::Method::Automatic;
177 else {
178 QL_FAIL("FlexiSwap engine parameter method (" << engineParameter("method") << ") not recognised");
179 }
180 Real singleSwaptionThreshold = parseReal(engineParameter("singleSwaptionThreshold"));
181
182 // Build engine
183 DLOG("Build engine (configuration " << configuration(MarketContext::pricing) << ")");
184 QuantLib::ext::shared_ptr<IborIndex> index;
185 string ccy = tryParseIborIndex(key, index) ? index->currency().code() : key;
186 Handle<YieldTermStructure> dscCurve = market_->discountCurve(ccy, configuration(MarketContext::pricing));
187 return QuantLib::ext::make_shared<QuantExt::NumericLgmFlexiSwapEngine>(lgm, sy, ny, sx, nx, dscCurve, method,
188 singleSwaptionThreshold);
189}
190
191QuantLib::ext::shared_ptr<PricingEngine>
192FlexiSwapBGSDiscountingEngineBuilderBase::engineImpl(const string& id, const string& id2, const string& key,
193 const std::vector<Date>& expiries, const Date& maturity,
194 const std::vector<Real>& strikes) {
195 DLOG("Building Discounting Flexi Swap engine for trade " << id);
196 DLOG("Build engine (configuration " << configuration(MarketContext::pricing) << ")");
197 QuantLib::ext::shared_ptr<IborIndex> index;
198 string ccy = tryParseIborIndex(key, index) ? index->currency().code() : key;
199 Handle<YieldTermStructure> dscCurve = market_->discountCurve(ccy, configuration(MarketContext::pricing));
200 return QuantLib::ext::make_shared<QuantLib::DiscountingSwapEngine>(dscCurve);
201}
202
203} // namespace data
204} // namespace ore
QuantLib::ext::shared_ptr< Market > market_
const string & model() const
Return the model name.
std::string modelParameter(const std::string &p, const std::vector< std::string > &qualifiers={}, const bool mandatory=true, const std::string &defaultValue="") const
std::string engineParameter(const std::string &p, const std::vector< std::string > &qualifiers={}, const bool mandatory=true, const std::string &defaultValue="") const
const string & configuration(const MarketContext &key)
Return a configuration (or the default one if key not found)
set< std::pair< string, QuantLib::ext::shared_ptr< QuantExt::ModelBuilder > > > modelBuilders_
std::map< std::string, std::string > globalParameters_
virtual QuantLib::ext::shared_ptr< QuantLib::PricingEngine > engineImpl(const std::string &id, const std::string &id2, const std::string &key, const std::vector< QuantLib::Date > &dates, const QuantLib::Date &maturity, const std::vector< QuantLib::Real > &strikes) override
Definition: flexiswap.cpp:192
virtual QuantLib::ext::shared_ptr< QuantLib::PricingEngine > engineImpl(const std::string &id, const std::string &id2, const std::string &key, const std::vector< QuantLib::Date > &dates, const QuantLib::Date &maturity, const std::vector< QuantLib::Real > &strikes) override
Definition: flexiswap.cpp:156
bool tryParseIborIndex(const string &s, QuantLib::ext::shared_ptr< IborIndex > &index)
Try to convert std::string to QuantLib::IborIndex.
bool parseBool(const string &s)
Convert text to bool.
Definition: parsers.cpp:144
Real parseReal(const string &s)
Convert text to Real.
Definition: parsers.cpp:112
Integer parseInteger(const string &s)
Convert text to QuantLib::Integer.
Definition: parsers.cpp:136
Build an lgm model.
@ data
Definition: log.hpp:77
#define DLOG(text)
Logging Macro (Level = Debug)
Definition: log.hpp:554
Time maturity
Definition: utilities.cpp:66
CalibrationType parseCalibrationType(const string &s)
Convert calibration type string into enumerated class value.
Definition: irmodeldata.cpp:47
CalibrationStrategy parseCalibrationStrategy(const string &s)
Convert calibration strategy string into enumerated class value.
Definition: irmodeldata.cpp:70
VolatilityType volatilityType(CapFloorVolatilityCurveConfig::VolatilityType type)
Imply QuantLib::VolatilityType from CapFloorVolatilityCurveConfig::VolatilityType.
std::string to_string(const LocationInfo &l)
Definition: ast.cpp:28
LgmData::ReversionType parseReversionType(const string &s)
Enum parsers.
Definition: lgmdata.cpp:62
LgmData::VolatilityType parseVolatilityType(const string &s)
Definition: lgmdata.cpp:81
Serializable Credit Default Swap.
Definition: namespaces.docs:23
Map text representations to QuantLib/QuantExt types.
vector< Real > strikes
string conversion utilities