29#include <boost/algorithm/string.hpp>
43#include <ql/quotes/simplequote.hpp>
45#include <boost/make_shared.hpp>
56std::vector<QuantLib::Handle<QuantLib::DefaultProbabilityTermStructure>>
61 const QuantLib::ext::shared_ptr<QuantLib::SimpleQuote>&,
62 const QuantLib::Real> {
67 virtual QuantLib::ext::shared_ptr<QuantExt::DefaultLossModel>
68 lossModel(
const string& qualifier,
const vector<Real>& recoveryRates,
const Real& detachmentPoint,
69 const QuantLib::Date& trancheMaturity,
bool homogeneous) = 0;
81 return parseListOfValues<QuantLib::Period>(
engineParameter(
"calibrationIndexTerms", {},
false,
""),
89 (rt->second ==
"SensitivityDelta" || rt->second ==
"SensitivityDeltaGamma"));
93 virtual vector<string>
keyImpl(
const Currency& ccy,
bool isIndexCDS,
const vector<string>& creditCurves,
94 const QuantLib::ext::shared_ptr<QuantLib::SimpleQuote>& calibrationFactor,
95 const QuantLib::Real fixedRecovery)
override {
97 res.reserve(creditCurves.size() + 4);
98 res.emplace_back(ccy.code());
100 res.emplace_back(
"_indexCDS");
101 res.insert(res.end(), creditCurves.begin(), creditCurves.end());
102 if (!
close_enough(calibrationFactor->value(), 1.0) && calibrationFactor->value() != QuantLib::Null<Real>()) {
103 res.emplace_back(
to_string(calibrationFactor->value()));
105 if (fixedRecovery != QuantLib::Null<QuantLib::Real>()) {
106 res.emplace_back(
to_string(fixedRecovery));
116 QuantLib::ext::shared_ptr<QuantExt::DefaultLossModel>
lossModel(
const string& qualifier,
const vector<Real>& recoveryRates,
117 const Real& detachmentPoint,
118 const QuantLib::Date& trancheMaturity,
119 bool homogeneous)
override {
121 Size poolSize = recoveryRates.size();
123 Handle<QuantExt::BaseCorrelationTermStructure> bcts =
127 RelinkableHandle<Quote> correlation;
128 if (detachmentPoint < 1.0) {
129 const Date& bctsRd = bcts->referenceDate();
130 QL_REQUIRE(trancheMaturity >= bctsRd,
"Tranche maturity ("
131 << io::iso_date(trancheMaturity) <<
") must be "
132 <<
" on or after base correlation structure's reference date ("
133 << io::iso_date(bctsRd) <<
").");
134 Period ttm = (trancheMaturity - bctsRd) * Days;
136 QuantLib::ext::make_shared<QuantExt::BaseCorrelationQuote>(bcts, ttm, detachmentPoint,
true));
138 correlation.linkTo(QuantLib::ext::make_shared<SimpleQuote>(0.0));
140 DLOG(
"Base correlation quote value is " << correlation->value() <<
" at detachment point " << detachmentPoint);
148 std::vector<std::vector<Real>> recoveryProbabilities, recoveryGrids;
149 if (useStochasticRecovery) {
150 string rrProbString =
modelParameter(
"recoveryRateProbabilities");
152 vector<string> rrProbStringTokens;
153 boost::split(rrProbStringTokens, rrProbString, boost::is_any_of(
","));
154 vector<Real> rrProb = parseVectorOfValues<Real>(rrProbStringTokens, &
parseReal);
155 for (Size i = 0; i < recoveryRates.size(); ++i) {
157 recoveryProbabilities.push_back(rrProb);
159 std::vector<Real> rrGrid(3, recoveryRates[i]);
160 QL_REQUIRE(rrProb.size() == rrGrid.size(),
"recovery grid size mismatch");
161 if (rrGridString ==
"Markit2020") {
162 if (recoveryRates[i] >= 0.1 && recoveryRates[i] <= 0.55) {
163 rrGrid[0] = 2.0 * recoveryRates[i] - 0.1;
164 rrGrid[1] = recoveryRates[i];
166 LOG(
"Using recovery rate grid for entity " << i <<
": " << rrGrid[0] <<
" " << rrGrid[1] <<
" " << rrGrid[2]);
169 ALOG(
"Market recovery rate " << recoveryRates[i] <<
" for entity " << i <<
" out of range [0.1, 0.55], using constant recovery");
170 recoveryGrids.push_back(rrGrid);
172 else if (rrGridString !=
"Constant") {
173 QL_FAIL(
"recovery rate model code " << rrGridString <<
" not recognized");
178 DLOG(
"Build ExtendedGaussianConstantLossLM");
180 correlation, recoveryRates, recoveryProbabilities, recoveryGrids, LatentModelIntegrationType::GaussianQuadrature, poolSize,
181 GaussianCopulaPolicy::initTraits()));
189 homogeneous = homogeneous && homogeneousPoolWhenJustified;
190 LOG(
"Use " << (homogeneous ?
"" :
"in") <<
"homogeneous pool loss model for qualifier " << qualifier);
191 DLOG(
"useQuadrature is set to " << std::boolalpha << useQuadrature);
192 return QuantLib::ext::make_shared<QuantExt::GaussPoolLossModel>(homogeneous, gaussLM, nBuckets, gaussCopulaMax,
193 gaussCopulaMin, gaussCopulaSteps, useQuadrature,
194 useStochasticRecovery);
198 virtual QuantLib::ext::shared_ptr<PricingEngine>
199 engineImpl(
const Currency& ccy,
bool isIndexCDS,
const vector<string>& creditCurves,
200 const QuantLib::ext::shared_ptr<QuantLib::SimpleQuote>& calibrationFactor,
201 const QuantLib::Real fixedRecovery = QuantLib::Null<QuantLib::Real>())
override;
Abstract template engine builder class.
Abstract template EngineBuilder class that can cache engines and coupon pricers.
virtual vector< string > keyImpl(const Currency &ccy, bool isIndexCDS, const vector< string > &creditCurves, const QuantLib::ext::shared_ptr< QuantLib::SimpleQuote > &calibrationFactor, const QuantLib::Real fixedRecovery) override
CdoEngineBuilder(const std::string &model, const std::string &engine)
std::vector< QuantLib::Period > calibrationIndexTerms() const
virtual QuantLib::ext::shared_ptr< QuantExt::DefaultLossModel > lossModel(const string &qualifier, const vector< Real > &recoveryRates, const Real &detachmentPoint, const QuantLib::Date &trancheMaturity, bool homogeneous)=0
bool optimizedSensitivityCalculation() const
CreditPortfolioSensitivityDecomposition sensitivityDecomposition() const
bool calibrateConstituentCurve() const
QuantLib::ext::shared_ptr< Market > market_
const string & engine() const
Return the engine name.
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)
std::map< std::string, std::string > globalParameters_
QuantLib::ext::shared_ptr< QuantExt::DefaultLossModel > lossModel(const string &qualifier, const vector< Real > &recoveryRates, const Real &detachmentPoint, const QuantLib::Date &trancheMaturity, bool homogeneous) override
GaussCopulaBucketingCdoEngineBuilder()
virtual QuantLib::ext::shared_ptr< PricingEngine > engineImpl(const Currency &ccy, bool isIndexCDS, const vector< string > &creditCurves, const QuantLib::ext::shared_ptr< QuantLib::SimpleQuote > &calibrationFactor, const QuantLib::Real fixedRecovery=QuantLib::Null< QuantLib::Real >()) override
Period parsePeriod(const string &s)
Convert text to QuantLib::Period.
bool parseBool(const string &s)
Convert text to bool.
Real parseReal(const string &s)
Convert text to Real.
Integer parseInteger(const string &s)
Convert text to QuantLib::Integer.
Classes and functions for log message handling.
#define LOG(text)
Logging Macro (Level = Notice)
#define DLOG(text)
Logging Macro (Level = Debug)
#define ALOG(text)
Logging Macro (Level = Alert)
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
CreditPortfolioSensitivityDecomposition parseCreditPortfolioSensitivityDecomposition(const std::string &s)
Convert text to CreditPortfolioSensitivitiyDecomposition.
std::string to_string(const LocationInfo &l)
std::vector< Handle< DefaultProbabilityTermStructure > > buildPerformanceOptimizedDefaultCurves(const std::vector< Handle< DefaultProbabilityTermStructure > > &curves)
CreditPortfolioSensitivityDecomposition
Enumeration CreditPortfolioSensitivityDecomposition.
Serializable Credit Default Swap.
Map text representations to QuantLib/QuantExt types.
string conversion utilities