26#include <boost/algorithm/string/join.hpp>
27#include <boost/algorithm/string.hpp>
66 auto amountNode = doc.
allocNode(
"Amount", value_);
84 return std::make_tuple(bucket_, label1_, label2_);
92 auto riskWeightsNode = doc.
allocNode(
"RiskWeights");
95 for (
const string& rwType : {
"Delta",
"Vega"}) {
96 auto& riskWeightsMap = rwType ==
"Delta" ? delta_ : vega_;
98 for (
const auto& [mpor,
riskWeights] : riskWeightsMap) {
102 Amount amount(rwKey, weight);
103 auto amountNode = amount.
toXML(doc);
112 for (
const auto& [mpor, amount] : historicalVolatilityRatio_) {
113 auto hvrNode = amount->toXML(doc);
119 return riskWeightsNode;
126 for (
const string& rwType : {
"Delta",
"Vega"}) {
127 auto& riskWeightsMap = rwType ==
"Delta" ? delta_ : vega_;
129 for (
XMLNode* rwNode : rwNodes) {
130 Size mpor = getMPOR(rwNode);
132 riskWeightsMap[mpor].clear();
133 for (
XMLNode* weightNode : weightNodes) {
134 Amount amount(weightNode);
135 riskWeightsMap[mpor][amount.
key()] = amount.
value();
142 for (
XMLNode* hvrNode : hvrNodes) {
143 Size mpor = getMPOR(hvrNode);
144 auto hvr = QuantLib::ext::make_shared<Amount>(hvrNode);
145 historicalVolatilityRatio_[mpor] = hvr;
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);
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);
179 return riskWeightsNode;
185 for (
const string& weightType : {
"Inflation",
"XCcyBasis"}) {
186 auto& weightMap = weightType ==
"Inflation" ? inflation_ : xCcyBasis_;
189 for (
XMLNode* weightTypeNode : weightTypeNodes) {
190 Size mpor = getMPOR(weightTypeNode);
191 auto amount = QuantLib::ext::make_shared<Amount>(weightTypeNode);
192 weightMap[mpor] = amount;
198 currencyLists_.clear();
201 currencyLists_[amount.
key()].insert(amount.
value());
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;
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;
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);
236 return riskWeightsNode;
244 currencyLists_.clear();
247 currencyLists_[amount.
key()].insert(amount.
value());
260 for (
const auto& [mpor, amount] : baseCorrelation_) {
261 auto rwNode = amount->toXML(doc);
267 return riskWeightsNode;
275 for (
XMLNode* baseCorrNode : baseCorrNodes) {
276 Size mpor = getMPOR(baseCorrNode);
277 auto baseCorrelation = QuantLib::ext::make_shared<Amount>(baseCorrNode);
278 baseCorrelation_[mpor] = baseCorrelation;
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;
286 for (
const auto& [mpor, rw] : baseCorrelation_)
287 urwMap[RT::BaseCorr][mpor] = rw;
293 auto correlationsNode = doc.
allocNode(
"Correlations");
296 for (
const string& corrType : {
"IntraBucket",
"InterBucket"}) {
297 auto&
correlations = corrType ==
"IntraBucket" ? intraBucketCorrelations_ : interBucketCorrelations_;
302 auto corrTypeNode = doc.
allocNode(corrType);
304 Amount amount(corrKey, corr);
305 auto correlationNode = amount.
toXML(doc);
312 return correlationsNode;
319 for (
const string& corrType : {
"IntraBucket",
"InterBucket"}) {
320 auto& correlationsMap = corrType ==
"IntraBucket" ? intraBucketCorrelations_ : interBucketCorrelations_;
321 correlationsMap.clear();
323 for (
XMLNode* corrNode : corrNodes) {
325 Amount amount(weightNode);
326 correlationsMap[amount.
key()] = amount.
value();
335 auto corrTypes = map<string, QuantLib::ext::shared_ptr<Amount>>(
336 {{
"SubCurves", subCurves_}, {
"Inflation", inflation_}, {
"XCcyBasis", xCcyBasis_}, {
"Outer", outer_}});
338 for (
const auto& [corrType, container] : corrTypes) {
339 auto correlationNode = container->toXML(doc);
344 return correlationsNode;
350 auto corrTypes = map<string, QuantLib::ext::shared_ptr<Amount>&>(
351 {{
"SubCurves", subCurves_}, {
"Inflation", inflation_}, {
"XCcyBasis", xCcyBasis_}, {
"Outer", outer_}});
353 for (
auto& [corrType, container] : corrTypes) {
355 container = QuantLib::ext::make_shared<Amount>(corrNode);
362 auto baseCorrelationNode = baseCorrelation_->toXML(doc);
366 return correlationsNode;
373 baseCorrelation_ = QuantLib::ext::make_shared<Amount>(baseCorrelationNode);
379 auto volatilityNode = volatility_->toXML(doc);
383 return correlationsNode;
390 volatility_ = QuantLib::ext::make_shared<Amount>(volatilityNode);
394 auto concThresholdsNode = doc.
allocNode(
"ConcentrationThresholds");
397 for (
const string& type : {
"Delta",
"Vega"}) {
398 auto& concThresholds = type ==
"Delta" ? delta_ : vega_;
401 for (
const auto& [ctKey, threshold] : concThresholds) {
402 Amount amount(ctKey, threshold);
403 auto amountNode = amount.
toXML(doc);
410 return concThresholdsNode;
417 for (
const string& concThresholdType : {
"Delta",
"Vega"}) {
418 auto& concThresholdsMap = concThresholdType ==
"Delta" ? delta_ : vega_;
419 concThresholdsMap.clear();
421 for (
XMLNode* concThresholdNode : concThresholdNodes) {
423 for (
XMLNode* thresholdNode : thresholdNodes) {
424 Amount amount(thresholdNode);
425 concThresholdsMap[amount.
key()] = amount.
value();
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);
447 return concThresholdsNode;
455 currencyLists_.clear();
458 currencyLists_[amount.
key()].insert(amount.
value());
474 return riskClassNode;
483 case (RC::InterestRate):
484 riskWeights_ = QuantLib::ext::make_shared<IRRiskWeights>(riskWeightsNode);
486 case (RC::CreditQualifying):
487 riskWeights_ = QuantLib::ext::make_shared<CreditQRiskWeights>(riskWeightsNode);
490 riskWeights_ = QuantLib::ext::make_shared<FXRiskWeights>(riskWeightsNode);
499 case (RC::InterestRate):
500 correlations_ = QuantLib::ext::make_shared<IRCorrelations>(correlationsNode);
502 case (RC::CreditQualifying):
503 correlations_ = QuantLib::ext::make_shared<CreditQCorrelations>(correlationsNode);
506 correlations_ = QuantLib::ext::make_shared<FXCorrelations>(correlationsNode);
509 correlations_ = QuantLib::ext::make_shared<Correlations>(correlationsNode);
544 auto rcNode = rcData->toXML(doc);
549 XMLNode* riskClassCorrelationsNode = doc.
allocNode(
"RiskClassCorrelations");
551 Amount amount(rcCorrKey, rcCorrelation);
552 auto corrNode = amount.
toXML(doc);
557 return simmCalibrationNode;
569 QL_REQUIRE(!
versionNames_.empty(),
"Must provide at least one version name for SIMM calibration");
580 { RC::InterestRate, RC::CreditQualifying, RC::CreditNonQualifying, RC::Equity, RC::Commodity, RC::FX }) {
582 auto riskClassData = QuantLib::ext::make_shared<RiskClassData>(rc);
591 Amount amount(rcCorrNode);
598 for (
const auto& [simmCalibrationId, simmCalibration] : data_) {
607 for (
XMLNode* scNode : simmCalibrationNodes) {
609 add(QuantLib::ext::make_shared<SimmCalibration>(scNode));
610 }
catch (
const std::exception& ex) {
612 "SIMM calibration node failed to parse", ex.what())
620 const string configurationType =
"SIMM calibration data";
621 const string exceptionType =
"Adding SIMM calibration";
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.")
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.";
650 data_[simmCalibration->id()] = simmCalibration;
655 QL_FAIL(
"Could not find SIMM calibration with ID '" <<
id <<
"'");
661 for (
const auto& kv : data_) {
662 const auto& simmCalibrationData = kv.second;
663 for (
const string& scVersion : simmCalibrationData->versionNames()) {
665 return simmCalibrationData;
void fromXML(ore::data::XMLNode *node) override
const std::string & value() const
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
const std::tuple< std::string, std::string, std::string > key() const
void fromXML(ore::data::XMLNode *node) override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
void fromXML(ore::data::XMLNode *node) override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
void fromXML(ore::data::XMLNode *node) override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
CreditQRiskWeights(ore::data::XMLNode *node)
void fromXML(ore::data::XMLNode *node) 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
void fromXML(ore::data::XMLNode *node) override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
void fromXML(ore::data::XMLNode *node) override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
FXRiskWeights(ore::data::XMLNode *node)
void fromXML(ore::data::XMLNode *node) override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
void fromXML(ore::data::XMLNode *node) override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
IRRiskWeights(ore::data::XMLNode *node)
void fromXML(ore::data::XMLNode *node) 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
void fromXML(ore::data::XMLNode *node) override
ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
void fromXML(ore::data::XMLNode *node) override
SimmConfiguration::RiskClass riskClass_
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
Amounts riskClassCorrelations_
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...