Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
stressscenariodata.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2017 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
23
24using namespace QuantLib;
25using namespace std;
26
27namespace ore {
28namespace analytics {
29
31 data_.clear();
32
33 XMLNode* node = XMLUtils::locateNode(root, "StressTesting");
34 XMLUtils::checkNode(node, "StressTesting");
35
37 ore::data::parseBool(XMLUtils::getChildValue(node, "UseSpreadedTermStructures", false, "false"));
38
39 for (XMLNode* testCase = XMLUtils::getChildNode(node, "StressTest"); testCase;
40 testCase = XMLUtils::getNextSibling(testCase)) {
41
42 StressTestData test;
43 test.label = XMLUtils::getAttribute(testCase, "id");
44 // XMLUtils::getChildValue(testCase, "Label", true);
45
46 LOG("Load stress test label " << test.label);
47
48 XMLNode* parShiftsNode = XMLUtils::getChildNode(testCase, "ParShifts");
49 if (parShiftsNode) {
50 test.irCurveParShifts = XMLUtils::getChildValueAsBool(parShiftsNode, "IRCurves", false, false);
52 XMLUtils::getChildValueAsBool(parShiftsNode, "CapFloorVolatilities", false, false);
54 XMLUtils::getChildValueAsBool(parShiftsNode, "SurvivalProbability", false, false);
55 }
56
57 LOG("Get recovery rate shift parameters");
58
59 test.recoveryRateShifts.clear();
60 XMLNode* recoveryRates = XMLUtils::getChildNode(testCase, "RecoveryRates");
61 if (recoveryRates) {
62 for (XMLNode* child = XMLUtils::getChildNode(recoveryRates, "RecoveryRate"); child;
63 child = XMLUtils::getNextSibling(child)) {
64 string isin = XMLUtils::getAttribute(child, "id");
65 LOG("Loading stress parameters for recovery rate for " << isin);
67 data.shiftSize = XMLUtils::getChildValueAsDouble(child, "ShiftSize", true);
68 data.shiftType = parseShiftType(XMLUtils::getChildValue(child, "ShiftType", true));
69 test.recoveryRateShifts[isin] = data;
70 }
71 }
72 LOG("Get survival probability shift parameters");
73 XMLNode* survivalProbability = XMLUtils::getChildNode(testCase, "SurvivalProbabilities");
74 QL_REQUIRE(survivalProbability, "Survival Probabilities node not found");
75 test.survivalProbabilityShifts.clear();
76 for (XMLNode* child = XMLUtils::getChildNode(survivalProbability, "SurvivalProbability"); child;
77 child = XMLUtils::getNextSibling(child)) {
78 string name = XMLUtils::getAttribute(child, "name");
79 LOG("Loading stress parameters for survival probability for " << name);
81 data.shiftType = parseShiftType(XMLUtils::getChildValue(child, "ShiftType", true));
82 data.shifts = XMLUtils::getChildrenValuesAsDoublesCompact(child, "Shifts", true);
83 data.shiftTenors = XMLUtils::getChildrenValuesAsPeriods(child, "ShiftTenors", true);
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");
88 }
89
90 LOG("Get discount curve shift parameters");
91 XMLNode* discountCurves = XMLUtils::getChildNode(testCase, "DiscountCurves");
92 QL_REQUIRE(discountCurves, "DiscountCurves node not found");
93 test.discountCurveShifts.clear();
94 for (XMLNode* child = XMLUtils::getChildNode(discountCurves, "DiscountCurve"); child;
95 child = XMLUtils::getNextSibling(child)) {
96 string ccy = XMLUtils::getAttribute(child, "ccy");
97 LOG("Loading stress parameters for discount curve for ccy " << ccy);
99 data.shiftType = parseShiftType(XMLUtils::getChildValue(child, "ShiftType", true));
100 data.shifts = XMLUtils::getChildrenValuesAsDoublesCompact(child, "Shifts", true);
101 data.shiftTenors = XMLUtils::getChildrenValuesAsPeriods(child, "ShiftTenors", true);
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);
106 test.discountCurveShifts[ccy] = data;
107 }
108
109 LOG("Get index curve stress parameters");
110 XMLNode* indexCurves = XMLUtils::getChildNode(testCase, "IndexCurves");
111 QL_REQUIRE(indexCurves, "IndexCurves node not found");
112 test.indexCurveShifts.clear();
113 for (XMLNode* child = XMLUtils::getChildNode(indexCurves, "IndexCurve"); child;
114 child = XMLUtils::getNextSibling(child)) {
115 string index = XMLUtils::getAttribute(child, "index");
116 LOG("Loading stress parameters for index " << index);
117 // same as discount curve sensitivity loading from here ...
119 data.shiftType = parseShiftType(XMLUtils::getChildValue(child, "ShiftType", true));
120 data.shifts = XMLUtils::getChildrenValuesAsDoublesCompact(child, "Shifts", true);
121 data.shiftTenors = XMLUtils::getChildrenValuesAsPeriods(child, "ShiftTenors", true);
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);
126 test.indexCurveShifts[index] = data;
127 }
128
129 LOG("Get yield curve stress parameters");
130 XMLNode* yieldCurves = XMLUtils::getChildNode(testCase, "YieldCurves");
131 QL_REQUIRE(yieldCurves, "YieldCurves node not found");
132 test.yieldCurveShifts.clear();
133 for (XMLNode* child = XMLUtils::getChildNode(yieldCurves, "YieldCurve"); child;
134 child = XMLUtils::getNextSibling(child)) {
135 string name = XMLUtils::getAttribute(child, "name");
136 LOG("Loading stress parameters for yield curve " << name);
137 // same as discount curve sensitivity loading from here ...
139 data.shiftType = parseShiftType(XMLUtils::getChildValue(child, "ShiftType", true));
140 data.shifts = XMLUtils::getChildrenValuesAsDoublesCompact(child, "Shifts", true);
141 data.shiftTenors = XMLUtils::getChildrenValuesAsPeriods(child, "ShiftTenors", true);
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);
146 test.yieldCurveShifts[name] = data;
147 }
148
149 LOG("Get FX spot stress parameters");
150 XMLNode* fxSpots = XMLUtils::getChildNode(testCase, "FxSpots");
151 QL_REQUIRE(fxSpots, "FxSpots node not found");
152 test.fxShifts.clear();
153 for (XMLNode* child = XMLUtils::getChildNode(fxSpots, "FxSpot"); child;
154 child = XMLUtils::getNextSibling(child)) {
155 string ccypair = XMLUtils::getAttribute(child, "ccypair");
156 LOG("Loading stress parameters for FX " << ccypair);
158 data.shiftType = parseShiftType(XMLUtils::getChildValue(child, "ShiftType", true));
159 data.shiftSize = XMLUtils::getChildValueAsDouble(child, "ShiftSize", true);
160 test.fxShifts[ccypair] = data;
161 }
162
163 LOG("Get fx vol stress parameters");
164 XMLNode* fxVols = XMLUtils::getChildNode(testCase, "FxVolatilities");
165 test.fxVolShifts.clear();
166 if (fxVols) {
167 for (XMLNode* child = XMLUtils::getChildNode(fxVols, "FxVolatility"); child;
168 child = XMLUtils::getNextSibling(child)) {
169 string ccypair = XMLUtils::getAttribute(child, "ccypair");
170 LOG("Loading stress parameters for FX vols " << ccypair);
172 data.shiftType = parseShiftType(XMLUtils::getChildValue(child, "ShiftType"));
173 data.shifts = XMLUtils::getChildrenValuesAsDoublesCompact(child, "Shifts", true);
174 data.shiftExpiries = XMLUtils::getChildrenValuesAsPeriods(child, "ShiftExpiries", true);
175 test.fxVolShifts[ccypair] = data;
176 }
177 }
178 LOG("Get Equity spot stress parameters");
179 XMLNode* equitySpots = XMLUtils::getChildNode(testCase, "EquitySpots");
180 test.equityShifts.clear();
181 if (equitySpots) {
182 for (XMLNode* child = XMLUtils::getChildNode(equitySpots, "EquitySpot"); child;
183 child = XMLUtils::getNextSibling(child)) {
184 string equity = XMLUtils::getAttribute(child, "equity");
185 LOG("Loading stress parameters for Equity " << equity);
187 data.shiftType = parseShiftType(XMLUtils::getChildValue(child, "ShiftType", true));
188 data.shiftSize = XMLUtils::getChildValueAsDouble(child, "ShiftSize", true);
189 test.equityShifts[equity] = data;
190 }
191 }
192 LOG("Get equity vol stress parameters");
193 XMLNode* equityVols = XMLUtils::getChildNode(testCase, "EquityVolatilities");
194 QL_REQUIRE(equityVols, "EquityVolatilities node not found");
195 test.equityVolShifts.clear();
196 for (XMLNode* child = XMLUtils::getChildNode(equityVols, "EquityVolatility"); child;
197 child = XMLUtils::getNextSibling(child)) {
198 string equity = XMLUtils::getAttribute(child, "equity");
199 LOG("Loading stress parameters for Equity vols " << equity);
201 data.shiftType = parseShiftType(XMLUtils::getChildValue(child, "ShiftType"));
202 data.shifts = XMLUtils::getChildrenValuesAsDoublesCompact(child, "Shifts", true);
203 data.shiftExpiries = XMLUtils::getChildrenValuesAsPeriods(child, "ShiftExpiries", true);
204 test.equityVolShifts[equity] = data;
205 }
206
207 LOG("Get swaption vol stress parameters");
208 XMLNode* swaptionVols = XMLUtils::getChildNode(testCase, "SwaptionVolatilities");
209 QL_REQUIRE(swaptionVols, "SwaptionVols node not found");
210 test.swaptionVolShifts.clear();
211 for (XMLNode* child = XMLUtils::getChildNode(swaptionVols, "SwaptionVolatility"); child;
212 child = XMLUtils::getNextSibling(child)) {
213 string ccy = XMLUtils::getAttribute(child, "ccy");
214 LOG("Loading stress parameters for swaption vols " << ccy);
216 data.shiftType = parseShiftType(XMLUtils::getChildValue(child, "ShiftType", true));
217 data.shiftTerms = XMLUtils::getChildrenValuesAsPeriods(child, "ShiftTerms", true);
218 data.shiftExpiries = XMLUtils::getChildrenValuesAsPeriods(child, "ShiftExpiries", true);
219 XMLNode* shiftSizes = XMLUtils::getChildNode(child, "Shifts");
220 data.parallelShiftSize = 0.0;
221 for (XMLNode* child2 = XMLUtils::getChildNode(shiftSizes, "Shift"); child2;
222 child2 = XMLUtils::getNextSibling(child2)) {
223 string expiry = XMLUtils::getAttribute(child2, "expiry");
224 string term = XMLUtils::getAttribute(child2, "term");
225 if (expiry == "" && term == "")
226 data.parallelShiftSize = ore::data::parseReal(XMLUtils::getNodeValue(child2));
227 else {
228 QL_REQUIRE(expiry != "" && term != "", "expiry and term attributes required on shift size nodes");
229 Period e = ore::data::parsePeriod(expiry);
230 Period t = ore::data::parsePeriod(term);
232 pair<Period, Period> key(e, t);
233 data.shifts[key] = value;
234 }
235 }
236 test.swaptionVolShifts[ccy] = data;
237 }
238
239 LOG("Get cap/floor vol stress parameters");
240 XMLNode* capVols = XMLUtils::getChildNode(testCase, "CapFloorVolatilities");
241 QL_REQUIRE(capVols, "CapVols node not found");
242 test.capVolShifts.clear();
243 for (XMLNode* child = XMLUtils::getChildNode(capVols, "CapFloorVolatility"); child;
244 child = XMLUtils::getNextSibling(child)) {
245 string key = XMLUtils::getAttribute(child, "key");
246 if (key.empty()) {
247 string ccyAttr = XMLUtils::getAttribute(child, "ccy");
248 if (!ccyAttr.empty()) {
249 key = ccyAttr;
250 WLOG("StressScenarioData: 'ccy' is deprecated as an attribute for CapFloorVolatilities, use 'key' "
251 "instead.");
252 }
253 }
255 data.shiftType = parseShiftType(XMLUtils::getChildValue(child, "ShiftType", true));
256 data.shiftExpiries = XMLUtils::getChildrenValuesAsPeriods(child, "ShiftExpiries", true);
257 data.shiftStrikes = XMLUtils::getChildrenValuesAsDoublesCompact(child, "ShiftStrikes", false);
258 XMLNode* shiftSizesNode = XMLUtils::getChildNode(child, "Shifts");
259 for (XMLNode* shiftNode = XMLUtils::getChildNode(shiftSizesNode, "Shift"); shiftNode;
260 shiftNode = XMLUtils::getNextSibling(shiftNode)) {
261 Period tenor = ore::data::parsePeriod(XMLUtils::getAttribute(shiftNode, "tenor"));
262 data.shifts[tenor] = XMLUtils::getNodeValueAsDoublesCompact(shiftNode);
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 "
268 << ore::data::to_string(tenor));
269 }
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() << ")");
274 test.capVolShifts[key] = data;
275 }
276 LOG("Get Security spread stress parameters");
277 XMLNode* securitySpreads = XMLUtils::getChildNode(testCase, "SecuritySpreads");
278 QL_REQUIRE(securitySpreads, "SecuritySpreads node not found");
279 test.securitySpreadShifts.clear();
280 for (XMLNode* child = XMLUtils::getChildNode(securitySpreads, "SecuritySpread"); child;
281 child = XMLUtils::getNextSibling(child)) {
282 string bond = XMLUtils::getAttribute(child, "security");
283 LOG("Loading stress parameters for Security spreads " << bond);
285 data.shiftType = parseShiftType(XMLUtils::getChildValue(child, "ShiftType", true));
286 data.shiftSize = XMLUtils::getChildValueAsDouble(child, "ShiftSize", true);
287 test.securitySpreadShifts[bond] = data;
288 }
289 data_.push_back(test);
290 LOG("Loading stress test label " << test.label << " done");
291 }
292 LOG("Loading stress tests done");
293}
294
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;
300 auto parentNode = XMLUtils::addChild(doc, node, name);
301 for (const auto& [key, data] : data) {
302 auto childNode = XMLUtils::addChild(doc, parentNode, nodeName);
303 XMLUtils::addAttribute(doc, childNode, identifier, key);
304 XMLUtils::addChild(doc, childNode, "ShiftType", ore::data::to_string(data.shiftType));
305 XMLUtils::addGenericChildAsList(doc, childNode, "Shifts", data.shifts);
306 XMLUtils::addGenericChildAsList(doc, childNode, "ShiftTenors", data.shiftTenors);
307 }
308}
309
311 const std::map<std::string, StressTestScenarioData::VolShiftData>& data,
312 const std::string& identifier, const std::string& nodeName, const std::string& parentNodeName) {
313 auto parentNode = XMLUtils::addChild(doc, node, parentNodeName);
314 for (const auto& [key, data] : data) {
315 auto childNode = XMLUtils::addChild(doc, parentNode, nodeName);
316 XMLUtils::addAttribute(doc, childNode, identifier, key);
317 XMLUtils::addChild(doc, childNode, "ShiftType", ore::data::to_string(data.shiftType));
318 XMLUtils::addGenericChildAsList(doc, childNode, "Shifts", data.shifts);
319 XMLUtils::addGenericChildAsList(doc, childNode, "ShiftExpiries", data.shiftExpiries);
320 }
321}
322
324 const std::map<std::string, StressTestScenarioData::SpotShiftData>& data,
325 const std::string& identifier, const std::string& nodeName) {
326 auto parentNode = XMLUtils::addChild(doc, node, nodeName + "s");
327 for (const auto& [key, data] : data) {
328 auto childNode = XMLUtils::addChild(doc, parentNode, nodeName);
329 XMLUtils::addAttribute(doc, childNode, identifier, key);
330 XMLUtils::addChild(doc, childNode, "ShiftType", ore::data::to_string(data.shiftType));
331 XMLUtils::addChild(doc, childNode, "ShiftSize", data.shiftSize);
332 }
333}
334
336 XMLNode* node = doc.allocNode("StressTesting");
337
338 XMLUtils::addChild(doc, node, "UseSpreadedTermStructures", ore::data::to_string(useSpreadedTermStructures_));
339 for (const auto& test : data_) {
340 // Add test node
341 auto testNode = XMLUtils::addChild(doc, node, "StressTest");
342 XMLUtils::addAttribute(doc, testNode, "id", test.label);
343 // Add Par Shifts node
344 auto parShiftsNode = XMLUtils::addChild(doc, testNode, "ParShifts");
345 XMLUtils::addChild(doc, parShiftsNode, "IRCurves", test.irCurveParShifts);
346 XMLUtils::addChild(doc, parShiftsNode, "CapFloorVolatilities", test.irCapFloorParShifts);
347 XMLUtils::addChild(doc, parShiftsNode, "SurvivalProbability", test.creditCurveParShifts);
348 // IR
349 curveShiftDataToXml(doc, testNode, test.discountCurveShifts, "ccy", "DiscountCurve");
350 curveShiftDataToXml(doc, testNode, test.indexCurveShifts, "index", "IndexCurve");
351 curveShiftDataToXml(doc, testNode, test.yieldCurveShifts, "name", "YieldCurve");
352
353 LOG("Write capFloor vol stress parameters");
354 XMLNode* capFloorVolsNode = XMLUtils::addChild(doc, testNode, "CapFloorVolatilities");
355 for (const auto& [key, data] : test.capVolShifts) {
356 XMLNode* capFloorVolNode = XMLUtils::addChild(doc, capFloorVolsNode, "CapFloorVolatility");
357 XMLUtils::addAttribute(doc, capFloorVolNode, "key", key);
358 XMLUtils::addChild(doc, capFloorVolNode, "ShiftType", ore::data::to_string(data.shiftType));
359 XMLNode* shiftSizesNode = XMLUtils::addChild(doc, capFloorVolNode, "Shifts");
360 for (const auto& [tenor, shifts] : data.shifts) {
361 XMLUtils::addGenericChildAsList(doc, shiftSizesNode, "Shift", shifts, "tenor",
362 ore::data::to_string(tenor));
363 }
364 XMLUtils::addGenericChildAsList(doc, capFloorVolNode, "ShiftExpiries", data.shiftExpiries);
365 XMLUtils::addGenericChildAsList(doc, capFloorVolNode, "ShiftStrikes", data.shiftStrikes);
366 }
367 // SwaptionVolData
368 // TODO: SwaptionVolData Missing
369 LOG("Write swaption vol stress parameters");
370 XMLNode* swaptionVolsNode = XMLUtils::addChild(doc, testNode, "SwaptionVolatilities");
371 const std::vector<std::string> swaptionAttributeNames = {"expiry", "term"};
372 for (const auto& [key, data] : test.swaptionVolShifts) {
373 XMLNode* swaptionVolNode = XMLUtils::addChild(doc, swaptionVolsNode, "SwaptionVolatility");
374 XMLUtils::addAttribute(doc, swaptionVolNode, "ccy", key);
375 XMLUtils::addChild(doc, swaptionVolNode, "ShiftType", ore::data::to_string(data.shiftType));
376 XMLUtils::addGenericChildAsList(doc, swaptionVolNode, "ShiftTerms", data.shiftTerms);
377 XMLUtils::addGenericChildAsList(doc, swaptionVolNode, "ShiftExpiries", data.shiftExpiries);
378 XMLNode* shiftSizesNode = XMLUtils::addChild(doc, swaptionVolNode, "Shifts");
379
380 if (data.shifts.empty()) {
381 XMLUtils::addChild(doc, shiftSizesNode, "Shift", ore::data::to_string(data.parallelShiftSize),
382 swaptionAttributeNames, {"", ""});
383 } else {
384 for (const auto& [key, shift] : data.shifts) {
385 const auto& [expiry, term] = key;
386 std::vector<std::string> attributeValues = {ore::data::to_string(expiry),
388 XMLUtils::addChild(doc, shiftSizesNode, "Shift", ore::data::to_string(shift),
389 swaptionAttributeNames, attributeValues);
390 }
391 }
392 }
393 // Credit
394 curveShiftDataToXml(doc, testNode, test.survivalProbabilityShifts, "name", "SurvivalProbability",
395 "SurvivalProbabilities");
396 spotShiftDataToXml(doc, testNode, test.recoveryRateShifts, "id", "RecoveryRate");
397 spotShiftDataToXml(doc, testNode, test.securitySpreadShifts, "security", "SecuritySpread");
398 // Equity
399 spotShiftDataToXml(doc, testNode, test.equityShifts, "equity", "EquitySpot");
400 volShiftDataToXml(doc, testNode, test.equityVolShifts, "equity", "EquityVolatility", "EquityVolatilities");
401 // FX
402 spotShiftDataToXml(doc, testNode, test.fxShifts, "ccypair", "FxSpot");
403 volShiftDataToXml(doc, testNode, test.fxVolShifts, "ccypair", "FxVolatility", "FxVolatilities");
404 }
405 return node;
406}
407} // namespace analytics
408} // namespace ore
virtual void fromXML(XMLNode *node) override
const vector< StressTestData > & data() const
virtual XMLNode * toXML(ore::data::XMLDocument &doc) const override
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)
data
#define LOG(text)
#define WLOG(text)
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)
Definition: scenario.cpp:216
std::string to_string(const LocationInfo &l)
A class to hold the parametrisation for building sensitivity scenarios.
string name