46 LOG(
"Load stress test label " << test.
label);
57 LOG(
"Get recovery rate shift parameters");
65 LOG(
"Loading stress parameters for recovery rate for " << isin);
72 LOG(
"Get survival probability shift parameters");
74 QL_REQUIRE(survivalProbability,
"Survival Probabilities node not found");
79 LOG(
"Loading stress parameters for survival probability for " <<
name);
84 QL_REQUIRE(
data.shifts.size() ==
data.shiftTenors.size(),
85 "number of tenors and shifts does not match in survival probability stress data");
86 QL_REQUIRE(
data.shifts.size() > 0,
"no shifts provided in survival probability stress data");
90 LOG(
"Get discount curve shift parameters");
92 QL_REQUIRE(discountCurves,
"DiscountCurves node not found");
97 LOG(
"Loading stress parameters for discount curve for ccy " << ccy);
102 QL_REQUIRE(
data.shifts.size() ==
data.shiftTenors.size(),
103 "number of tenors (" <<
data.shiftTenors.size() <<
")and shifts (" <<
data.shifts.size()
104 <<
") does not match in discount curve stress data for ccy = " << ccy);
105 QL_REQUIRE(
data.shifts.size() > 0,
"no shifts provided in discount curve stress data for ccy = " << ccy);
109 LOG(
"Get index curve stress parameters");
111 QL_REQUIRE(indexCurves,
"IndexCurves node not found");
116 LOG(
"Loading stress parameters for index " << index);
122 QL_REQUIRE(
data.shifts.size() ==
data.shiftTenors.size(),
123 "number of tenors (" <<
data.shiftTenors.size() <<
")and shifts (" <<
data.shifts.size()
124 <<
") does not match in index curve stress data curve = " << index);
125 QL_REQUIRE(
data.shifts.size() > 0,
"no shifts provided in index curve stress data curve = " << index);
129 LOG(
"Get yield curve stress parameters");
131 QL_REQUIRE(yieldCurves,
"YieldCurves node not found");
136 LOG(
"Loading stress parameters for yield curve " <<
name);
142 QL_REQUIRE(
data.shifts.size() ==
data.shiftTenors.size(),
143 "number of tenors (" <<
data.shiftTenors.size() <<
")and shifts (" <<
data.shifts.size()
144 <<
") does not match in yield curve stress data curve = " <<
name);
145 QL_REQUIRE(
data.shifts.size() > 0,
"no shifts provided in yield curve stress data curve = " <<
name);
149 LOG(
"Get FX spot stress parameters");
151 QL_REQUIRE(fxSpots,
"FxSpots node not found");
156 LOG(
"Loading stress parameters for FX " << ccypair);
163 LOG(
"Get fx vol stress parameters");
170 LOG(
"Loading stress parameters for FX vols " << ccypair);
178 LOG(
"Get Equity spot stress parameters");
185 LOG(
"Loading stress parameters for Equity " << equity);
192 LOG(
"Get equity vol stress parameters");
194 QL_REQUIRE(equityVols,
"EquityVolatilities node not found");
199 LOG(
"Loading stress parameters for Equity vols " << equity);
207 LOG(
"Get swaption vol stress parameters");
209 QL_REQUIRE(swaptionVols,
"SwaptionVols node not found");
214 LOG(
"Loading stress parameters for swaption vols " << ccy);
220 data.parallelShiftSize = 0.0;
225 if (expiry ==
"" && term ==
"")
228 QL_REQUIRE(expiry !=
"" && term !=
"",
"expiry and term attributes required on shift size nodes");
232 pair<Period, Period> key(e, t);
239 LOG(
"Get cap/floor vol stress parameters");
241 QL_REQUIRE(capVols,
"CapVols node not found");
248 if (!ccyAttr.empty()) {
250 WLOG(
"StressScenarioData: 'ccy' is deprecated as an attribute for CapFloorVolatilities, use 'key' "
263 QL_REQUIRE((
data.shiftStrikes.empty() &&
data.shifts[tenor].size() == 1) ||
264 (
data.shifts[tenor].size() ==
data.shiftStrikes.size()),
265 "StressScenarioData: CapFloor " << key <<
": Mismatch between size of strikes ("
266 <<
data.shiftStrikes.size() <<
") and shifts ("
267 <<
data.shifts[tenor].size() <<
") for tenor "
270 QL_REQUIRE(
data.shifts.size() ==
data.shiftExpiries.size(),
271 "StressScenarioData: CapFloor " << key <<
": Mismatch between size of expiries ("
272 <<
data.shiftExpiries.size() <<
") and shifts("
273 <<
data.shifts.size() <<
")");
276 LOG(
"Get Security spread stress parameters");
278 QL_REQUIRE(securitySpreads,
"SecuritySpreads node not found");
283 LOG(
"Loading stress parameters for Security spreads " << bond);
289 data_.push_back(test);
290 LOG(
"Loading stress test label " << test.
label <<
" done");
292 LOG(
"Loading stress tests done");
296 const std::map<std::string, StressTestScenarioData::CurveShiftData>& data,
297 const std::string& identifier,
const std::string& nodeName,
298 const std::string& parentNodeName = std::string()) {
299 std::string
name = parentNodeName.empty() ? nodeName +
"s" : parentNodeName;
301 for (
const auto& [key,
data] :
data) {
311 const std::map<std::string, StressTestScenarioData::VolShiftData>& data,
312 const std::string& identifier,
const std::string& nodeName,
const std::string& parentNodeName) {
314 for (
const auto& [key,
data] :
data) {
324 const std::map<std::string, StressTestScenarioData::SpotShiftData>& data,
325 const std::string& identifier,
const std::string& nodeName) {
327 for (
const auto& [key,
data] :
data) {
339 for (
const auto& test :
data_) {
346 XMLUtils::addChild(doc, parShiftsNode,
"CapFloorVolatilities", test.irCapFloorParShifts);
347 XMLUtils::addChild(doc, parShiftsNode,
"SurvivalProbability", test.creditCurveParShifts);
353 LOG(
"Write capFloor vol stress parameters");
355 for (
const auto& [key,
data] : test.capVolShifts) {
360 for (
const auto& [tenor, shifts] :
data.shifts) {
369 LOG(
"Write swaption vol stress parameters");
371 const std::vector<std::string> swaptionAttributeNames = {
"expiry",
"term"};
372 for (
const auto& [key,
data] : test.swaptionVolShifts) {
380 if (
data.shifts.empty()) {
382 swaptionAttributeNames, {
"",
""});
384 for (
const auto& [key, shift] :
data.shifts) {
385 const auto& [expiry, term] = key;
389 swaptionAttributeNames, attributeValues);
394 curveShiftDataToXml(doc, testNode, test.survivalProbabilityShifts,
"name",
"SurvivalProbability",
395 "SurvivalProbabilities");
397 spotShiftDataToXml(doc, testNode, test.securitySpreadShifts,
"security",
"SecuritySpread");
400 volShiftDataToXml(doc, testNode, test.equityVolShifts,
"equity",
"EquityVolatility",
"EquityVolatilities");
403 volShiftDataToXml(doc, testNode, test.fxVolShifts,
"ccypair",
"FxVolatility",
"FxVolatilities");
bool useSpreadedTermStructures_
virtual void fromXML(XMLNode *node) override
const vector< StressTestData > & data() const
virtual XMLNode * toXML(ore::data::XMLDocument &doc) const override
vector< StressTestData > data_
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 addGenericChildAsList(XMLDocument &doc, XMLNode *n, const string &name, const vector< T > &values, const string &attrName="", const string &attr="")
static void checkNode(XMLNode *n, const string &expectedName)
static Real getChildValueAsDouble(XMLNode *node, const string &name, bool mandatory=false, double defaultValue=0.0)
static XMLNode * locateNode(XMLNode *n, const string &name="")
static string getChildValue(XMLNode *node, const string &name, bool mandatory=false, const string &defaultValue=string())
static bool getChildValueAsBool(XMLNode *node, const string &name, bool mandatory=false, bool defaultValue=true)
static XMLNode * getChildNode(XMLNode *n, const string &name="")
static string getNodeValue(XMLNode *node)
static XMLNode * getNextSibling(XMLNode *node, const string &name="")
static vector< Real > getChildrenValuesAsDoublesCompact(XMLNode *node, const string &name, bool mandatory=false)
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
static vector< Period > getChildrenValuesAsPeriods(XMLNode *node, const string &name, bool mandatory=false)
static vector< Real > getNodeValueAsDoublesCompact(XMLNode *node)
SafeStack< ValueType > value
Period parsePeriod(const string &s)
bool parseBool(const string &s)
Real parseReal(const string &s)
void curveShiftDataToXml(ore::data::XMLDocument &doc, XMLNode *node, const std::map< std::string, StressTestScenarioData::CurveShiftData > &data, const std::string &identifier, const std::string &nodeName, const std::string &parentNodeName=std::string())
void volShiftDataToXml(ore::data::XMLDocument &doc, XMLNode *node, const std::map< std::string, StressTestScenarioData::VolShiftData > &data, const std::string &identifier, const std::string &nodeName, const std::string &parentNodeName)
void spotShiftDataToXml(ore::data::XMLDocument &doc, XMLNode *node, const std::map< std::string, StressTestScenarioData::SpotShiftData > &data, const std::string &identifier, const std::string &nodeName)
ShiftType parseShiftType(const std::string &s)
std::string to_string(const LocationInfo &l)
A class to hold the parametrisation for building sensitivity scenarios.
map< string, CurveShiftData > discountCurveShifts
bool creditCurveParShifts
map< string, CurveShiftData > yieldCurveShifts
map< string, VolShiftData > fxVolShifts
map< string, SpotShiftData > fxShifts
map< string, CurveShiftData > survivalProbabilityShifts
map< string, SpotShiftData > recoveryRateShifts
map< string, SwaptionVolShiftData > swaptionVolShifts
map< string, SpotShiftData > equityShifts
map< string, SpotShiftData > securitySpreadShifts
map< string, CapFloorVolShiftData > capVolShifts
map< string, CurveShiftData > indexCurveShifts
map< string, VolShiftData > equityVolShifts