Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
simmconfigurationbase.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
21
22#include <boost/math/distributions/normal.hpp>
23#include <boost/optional/optional_io.hpp>
26#include <ql/errors.hpp>
27#include <ql/math/comparison.hpp>
28#include <ql/math/matrix.hpp>
29#include <ql/math/matrixutilities/symmetricschurdecomposition.hpp>
30
31using namespace QuantLib;
32
35using QuantLib::Integer;
36using std::map;
37using std::pair;
38using std::tuple;
39using std::set;
40using std::string;
41using std::vector;
42
43namespace ore {
44namespace analytics {
45
46// Ease syntax
49
50namespace {
51
52// Useful for the implementation of a number of methods below
53vector<string> lookup(const RiskType& rt, const map<RiskType, vector<string>>& m) {
54 if (m.count(rt) > 0) {
55 return m.at(rt);
56 } else {
57 return {};
58 }
59}
60
61std::ostream& operator<<(std::ostream& out, const tuple<string, string, string>& tup) {
62 return out << "[Bucket: '" << std::get<0>(tup) << "', Label1: '" << std::get<1>(tup) << "', Label2: '"
63 << std::get<2>(tup) << "']";
64}
65
66
67
68} // anonymous namespace
69
70const tuple<string, string, string> SimmConfigurationBase::makeKey(const string& bucket, const string& label1,
71 const string& label2) const {
72 return std::make_tuple(bucket, label1, label2);
73}
74
75SimmConfigurationBase::SimmConfigurationBase(const QuantLib::ext::shared_ptr<SimmBucketMapper>& simmBucketMapper,
76 const std::string& name, const std::string version, Size mporDays)
77 : name_(name), version_(version), simmBucketMapper_(simmBucketMapper), mporDays_(mporDays) {}
78
79bool SimmConfigurationBase::hasBuckets(const RiskType& rt) const { return simmBucketMapper_->hasBuckets(rt); }
80
81string SimmConfigurationBase::bucket(const RiskType& rt, const string& qualifier) const {
82 QL_REQUIRE(hasBuckets(rt), "The SIMM risk type " << rt << " does not have buckets");
83 return simmBucketMapper_->bucket(rt, qualifier);
84}
85
86const bool SimmConfigurationBase::checkValue(const string& value, const vector<string>& container) const {
87 return std::find(container.begin(), container.end(), value) != container.end();
88}
89
90vector<string> SimmConfigurationBase::buckets(const RiskType& rt) const {
91 QL_REQUIRE(isValidRiskType(rt),
92 "The risk type " << rt << " is not valid for SIMM configuration with name" << name_);
93 return lookup(rt, mapBuckets_);
94}
95
96vector<string> SimmConfigurationBase::labels1(const RiskType& rt) const {
97 QL_REQUIRE(isValidRiskType(rt),
98 "The risk type " << rt << " is not valid for SIMM configuration with name" << name_);
99 return lookup(rt, mapLabels_1_);
100}
101
102vector<string> SimmConfigurationBase::labels2(const RiskType& rt) const {
103 QL_REQUIRE(isValidRiskType(rt),
104 "The risk type " << rt << " is not valid for SIMM configuration with name" << name_);
105 return lookup(rt, mapLabels_2_);
106}
107
108QuantLib::Real SimmConfigurationBase::weight(const RiskType& rt, boost::optional<string> qualifier,
109 boost::optional<std::string> label_1, const std::string&) const {
110
111 QL_REQUIRE(isValidRiskType(rt),
112 "The risk type " << rt << " is not valid for SIMM configuration with name" << name_);
113
114 // If the risk type has flat risk weights, ignore last 2 parameters
115 if (rwRiskType_.count(rt) > 0) {
116 return rwRiskType_.at(rt);
117 }
118
119 // We now at least have bucket dependent risk weights so check qualifier and buckets
120 QL_REQUIRE(qualifier, "Need a valid qualifier to return a risk weight because the risk type "
121 << rt << " has bucket dependent risk weights");
122 QL_REQUIRE(!buckets(rt).empty(), "Could not find any buckets for risk type " << rt);
123 string bucket = simmBucketMapper_->bucket(rt, *qualifier);
124
125 // If risk weight for this risk type is bucket-dependent
126 if (rwBucket_.find(rt) != rwBucket_.end()) {
127 auto bucketKey = makeKey(bucket, "", "");
128 if (rwBucket_.at(rt).find(bucketKey) != rwBucket_.at(rt).end())
129 return rwBucket_.at(rt).at(bucketKey);
130 else
131 QL_FAIL("Could not find risk weight for risk type " << rt << " and key " << bucketKey);
132 }
133
134 // If we get to here, risk weight must depend on risk type, bucket and Label1
135 if (rwLabel_1_.find(rt) != rwLabel_1_.end()) {
136
137 QL_REQUIRE(label_1, "Need a valid Label1 value to return a risk weight because the risk type "
138 << rt << " has bucket and Label1 dependent risk weights");
139 QL_REQUIRE(!labels1(rt).empty(), "Could not find any Label1 values for risk type " << rt);
140 auto label1Key = makeKey(bucket, *label_1, "");
141
142 if (rwLabel_1_.at(rt).find(label1Key) != rwLabel_1_.at(rt).end())
143 return rwLabel_1_.at(rt).at(label1Key);
144 else
145 QL_FAIL("Could not find risk weight for risk type " << rt << " and key " << label1Key);
146 }
147
148 // If we get to here, we have failed to get a risk weight
149 QL_FAIL("Could not find a risk weight for (risk type, qualifier, Label1) = (" << rt << "," << qualifier << ","
150 << label_1 << ")");
151}
152
153QuantLib::Real SimmConfigurationBase::curvatureWeight(const RiskType& rt, const std::string& label_1) const {
154
155 QL_REQUIRE(isValidRiskType(rt),
156 "The risk type " << rt << " is not valid for SIMM configuration with name" << name_);
157
158 QL_REQUIRE(curvatureWeights_.count(rt) > 0, "The risk type " << rt << " does not have a curvature weight.");
159
160 QL_REQUIRE(!labels1(rt).empty(), "Could not find any Label1 values for risk type " << rt);
161 auto idx = labelIndex(label_1, labels1(rt));
162
163 return curvatureWeights_.at(rt)[idx];
164}
165
167 QL_REQUIRE(isValidRiskType(rt),
168 "The risk type " << rt << " is not valid for SIMM configuration with name" << name_);
169
170 if (historicalVolatilityRatios_.count(rt) > 0) {
171 return historicalVolatilityRatios_.at(rt);
172 } else {
173 return 1.0;
174 }
175}
176
177Real SimmConfigurationBase::sigma(const RiskType& rt, boost::optional<std::string> qualifier,
178 boost::optional<std::string> label_1, const std::string& calculationCurrency) const {
179
181
182 Real result = 1.0;
183 Real deltaRiskWeight;
184 std::string ccy1, ccy2;
185 switch (rt) {
186 case RiskType::CommodityVol:
187 deltaRiskWeight = weight(RiskType::Commodity, qualifier, label_1);
188 result = sigmaMultiplier * deltaRiskWeight;
189 break;
190 case RiskType::EquityVol:
191 deltaRiskWeight = weight(RiskType::Equity, qualifier, label_1);
192 result = sigmaMultiplier * deltaRiskWeight;
193 break;
194 case RiskType::FXVol:
195 /*For FX vega (which depends on a pair of currencies), the risk weight to use here is
196 the FX delta risk weight value. Before ISDA 2.2 this value is common for all currency pairs.
197 For ISDA 2.2 the FX delta is from the sensitivity table, given explicitly
198 in section I of the ISDA document, whose row is the FX volatility group of the first currency and
199 whose column is the FX volatility group of the second currency.
200 */
201 ccy1 = (*qualifier).substr(0, 3);
202 ccy2 = (*qualifier).substr(3, 3);
203 // make sure they parse as currencies
206 deltaRiskWeight = weight(RiskType::FX, ccy1, label_1, ccy2);
207 result = sigmaMultiplier * deltaRiskWeight;
208 break;
209 default:
210 break;
211 }
212
213 return result;
214}
215
216QuantLib::Real SimmConfigurationBase::correlation(const RiskType& firstRt, const string& firstQualifier,
217 const string& firstLabel_1, const string& firstLabel_2,
218 const RiskType& secondRt, const string& secondQualifier,
219 const string& secondLabel_1, const string& secondLabel_2,
220 const std::string&) const {
221
222 // First check that we have valid risk types for the configuration in question
223 QL_REQUIRE(isValidRiskType(firstRt),
224 "The risk type " << firstRt << " is not valid for SIMM configuration with name" << name());
225 QL_REQUIRE(isValidRiskType(secondRt),
226 "The risk type " << secondRt << " is not valid for SIMM configuration with name" << name());
227
228 // Deal with trivial case of everything equal
229 if (firstRt == secondRt && firstQualifier == secondQualifier && firstLabel_1 == secondLabel_1 &&
230 firstLabel_2 == secondLabel_2) {
231 return 1.0;
232 }
233
234 // Deal with Equity correlations
235 if ((firstRt == RiskType::Equity && secondRt == RiskType::Equity) ||
236 (firstRt == RiskType::EquityVol && secondRt == RiskType::EquityVol)) {
237
238 // Get the bucket of each qualifier
239 string bucket_1 = simmBucketMapper_->bucket(firstRt, firstQualifier);
240 string bucket_2 = simmBucketMapper_->bucket(secondRt, secondQualifier);
241
242 // Residual is special, 0 correlation inter and intra except if same qualifier
243 if (bucket_1 == "Residual" || bucket_2 == "Residual") {
244 return firstQualifier == secondQualifier ? 1.0 : 0.0;
245 }
246
247 // Non-residual
248 // Get the bucket index of each qualifier
249 if (bucket_1 == bucket_2) {
250 auto bucketKey = makeKey(bucket_1, "", "");
251 // If same bucket, return the intra-bucket correlation
252 return firstQualifier == secondQualifier ? 1.0 : intraBucketCorrelation_.at(RiskType::Equity).at(bucketKey);
253 } else {
254 // If different buckets, return the inter-bucket correlation
255 auto label12Key = makeKey("", bucket_1, bucket_2);
256 return interBucketCorrelation_.at(RiskType::Equity).at(label12Key);
257 }
258 }
259
260 // Deal with CreditQ correlations
261 if ((firstRt == RiskType::CreditQ && secondRt == RiskType::CreditQ) ||
262 (firstRt == RiskType::CreditVol && secondRt == RiskType::CreditVol)) {
263
264 // Get the bucket of each qualifier
265 string bucket_1 = simmBucketMapper_->bucket(firstRt, firstQualifier);
266 string bucket_2 = simmBucketMapper_->bucket(secondRt, secondQualifier);
267
268 // Residual is special
269 if (bucket_1 == "Residual" || bucket_2 == "Residual") {
270 if (bucket_1 == bucket_2) {
271 // Both Residual
273 } else {
274 // One is a residual bucket and the other is not
275 return 0.0;
276 }
277 }
278
279 // Non-residual
280 if (bucket_1 == bucket_2) {
281 // If same bucket
282 if (firstQualifier != secondQualifier) {
283 // If different qualifier (i.e. here issuer/seniority)
284 return crqDiffIntraCorr_;
285 } else {
286 // If same qualifier (i.e. here issuer/seniority)
287 return crqSameIntraCorr_;
288 }
289 } else {
290 // Get the bucket indices of each qualifier for reading the matrix
291 RiskType rt = RiskType::CreditQ;
292 auto label12Key = makeKey("", bucket_1, bucket_2);
293 if (interBucketCorrelation_.at(rt).find(label12Key) != interBucketCorrelation_.at(rt).end())
294 return interBucketCorrelation_.at(rt).at(label12Key);
295 else
296 QL_FAIL("Could not find correlation for risk type " << rt << " and key " << label12Key);
297 }
298 }
299
300 // Deal with CreditNonQ correlations
301 if ((firstRt == RiskType::CreditNonQ && secondRt == RiskType::CreditNonQ) ||
302 (firstRt == RiskType::CreditVolNonQ && secondRt == RiskType::CreditVolNonQ)) {
303
304 // Get the bucket of each qualifier
305 string bucket_1 = simmBucketMapper_->bucket(firstRt, firstQualifier);
306 string bucket_2 = simmBucketMapper_->bucket(secondRt, secondQualifier);
307
308 // Residual is special
309 if (bucket_1 == "Residual" || bucket_2 == "Residual") {
310 if (bucket_1 == bucket_2) {
311 // Both Residual
313 } else {
314 // One is a residual bucket and the other is not
315 return 0.0;
316 }
317 }
318
319 // Non-residual
320 if (bucket_1 == bucket_2) {
321 SimmVersion thresholdVersion = SimmVersion::V2_2;
322 if (isSimmConfigCalibration() || parseSimmVersion(version_) >= thresholdVersion) {
323 // In ISDA SIMM version 2.2 or greater, the CRNQ correlations differ depending on whether or not
324 // the entities have the same group name i.e. CMBX.
325 return firstLabel_2 == secondLabel_2 ? crnqSameIntraCorr_ : crnqDiffIntraCorr_;
326 }
327 // TODO:
328 // If same bucket. For ISDA SIMM < 2.2 there is a section in the documentation where
329 // you choose between a correlation if the underlying names are the same and another
330 // correlation if the underlying names are different. The underlying names being the
331 // same is defined in terms of an overlap of 80% in notional terms in underlying names.
332 // Don't know how to pass this down yet so we just go on qualifiers here.
333 return firstQualifier == secondQualifier ? crnqSameIntraCorr_ : crnqDiffIntraCorr_;
334 } else {
335 // If different buckets, return the inter-bucket correlation
336 return crnqInterCorr_;
337 }
338 }
339
340 // Deal with Commodity correlations
341 if ((firstRt == RiskType::Commodity && secondRt == RiskType::Commodity) ||
342 (firstRt == RiskType::CommodityVol && secondRt == RiskType::CommodityVol)) {
343
344 // Get the bucket index of each qualifier
345 const string& bucket_1 = simmBucketMapper_->bucket(firstRt, firstQualifier);
346 const string& bucket_2 = simmBucketMapper_->bucket(secondRt, secondQualifier);
347
348 if (bucket_1 == bucket_2) {
349 auto bucketKey = makeKey(bucket_1, "", "");
350 // If same bucket, return the intra-bucket correlation
351 return firstQualifier == secondQualifier ? 1.0 : intraBucketCorrelation_.at(RiskType::Commodity).at(bucketKey);
352 } else {
353 // If different buckets, return the inter-bucket correlation
354 auto label12Key = makeKey("", bucket_1, bucket_2);
355 return interBucketCorrelation_.at(RiskType::Commodity).at(label12Key);
356 }
357 }
358
359 // Deal with case of different risk types
360 if ((firstRt != secondRt) && (firstQualifier == secondQualifier)) {
361 if (((firstRt == RiskType::IRCurve || firstRt == RiskType::Inflation) && secondRt == RiskType::XCcyBasis) ||
362 (firstRt == RiskType::XCcyBasis && (secondRt == RiskType::IRCurve || secondRt == RiskType::Inflation))) {
363 // Between xccy basis and any yield or inflation in same currency
364 return xccyCorr_;
365 }
366 if ((firstRt == RiskType::IRCurve && secondRt == RiskType::Inflation) ||
367 (firstRt == RiskType::Inflation && secondRt == RiskType::IRCurve)) {
368 // Between any yield and inflation in same currency
369 return infCorr_;
370 }
371 if ((firstRt == RiskType::IRVol && secondRt == RiskType::InflationVol) ||
372 (firstRt == RiskType::InflationVol && secondRt == RiskType::IRVol)) {
373 // Between any yield volatility and inflation volatility in same currency
374 return infVolCorr_;
375 }
376 }
377
378 // Deal with IRCurve and IRVol correlations
379 if ((firstRt == RiskType::IRCurve && secondRt == RiskType::IRCurve) ||
380 (firstRt == RiskType::IRVol && secondRt == RiskType::IRVol)) {
381
382 // If the qualifiers, i.e. currencies, are the same
383 if (firstQualifier == secondQualifier) {
384 // Label2 level, i.e. sub-curve, correlations
385 if (firstLabel_2 != secondLabel_2) {
386 QL_REQUIRE(
387 firstLabel_1 == "" && secondLabel_1 == "",
388 "When asking for Label2 level correlations, "
389 << "the Label1 level values should both contain the default parameter i.e. empty string");
390 QL_REQUIRE(firstRt != RiskType::IRVol, "There is no correlation at the Label2 level for Risk_IRVol");
391 return irSubCurveCorr_;
392 }
393
394 // Label1 level, i.e. tenor, correlations
395 RiskType rt = RiskType::IRCurve;
396 auto label12Key = makeKey("", firstLabel_1, secondLabel_1);
397 if (intraBucketCorrelation_.at(rt).find(label12Key) != intraBucketCorrelation_.at(rt).end())
398 return intraBucketCorrelation_.at(rt).at(label12Key);
399 else
400 QL_FAIL("Could not find correlation for risk type " << rt << " and key " << label12Key);
401 } else {
402 // If the qualifiers, i.e. currencies, are not the same
404 }
405 }
406
407 // Deal with inflation volatility correlations
408 if (firstRt == RiskType::InflationVol && secondRt == RiskType::InflationVol) {
409 return 1.0;
410 }
411
412 // Deal with FX correlations
413 // TODO:
414 // For FXVol, qualifier is a currency pair. Is it possible to get here
415 // and to have something like secondQualifier = USDJPY and firstQualifier =
416 // JPYUSD an to give back 0.5
417 if ((firstRt == RiskType::FX && secondRt == RiskType::FX) ||
418 (firstRt == RiskType::FXVol && secondRt == RiskType::FXVol)) {
419 return firstQualifier == secondQualifier ? 1.0 : fxCorr_;
420 }
421
422 // Both risk types Base correlation
423 if (firstRt == RiskType::BaseCorr && secondRt == RiskType::BaseCorr) {
424 return basecorrCorr_;
425 }
426
427 // If we get to here
428 return 0.0;
429}
430
432 // return 2.19486471232815;
433 // Use boost inverse normal here as opposed to QL. Using QL inverse normal
434 // will cause the ISDA SIMM unit tests to fail
435
436 /* We write sqrt(365.0 / (1.4 * mporDays_)) so that this function is
437 sqrt(365.0 / 14) for MPOR = 10 as expected and sqrt(365.0 / 1.4) for MPOR = 1.
438 This is described in SIMM:Technical Paper (Version 10), Section I.2 */
439 return sqrt(365.0 / (1.4 * mporDays_)) / boost::math::quantile(boost::math::normal(), 0.99);
440}
441
442QuantLib::Real SimmConfigurationBase::correlationRiskClasses(const RiskClass& rc_1, const RiskClass& rc_2) const {
443
444 if (rc_1 == rc_2)
445 return 1.0;
446
447 auto rcLabel12Key = makeKey("", ore::data::to_string(rc_1), ore::data::to_string(rc_2));
448
449 QL_REQUIRE(riskClassCorrelation_.find(rcLabel12Key) != riskClassCorrelation_.end(),
450 "Could not find risk class correlation between " << rc_1 << " and " << rc_2 << ".");
451
452 return riskClassCorrelation_.at(rcLabel12Key);
453}
454
455Size SimmConfigurationBase::labelIndex(const string& label, const vector<string>& labels) const {
456 QL_REQUIRE(!labels.empty(), "Labels cannot be empty");
457 auto it = std::find(labels.begin(), labels.end(), label);
458 QL_REQUIRE(it != labels.end(), "The label '" << label << "' could not be found in the labels.");
459 return std::distance(labels.begin(), it);
460}
461
462void SimmConfigurationBase::addLabels2Impl(const RiskType& rt, const string& label_2) {
463 // Only currently need this for risk type CreditQ
464 QL_REQUIRE(rt == RiskType::CreditQ, "addLabels2 only supported for RiskType_CreditQ");
465
466 // Expect label of the form "CCY" or "CCY,Sec"
467 if (label_2.size() == 3) {
468 QL_REQUIRE(checkCurrency(label_2), "Expected a Label2 of size 3 to be a valid currency code");
469 }
470
471 if (label_2.size() == 7) {
472 QL_REQUIRE(checkCurrency(label_2.substr(0, 3)), "Expected first 3 characters of Label2 ("
473 << label_2.substr(0, 3) << ") to be a valid currency code");
474 QL_REQUIRE(label_2.substr(4) == "Sec", "Last 3 characters of Label2 should be 'Sec'");
475 QL_REQUIRE(checkCurrency(label_2.substr(3, 1)), "Delimiter should be a comma");
476 }
477
478 QL_FAIL("Label2 passed to addLabels2 is unusable for RiskType " << rt);
479}
480
481} // namespace analytics
482} // namespace ore
virtual std::string label2(const QuantLib::ext::shared_ptr< QuantLib::InterestRateIndex > &irIndex) const
QuantLib::Real correlation(const CrifRecord::RiskType &firstRt, const std::string &firstQualifier, const std::string &firstLabel_1, const std::string &firstLabel_2, const CrifRecord::RiskType &secondRt, const std::string &secondQualifier, const std::string &secondLabel_1, const std::string &secondLabel_2, const std::string &calculationCurrency="") const override
const std::tuple< std::string, std::string, std::string > makeKey(const std::string &, const std::string &, const std::string &) const
QuantLib::Real crqResidualIntraCorr_
Credit-Q residual intra correlation.
SimmConfigurationBase(const QuantLib::ext::shared_ptr< SimmBucketMapper > &simmBucketMapper, const std::string &name, const std::string version, QuantLib::Size mporDays=10)
Constructor taking the SIMM configuration name and version.
QuantLib::Real basecorrCorr_
Base correlation risk factor correlation.
std::vector< std::string > buckets(const CrifRecord::RiskType &rt) const override
QuantLib::Real correlationRiskClasses(const RiskClass &rc_1, const RiskClass &rc_2) const override
Return the correlation between SIMM risk classes rc_1 and rc_2.
std::map< CrifRecord::RiskType, QuantLib::Real > rwRiskType_
QuantLib::Real weight(const CrifRecord::RiskType &rt, boost::optional< std::string > qualifier=boost::none, boost::optional< std::string > label_1=boost::none, const std::string &calculationCurrency="") const override
QuantLib::Size labelIndex(const std::string &label, const std::vector< std::string > &labels) const
Helper method to find the index of the label in labels.
std::string name_
Name of the SIMM configuration.
QuantLib::Real crnqResidualIntraCorr_
Credit-NonQ residual intra correlation.
std::string version_
SIMM configuration version.
bool hasBuckets(const CrifRecord::RiskType &rt) const override
Return true if the SIMM risk type rt has buckets.
std::map< CrifRecord::RiskType, std::vector< std::string > > mapLabels_2_
bool isValidRiskType(const CrifRecord::RiskType &rt) const override
QuantLib::Real irInterCurrencyCorr_
IR correlation across currencies.
std::vector< std::string > labels2(const CrifRecord::RiskType &rt) const override
std::map< CrifRecord::RiskType, Amounts > rwLabel_1_
std::map< CrifRecord::RiskType, Amounts > intraBucketCorrelation_
std::map< CrifRecord::RiskType, std::vector< std::string > > mapBuckets_
QuantLib::Real crnqDiffIntraCorr_
Credit-NonQ non-residual intra correlation when different underlying names.
QuantLib::Real sigma(const CrifRecord::RiskType &rt, boost::optional< std::string > qualifier=boost::none, boost::optional< std::string > label_1=boost::none, const std::string &calculationCurrency="") const override
QuantLib::Real crqSameIntraCorr_
Credit-Q non-residual intra correlation when same qualifier but different vertex/source.
const std::string & name() const override
Returns the SIMM configuration name.
QuantLib::Real crnqSameIntraCorr_
Credit-NonQ non-residual intra correlation when same underlying names.
std::vector< std::string > labels1(const CrifRecord::RiskType &rt) const override
const bool checkValue(const std::string &, const std::vector< std::string > &) const
QuantLib::Real sigmaMultiplier() const
Calculate variable for use in sigma method.
QuantLib::Real curvatureWeight(const CrifRecord::RiskType &rt, const std::string &label_1) const override
QuantLib::Real infCorr_
Correlation between any yield and inflation in same currency.
Amounts riskClassCorrelation_
Risk class correlation matrix.
QuantLib::Real crnqInterCorr_
Credit-NonQ non-residual inter bucket correlation.
std::map< CrifRecord::RiskType, QuantLib::Real > historicalVolatilityRatios_
Map from risk type to a historical volatility ratio.
std::map< CrifRecord::RiskType, Amounts > interBucketCorrelation_
std::map< CrifRecord::RiskType, std::vector< std::string > > mapLabels_1_
QuantLib::Real infVolCorr_
Correlation between any yield volatility and inflation volatility in same currency.
QuantLib::Real crqDiffIntraCorr_
Credit-Q non-residual intra correlation when different qualifier.
QuantLib::Real irSubCurveCorr_
IR Label2 level i.e. sub-curve correlation.
QuantLib::Real historicalVolatilityRatio(const CrifRecord::RiskType &rt) const override
void addLabels2Impl(const CrifRecord::RiskType &rt, const std::string &label_2)
A base implementation of addLabels2 that can be shared by derived classes.
std::map< CrifRecord::RiskType, std::vector< QuantLib::Real > > curvatureWeights_
QuantLib::ext::shared_ptr< SimmBucketMapper > simmBucketMapper_
Used to map SIMM Qualifier names to SIMM bucket values.
std::string bucket(const CrifRecord::RiskType &rt, const std::string &qualifier) const override
std::map< CrifRecord::RiskType, Amounts > rwBucket_
virtual bool isSimmConfigCalibration() const
SafeStack< ValueType > value
Currency parseCurrency(const string &s)
bool checkCurrency(const string &code)
Integer parseInteger(const string &s)
RandomVariable sqrt(RandomVariable x)
std::ostream & operator<<(std::ostream &out, EquityReturnType t)
SimmConfiguration::RiskClass RiskClass
CrifRecord::RiskType RiskType
Definition: crifloader.cpp:92
SimmVersion
Ordered SIMM versions.
Definition: utilities.hpp:43
SimmVersion parseSimmVersion(const string &version)
Definition: utilities.cpp:162
std::string to_string(const LocationInfo &l)
Base SIMM configuration class.
string name
supporting utilities