Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
simmcalibration.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2023 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
25
26#include <boost/algorithm/string/join.hpp>
27#include <boost/algorithm/string.hpp>
28
29using QuantLib::Size;
30using QuantLib::Real;
31using std::map;
32using std::make_pair;
33using std::pair;
34using std::tuple;
35using std::string;
36using std::vector;
37using std::set;
41
42
43namespace ore {
44namespace analytics {
45
46namespace {
47
48Size getMPOR(XMLNode* node) {
49 string mporStr = XMLUtils::getAttribute(node, "mporDays");
50 return mporStr.empty() ? 10 : ore::data::parseInteger(mporStr);
51}
52
53}
54
57
58SimmCalibration::Amount::Amount(const tuple<string, string, string>& key, const string& value) {
59 bucket_ = std::get<0>(key);
60 label1_ = std::get<1>(key);
61 label2_ = std::get<2>(key);
62 value_ = value;
63}
64
66 auto amountNode = doc.allocNode("Amount", value_);
67 if (!bucket_.empty())
68 XMLUtils::addAttribute(doc, amountNode, "bucket", bucket_);
69 if (!label1_.empty())
70 XMLUtils::addAttribute(doc, amountNode, "label1", label1_);
71 if (!label2_.empty())
72 XMLUtils::addAttribute(doc, amountNode, "label2", label2_);
73 return amountNode;
74}
75
77 bucket_ = XMLUtils::getAttribute(node, "bucket");
78 label1_ = XMLUtils::getAttribute(node, "label1");
79 label2_ = XMLUtils::getAttribute(node, "label2");
80 value_ = XMLUtils::getNodeValue(node);
81}
82
83const tuple<string, string, string> SimmCalibration::Amount::key() const {
84 return std::make_tuple(bucket_, label1_, label2_);
85}
86
87SimmCalibration::RiskClassData::RiskWeights::RiskWeights(const RC& riskClass, XMLNode* node) : riskClass_(riskClass) {
88 fromXML(node);
89}
90
92 auto riskWeightsNode = doc.allocNode("RiskWeights");
93
94 // Delta and Vega risk weights
95 for (const string& rwType : {"Delta", "Vega"}) {
96 auto& riskWeightsMap = rwType == "Delta" ? delta_ : vega_;
97
98 for (const auto& [mpor, riskWeights] : riskWeightsMap) {
99 auto rwTypeNode = doc.allocNode(rwType);
100 XMLUtils::addAttribute(doc, rwTypeNode, "mporDays", ore::data::to_string(mpor));
101 for (const auto& [rwKey, weight] : riskWeights) {
102 Amount amount(rwKey, weight);
103 auto amountNode = amount.toXML(doc);
104 XMLUtils::setNodeName(doc, amountNode, "Weight");
105 XMLUtils::appendNode(rwTypeNode, amountNode);
106 }
107 XMLUtils::appendNode(riskWeightsNode, rwTypeNode);
108 }
109 }
110
111 // Historical volatility ratio
112 for (const auto& [mpor, amount] : historicalVolatilityRatio_) {
113 auto hvrNode = amount->toXML(doc);
114 XMLUtils::setNodeName(doc, hvrNode, "HistoricalVolatilityRatio");
115 XMLUtils::addAttribute(doc, hvrNode, "mporDays", ore::data::to_string(mpor));
116 XMLUtils::appendNode(riskWeightsNode, hvrNode);
117 }
118
119 return riskWeightsNode;
120}
121
123 XMLUtils::checkNode(node, "RiskWeights");
124
125 // Delta and Vega risk weights
126 for (const string& rwType : {"Delta", "Vega"}) {
127 auto& riskWeightsMap = rwType == "Delta" ? delta_ : vega_;
128 auto rwNodes = XMLUtils::getChildrenNodes(node, rwType);
129 for (XMLNode* rwNode : rwNodes) {
130 Size mpor = getMPOR(rwNode);
131 auto weightNodes = XMLUtils::getChildrenNodes(rwNode, "Weight");
132 riskWeightsMap[mpor].clear();
133 for (XMLNode* weightNode : weightNodes) {
134 Amount amount(weightNode);
135 riskWeightsMap[mpor][amount.key()] = amount.value();
136 }
137 }
138 }
139
140 // Historical volatility ratio
141 auto hvrNodes = XMLUtils::getChildrenNodes(node, "HistoricalVolatilityRatio");
142 for (XMLNode* hvrNode : hvrNodes) {
143 Size mpor = getMPOR(hvrNode);
144 auto hvr = QuantLib::ext::make_shared<Amount>(hvrNode);
145 historicalVolatilityRatio_[mpor] = hvr;
146 }
147}
148
150 fromXML(node);
151}
152
154 auto riskWeightsNode = RiskWeights::toXML(doc);
155
156 // Inflation and XCcyBasis
157 for (const string& rwType : {"Inflation", "XCcyBasis"}) {
158 auto container = rwType == "Inflation" ? inflation_ : xCcyBasis_;
159 for (const auto& [mpor, amount] : container) {
160 auto rwNode = amount->toXML(doc);
161 XMLUtils::setNodeName(doc, rwNode, rwType);
162 XMLUtils::addAttribute(doc, rwNode, "mporDays", ore::data::to_string(mpor));
163 XMLUtils::appendNode(riskWeightsNode, rwNode);
164 }
165 }
166
167 // Currency lists
168 auto currencyListsNode = doc.allocNode("CurrencyLists");
169 for (const auto& [ccyKey, ccyList] : currencyLists_) {
170 for (const string& ccy : ccyList) {
171 Amount amount(ccyKey, ccy);
172 auto ccyNode = amount.toXML(doc);
173 XMLUtils::setNodeName(doc, ccyNode, "Currency");
174 XMLUtils::appendNode(currencyListsNode, ccyNode);
175 }
176 }
177 XMLUtils::appendNode(riskWeightsNode, currencyListsNode);
178
179 return riskWeightsNode;
180}
181
184
185 for (const string& weightType : {"Inflation", "XCcyBasis"}) {
186 auto& weightMap = weightType == "Inflation" ? inflation_ : xCcyBasis_;
187 weightMap.clear();
188 auto weightTypeNodes = XMLUtils::getChildrenNodes(node, weightType);
189 for (XMLNode* weightTypeNode : weightTypeNodes) {
190 Size mpor = getMPOR(weightTypeNode);
191 auto amount = QuantLib::ext::make_shared<Amount>(weightTypeNode);
192 weightMap[mpor] = amount;
193 }
194 }
195
196 // Currency lists
197 auto ccyListsNode = XMLUtils::getChildNode(node, "CurrencyLists");
198 currencyLists_.clear();
199 for (XMLNode* ccyNode : XMLUtils::getChildrenNodes(ccyListsNode, "Currency")) {
200 Amount amount(ccyNode);
201 currencyLists_[amount.key()].insert(amount.value());
202 }
203}
204
205const std::map<RT, map<Size, QuantLib::ext::shared_ptr<SimmCalibration::Amount>>>
207 std::map<RT, map<Size, QuantLib::ext::shared_ptr<SimmCalibration::Amount>>> urwMap;
208
209 for (const auto& [mpor, rw] : inflation_)
210 urwMap[RT::Inflation][mpor] = rw;
211 for (const auto& [mpor, rw] : xCcyBasis_)
212 urwMap[RT::XCcyBasis][mpor] = rw;
213
214 return urwMap;
215}
216
218 fromXML(node);
219}
220
222 auto riskWeightsNode = RiskWeights::toXML(doc);
223
224 // Currency lists
225 auto currencyListsNode = doc.allocNode("CurrencyLists");
226 for (const auto& [ccyKey, ccyList] : currencyLists_) {
227 for (const string& ccy : ccyList) {
228 Amount amount(ccyKey, ccy);
229 auto ccyNode = amount.toXML(doc);
230 XMLUtils::setNodeName(doc, ccyNode, "Currency");
231 XMLUtils::appendNode(currencyListsNode, ccyNode);
232 }
233 }
234 XMLUtils::appendNode(riskWeightsNode, currencyListsNode);
235
236 return riskWeightsNode;
237}
238
241
242 // Currency lists
243 auto ccyListsNode = XMLUtils::getChildNode(node, "CurrencyLists");
244 currencyLists_.clear();
245 for (XMLNode* ccyNode : XMLUtils::getChildrenNodes(ccyListsNode, "Currency")) {
246 Amount amount(ccyNode);
247 currencyLists_[amount.key()].insert(amount.value());
248 }
249}
250
252 : RiskWeights(RC::CreditQualifying) {
253 fromXML(node);
254}
255
257 auto riskWeightsNode = RiskWeights::toXML(doc);
258
259 // Base correlation
260 for (const auto& [mpor, amount] : baseCorrelation_) {
261 auto rwNode = amount->toXML(doc);
262 XMLUtils::setNodeName(doc, rwNode, "BaseCorrelation");
263 XMLUtils::addAttribute(doc, rwNode, "mporDays", ore::data::to_string(mpor));
264 XMLUtils::appendNode(riskWeightsNode, rwNode);
265 }
266
267 return riskWeightsNode;
268}
269
272
273 // Base correlation
274 auto baseCorrNodes = XMLUtils::getChildrenNodes(node, "BaseCorrelation");
275 for (XMLNode* baseCorrNode : baseCorrNodes) {
276 Size mpor = getMPOR(baseCorrNode);
277 auto baseCorrelation = QuantLib::ext::make_shared<Amount>(baseCorrNode);
278 baseCorrelation_[mpor] = baseCorrelation;
279 }
280}
281
282const std::map<RT, map<Size, QuantLib::ext::shared_ptr<SimmCalibration::Amount>>>
284 std::map<RT, map<Size, QuantLib::ext::shared_ptr<SimmCalibration::Amount>>> urwMap;
285
286 for (const auto& [mpor, rw] : baseCorrelation_)
287 urwMap[RT::BaseCorr][mpor] = rw;
288
289 return urwMap;
290}
291
293 auto correlationsNode = doc.allocNode("Correlations");
294
295 // Intra- and Inter-bucket correlations
296 for (const string& corrType : {"IntraBucket", "InterBucket"}) {
297 auto& correlations = corrType == "IntraBucket" ? intraBucketCorrelations_ : interBucketCorrelations_;
298
299 if (correlations.empty())
300 continue;
301
302 auto corrTypeNode = doc.allocNode(corrType);
303 for (const auto& [corrKey, corr] : correlations) {
304 Amount amount(corrKey, corr);
305 auto correlationNode = amount.toXML(doc);
306 XMLUtils::setNodeName(doc, correlationNode, "Correlation");
307 XMLUtils::appendNode(corrTypeNode, correlationNode);
308 }
309 XMLUtils::appendNode(correlationsNode, corrTypeNode);
310 }
311
312 return correlationsNode;
313}
314
316 XMLUtils::checkNode(node, "Correlations");
317
318 // Intra- and Inter-bucket correlations
319 for (const string& corrType : {"IntraBucket", "InterBucket"}) {
320 auto& correlationsMap = corrType == "IntraBucket" ? intraBucketCorrelations_ : interBucketCorrelations_;
321 correlationsMap.clear();
322 auto corrNodes = XMLUtils::getChildrenNodes(node, corrType);
323 for (XMLNode* corrNode : corrNodes) {
324 for (XMLNode* weightNode : XMLUtils::getChildrenNodes(corrNode, "Correlation")) {
325 Amount amount(weightNode);
326 correlationsMap[amount.key()] = amount.value();
327 }
328 }
329 }
330}
331
333 auto correlationsNode = Correlations::toXML(doc);
334
335 auto corrTypes = map<string, QuantLib::ext::shared_ptr<Amount>>(
336 {{"SubCurves", subCurves_}, {"Inflation", inflation_}, {"XCcyBasis", xCcyBasis_}, {"Outer", outer_}});
337
338 for (const auto& [corrType, container] : corrTypes) {
339 auto correlationNode = container->toXML(doc);
340 XMLUtils::setNodeName(doc, correlationNode, corrType);
341 XMLUtils::appendNode(correlationsNode, correlationNode);
342 }
343
344 return correlationsNode;
345}
346
349
350 auto corrTypes = map<string, QuantLib::ext::shared_ptr<Amount>&>(
351 {{"SubCurves", subCurves_}, {"Inflation", inflation_}, {"XCcyBasis", xCcyBasis_}, {"Outer", outer_}});
352
353 for (auto& [corrType, container] : corrTypes) {
354 auto corrNode = XMLUtils::getChildNode(node, corrType);
355 container = QuantLib::ext::make_shared<Amount>(corrNode);
356 }
357}
358
360 auto correlationsNode = Correlations::toXML(doc);
361
362 auto baseCorrelationNode = baseCorrelation_->toXML(doc);
363 XMLUtils::setNodeName(doc, baseCorrelationNode, "BaseCorrelation");
364 XMLUtils::appendNode(correlationsNode, baseCorrelationNode);
365
366 return correlationsNode;
367}
368
371
372 auto baseCorrelationNode = XMLUtils::getChildNode(node, "BaseCorrelation");
373 baseCorrelation_ = QuantLib::ext::make_shared<Amount>(baseCorrelationNode);
374}
375
377 auto correlationsNode = Correlations::toXML(doc);
378
379 auto volatilityNode = volatility_->toXML(doc);
380 XMLUtils::setNodeName(doc, volatilityNode, "Volatility");
381 XMLUtils::appendNode(correlationsNode, volatilityNode);
382
383 return correlationsNode;
384}
385
388
389 auto volatilityNode = XMLUtils::getChildNode(node, "Volatility");
390 volatility_ = QuantLib::ext::make_shared<Amount>(volatilityNode);
391}
392
394 auto concThresholdsNode = doc.allocNode("ConcentrationThresholds");
395
396 // Delta and Vega risk weights
397 for (const string& type : {"Delta", "Vega"}) {
398 auto& concThresholds = type == "Delta" ? delta_ : vega_;
399
400 auto typeNode = doc.allocNode(type);
401 for (const auto& [ctKey, threshold] : concThresholds) {
402 Amount amount(ctKey, threshold);
403 auto amountNode = amount.toXML(doc);
404 XMLUtils::setNodeName(doc, amountNode, "Threshold");
405 XMLUtils::appendNode(typeNode, amountNode);
406 }
407 XMLUtils::appendNode(concThresholdsNode, typeNode);
408 }
409
410 return concThresholdsNode;
411}
412
414 XMLUtils::checkNode(node, "ConcentrationThresholds");
415
416 // Delta and Vega risk weights
417 for (const string& concThresholdType : {"Delta", "Vega"}) {
418 auto& concThresholdsMap = concThresholdType == "Delta" ? delta_ : vega_;
419 concThresholdsMap.clear();
420 auto concThresholdNodes = XMLUtils::getChildrenNodes(node, concThresholdType);
421 for (XMLNode* concThresholdNode : concThresholdNodes) {
422 auto thresholdNodes = XMLUtils::getChildrenNodes(concThresholdNode, "Threshold");
423 for (XMLNode* thresholdNode : thresholdNodes) {
424 Amount amount(thresholdNode);
425 concThresholdsMap[amount.key()] = amount.value();
426 }
427 }
428 }
429
430}
431
433 auto concThresholdsNode = ConcentrationThresholds::toXML(doc);
434
435 // Currency lists
436 auto currencyListsNode = doc.allocNode("CurrencyLists");
437 for (const auto& [ccyKey, ccyList] : currencyLists_) {
438 for (const string& ccy : ccyList) {
439 Amount amount(ccyKey, ccy);
440 auto ccyNode = amount.toXML(doc);
441 XMLUtils::setNodeName(doc, ccyNode, "Currency");
442 XMLUtils::appendNode(currencyListsNode, ccyNode);
443 }
444 }
445 XMLUtils::appendNode(concThresholdsNode, currencyListsNode);
446
447 return concThresholdsNode;
448}
449
452
453 // Currency lists
454 auto ccyListsNode = XMLUtils::getChildNode(node, "CurrencyLists");
455 currencyLists_.clear();
456 for (XMLNode* ccyNode : XMLUtils::getChildrenNodes(ccyListsNode, "Currency")) {
457 Amount amount(ccyNode);
458 currencyLists_[amount.key()].insert(amount.value());
459 }
460}
461
463 auto riskClassNode = doc.allocNode(ore::data::to_string(riskClass_));
464
465 // Risk weights
466 XMLUtils::appendNode(riskClassNode, riskWeights_->toXML(doc));
467
468 // Correlations
469 XMLUtils::appendNode(riskClassNode, correlations_->toXML(doc));
470
471 // Concentration thresholds
472 XMLUtils::appendNode(riskClassNode, concentrationThresholds_->toXML(doc));
473
474 return riskClassNode;
475}
476
479
480 // Risk weights
481 XMLNode* riskWeightsNode = XMLUtils::getChildNode(node, "RiskWeights");
482 switch (riskClass_) {
483 case (RC::InterestRate):
484 riskWeights_ = QuantLib::ext::make_shared<IRRiskWeights>(riskWeightsNode);
485 break;
486 case (RC::CreditQualifying):
487 riskWeights_ = QuantLib::ext::make_shared<CreditQRiskWeights>(riskWeightsNode);
488 break;
489 case (RC::FX):
490 riskWeights_ = QuantLib::ext::make_shared<FXRiskWeights>(riskWeightsNode);
491 break;
492 default:
493 riskWeights_ = QuantLib::ext::make_shared<RiskWeights>(riskClass_, riskWeightsNode);
494 }
495
496 // Correlations
497 XMLNode* correlationsNode = XMLUtils::getChildNode(node, "Correlations");
498 switch (riskClass_) {
499 case (RC::InterestRate):
500 correlations_ = QuantLib::ext::make_shared<IRCorrelations>(correlationsNode);
501 break;
502 case (RC::CreditQualifying):
503 correlations_ = QuantLib::ext::make_shared<CreditQCorrelations>(correlationsNode);
504 break;
505 case (RC::FX):
506 correlations_ = QuantLib::ext::make_shared<FXCorrelations>(correlationsNode);
507 break;
508 default:
509 correlations_ = QuantLib::ext::make_shared<Correlations>(correlationsNode);
510 }
511
512 // Concentration Thresholds
513 XMLNode* concentrationThresholdsNode = XMLUtils::getChildNode(node, "ConcentrationThresholds");
514 if (riskClass_ == RC::InterestRate || riskClass_ == RC::FX) {
515 concentrationThresholds_ = QuantLib::ext::make_shared<IRFXConcentrationThresholds>(concentrationThresholdsNode);
516 } else {
517 concentrationThresholds_ = QuantLib::ext::make_shared<ConcentrationThresholds>(concentrationThresholdsNode);
518 }
519}
520
521const string& SimmCalibration::version() const { return versionNames_.front(); }
522
524 XMLNode* simmCalibrationNode = doc.allocNode("SIMMCalibration");
525 XMLUtils::addAttribute(doc, simmCalibrationNode, "id", id_);
526
527 // Version names
528 XMLNode* versionNamesNode = doc.allocNode("VersionNames");
529 for (const string& vname : versionNames()) {
530 XMLUtils::addChild(doc, versionNamesNode, "Name", vname);
531 }
532 XMLUtils::appendNode(simmCalibrationNode, versionNamesNode);
533
534 // Additional fields
535 XMLNode* additionalFieldsNode = doc.allocNode("AdditionalFields");
536 for (const auto& [nodeName, nodeValue] : additionalFields()) {
537 XMLUtils::addChild(doc, additionalFieldsNode, nodeName, nodeValue);
538 }
539 XMLUtils::appendNode(simmCalibrationNode, additionalFieldsNode);
540
541 // Risk class-specific nodes (e.g. InterestRate, CreditQ, CreditNonQ, etc.)
542 for (const auto& [riskClass, rcData] : riskClassData_) {
543 const string rcString = ore::data::to_string(riskClass);
544 auto rcNode = rcData->toXML(doc);
545 XMLUtils::appendNode(simmCalibrationNode, rcNode);
546 }
547
548 // Risk class correlations
549 XMLNode* riskClassCorrelationsNode = doc.allocNode("RiskClassCorrelations");
550 for (const auto& [rcCorrKey, rcCorrelation] : riskClassCorrelations_) {
551 Amount amount(rcCorrKey, rcCorrelation);
552 auto corrNode = amount.toXML(doc);
553 XMLUtils::setNodeName(doc, corrNode, "Correlation");
554 XMLUtils::appendNode(riskClassCorrelationsNode, corrNode);
555 }
556 XMLUtils::appendNode(simmCalibrationNode, riskClassCorrelationsNode);
557 return simmCalibrationNode;
558}
559
561 XMLUtils::checkNode(node, "SIMMCalibration");
562
563 id_ = XMLUtils::getAttribute(node, "id");
564
565 // Version names
566 XMLNode* versionNamesNode = XMLUtils::getChildNode(node, "VersionNames");
567 for (XMLNode* name : XMLUtils::getChildrenNodes(versionNamesNode, "Name"))
569 QL_REQUIRE(!versionNames_.empty(), "Must provide at least one version name for SIMM calibration");
570
571 // Additional fields
572 XMLNode* addFieldsNode = XMLUtils::getChildNode(node, "AdditionalFields");
573 if (addFieldsNode)
574 for (XMLNode* child = XMLUtils::getChildNode(addFieldsNode); child; child = XMLUtils::getNextSibling(child))
575 additionalFields_.push_back(std::make_pair(XMLUtils::getNodeName(child), XMLUtils::getNodeValue(child)));
576
577 // Risk class-specific nodes (e.g. InterestRate, CreditQ, CreditNonQ, etc.)
578 XMLNode* riskClassNode;
579 for (const SimmConfiguration::RiskClass& rc :
580 { RC::InterestRate, RC::CreditQualifying, RC::CreditNonQualifying, RC::Equity, RC::Commodity, RC::FX }) {
581 riskClassNode = XMLUtils::getChildNode(node, ore::data::to_string(rc));
582 auto riskClassData = QuantLib::ext::make_shared<RiskClassData>(rc);
583 riskClassData->fromXML(riskClassNode);
585 }
586
587 // Risk class correlations
588 auto rcCorrsNode = XMLUtils::getChildNode(node, "RiskClassCorrelations");
590 for (auto rcCorrNode : XMLUtils::getChildrenNodes(rcCorrsNode, "Correlation")) {
591 Amount amount(rcCorrNode);
592 riskClassCorrelations_[amount.key()] = amount.value();
593 }
594}
595
597 XMLNode* node = doc.allocNode("SIMMCalibrationData");
598 for (const auto& [simmCalibrationId, simmCalibration] : data_) {
599 XMLUtils::appendNode(node, simmCalibration->toXML(doc));
600 }
601 return node;
602}
603
605 XMLUtils::checkNode(node, "SIMMCalibrationData");
606 vector<XMLNode*> simmCalibrationNodes = XMLUtils::getChildrenNodes(node, "SIMMCalibration");
607 for (XMLNode* scNode : simmCalibrationNodes) {
608 try {
609 add(QuantLib::ext::make_shared<SimmCalibration>(scNode));
610 } catch (const std::exception& ex) {
611 ore::data::StructuredConfigurationErrorMessage("SIMM calibration data", "",
612 "SIMM calibration node failed to parse", ex.what())
613 .log();
614 }
615 }
616}
617
618void SimmCalibrationData::add(const QuantLib::ext::shared_ptr<SimmCalibration>& simmCalibration) {
619
620 const string configurationType = "SIMM calibration data";
621 const string exceptionType = "Adding SIMM calibration";
622
623 // Check for SIMM calibration ID duplicates
624 if (data_.find(simmCalibration->id()) != data_.end()) {
626 configurationType, simmCalibration->id(), exceptionType,
627 "Cannot add SIMM calibration data since data with the same ID already exists.")
628 .log();
629 return;
630 }
631
632 // Check for SIMM version name clashes
633 const auto& incVersionNames = simmCalibration->versionNames();
634 for (const auto& [id, sc] : data_) {
635 for (const string& incName : incVersionNames) {
636 for (const string& currName : sc->versionNames()) {
637 if (incName == currName) {
638 const string msg = "SIMM calibration has duplicate version name '" + incName +
639 "' (added under calibration id='" + id +
640 "'). SIMM calibration will not be added.";
641 ore::data::StructuredConfigurationWarningMessage(configurationType, simmCalibration->id(),
642 exceptionType, msg)
643 .log();
644 return;
645 }
646 }
647 }
648 }
649
650 data_[simmCalibration->id()] = simmCalibration;
651}
652
653const QuantLib::ext::shared_ptr<SimmCalibration>& SimmCalibrationData::getById(const string& id) const {
654 if (!hasId(id))
655 QL_FAIL("Could not find SIMM calibration with ID '" << id << "'");
656
657 return data_.at(id);
658}
659
660const QuantLib::ext::shared_ptr<SimmCalibration> SimmCalibrationData::getBySimmVersion(const string& version) const {
661 for (const auto& kv : data_) {
662 const auto& simmCalibrationData = kv.second;
663 for (const string& scVersion : simmCalibrationData->versionNames()) {
664 if (scVersion == version) {
665 return simmCalibrationData;
666 }
667 }
668 }
669
670 return nullptr;
671}
672
673} // namespace analytics
674} // namespace ore
void fromXML(ore::data::XMLNode *node) override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
const std::tuple< std::string, std::string, std::string > key() const
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
virtual const std::map< CrifRecord::RiskType, std::map< QuantLib::Size, QuantLib::ext::shared_ptr< Amount > > > uniqueRiskWeights() const override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
virtual const std::map< CrifRecord::RiskType, std::map< QuantLib::Size, QuantLib::ext::shared_ptr< Amount > > > uniqueRiskWeights() const override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
void fromXML(ore::data::XMLNode *node) override
QuantLib::ext::shared_ptr< ConcentrationThresholds > concentrationThresholds_
QuantLib::ext::shared_ptr< Correlations > correlations_
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
QuantLib::ext::shared_ptr< RiskWeights > riskWeights_
const QuantLib::ext::shared_ptr< Correlations > & correlations() const
const QuantLib::ext::shared_ptr< RiskWeights > & riskWeights() const
void fromXML(ore::data::XMLNode *node) override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
void add(const QuantLib::ext::shared_ptr< SimmCalibration > &)
const QuantLib::ext::shared_ptr< SimmCalibration > getBySimmVersion(const std::string &id) const
const QuantLib::ext::shared_ptr< SimmCalibration > & getById(const std::string &id) const
const std::string & version() const
const std::vector< std::pair< std::string, std::string > > & additionalFields() const
const std::map< SimmConfiguration::RiskClass, QuantLib::ext::shared_ptr< RiskClassData > > & riskClassData() const
void fromXML(ore::data::XMLNode *node) override
const std::vector< std::string > & versionNames() const
std::vector< std::string > versionNames_
std::vector< std::pair< std::string, std::string > > additionalFields_
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
std::map< SimmConfiguration::RiskClass, QuantLib::ext::shared_ptr< RiskClassData > > riskClassData_
XMLNode * allocNode(const string &nodeName)
static void addAttribute(XMLDocument &doc, XMLNode *node, const string &attrName, const string &attrValue)
static string getAttribute(XMLNode *node, const string &attrName)
static void checkNode(XMLNode *n, const string &expectedName)
static vector< XMLNode * > getChildrenNodes(XMLNode *node, const string &name)
static string getNodeName(XMLNode *n)
static XMLNode * getChildNode(XMLNode *n, const string &name="")
static string getNodeValue(XMLNode *node)
static XMLNode * getNextSibling(XMLNode *node, const string &name="")
static void setNodeName(XMLDocument &doc, XMLNode *node, const string &name)
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
static void appendNode(XMLNode *parent, XMLNode *child)
Integer parseInteger(const string &s)
std::string to_string(const LocationInfo &l)
SIMM class for defining SIMM risk weights, thresholds, buckets, and labels. Currently only supports t...
string name