Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
todaysmarketparameters.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 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
22using namespace QuantLib;
23
24namespace ore {
25namespace data {
26
27namespace {
28
29// container class to link the enum in the header with the various XML strings
30struct MarketObjectMetaInfo {
32 string name; // AKA marketObjectStrings
33 string xmlName; // AKA marketObjectXMLNames
34 pair<string, string> xmlSingleName; // AKA marketObjectXMLNamesSingle
35};
36
37// Note the order of elements in this array MUST respect the XML Schema
38static const vector<MarketObjectMetaInfo> marketObjectData = {
39 {MarketObject::YieldCurve, "YieldCurve", "YieldCurves", {"YieldCurve", "name"}},
40 {MarketObject::DiscountCurve, "DiscountCurve", "DiscountingCurves", {"DiscountingCurve", "currency"}},
41 {MarketObject::IndexCurve, "IndexCurve", "IndexForwardingCurves", {"Index", "name"}},
42 {MarketObject::SwapIndexCurve, "SwapIndexCurve", "SwapIndexCurves", {"SwapIndex", "name"}},
44 "ZeroInflationCurve",
45 "ZeroInflationIndexCurves",
46 {"ZeroInflationIndexCurve", "name"}},
47 {MarketObject::YoYInflationCurve, "YoYInflationCurve", "YYInflationIndexCurves", {"YYInflationIndexCurve", "name"}},
48 {MarketObject::FXSpot, "FXSpot", "FxSpots", {"FxSpot", "pair"}},
49 {MarketObject::FXVol, "FXVol", "FxVolatilities", {"FxVolatility", "pair"}},
50 {MarketObject::SwaptionVol, "SwaptionVol", "SwaptionVolatilities", {"SwaptionVolatility", "key"}},
51 {MarketObject::YieldVol, "YieldVol", "YieldVolatilities", {"YieldVolatility", "name"}},
52 {MarketObject::CapFloorVol, "CapFloorVol", "CapFloorVolatilities", {"CapFloorVolatility", "key"}},
53 {MarketObject::CDSVol, "CDSVol", "CDSVolatilities", {"CDSVolatility", "name"}},
54 {MarketObject::DefaultCurve, "DefaultCurve", "DefaultCurves", {"DefaultCurve", "name"}},
56 "YoYInflationCapFloorVol",
57 "YYInflationCapFloorVolatilities",
58 {"YYInflationCapFloorVolatility", "name"}},
60 "ZeroInflationCapFloorVol",
61 "ZeroInflationCapFloorVolatilities",
62 {"ZeroInflationCapFloorVolatility", "name"}},
63 {MarketObject::EquityCurve, "EquityCurves", "EquityCurves", {"EquityCurve", "name"}},
64 {MarketObject::EquityVol, "EquityVols", "EquityVolatilities", {"EquityVolatility", "name"}},
65 {MarketObject::Security, "Securities", "Securities", {"Security", "name"}},
66 {MarketObject::BaseCorrelation, "BaseCorrelation", "BaseCorrelations", {"BaseCorrelation", "name"}},
67 {MarketObject::CommodityCurve, "CommodityCurves", "CommodityCurves", {"CommodityCurve", "name"}},
69 "CommodityVolatilities",
70 "CommodityVolatilities",
71 {"CommodityVolatility", "name"}},
72 {MarketObject::Correlation, "Correlation", "Correlations", {"Correlation", "name"}}};
73
74} // anonymous namespace
75
76std::ostream& operator<<(std::ostream& out, const MarketObject& o) {
77 for (Size i = 0; i < marketObjectData.size(); i++) {
78 if (marketObjectData[i].obj == o)
79 return out << marketObjectData[i].name;
80 }
81 return out << "Unknown";
82}
83
84std::set<MarketObject> getMarketObjectTypes() {
85 thread_local static std::set<MarketObject> result;
86 if (result.empty()) {
87 for (auto const& o : marketObjectData) {
88 result.insert(o.obj);
89 }
90 }
91 return result;
92}
93
94MarketConfiguration::MarketConfiguration(map<MarketObject, string> marketObjectIds) {
95 for (Size i = 0; i < marketObjectData.size(); ++i) {
96 marketObjectIds_[marketObjectData[i].obj] = Market::defaultConfiguration;
97 }
98
99 for (const auto& moi : marketObjectIds)
100 setId(moi.first, moi.second);
101}
102
104 QL_REQUIRE(marketObjectIds_.find(o) != marketObjectIds_.end(),
105 "MarketConfiguration: did not find MarketObject " << o << " (this is unexpected)");
106 return marketObjectIds_.at(o);
107}
108
109void MarketConfiguration::setId(const MarketObject o, const string& id) {
110 if (id != "")
111 marketObjectIds_[o] = id;
112}
113
115 // overwrite if already existent
116 for (auto const& x : o.marketObjectIds_)
117 marketObjectIds_[x.first] = x.second;
118}
119
120void TodaysMarketParameters::addConfiguration(const string& id, const MarketConfiguration& configuration) {
121 if (hasConfiguration(id)) {
122 auto it =
123 find_if(configurations_.begin(), configurations_.end(),
124 [&id](const pair<string, MarketConfiguration>& s) { return s.first == id; });
125 it->second.add(configuration);
126 } else
127 configurations_.push_back(make_pair(id, configuration));
128}
129
131 // clear data members
132 configurations_.clear();
133 marketObjects_.clear();
134}
135
137 return marketObjects_.size() == 0;
138}
139
141
142 // add default configuration if we do not have one (may be overwritten below)
145
146 // fill data from XML
147 XMLUtils::checkNode(node, "TodaysMarket");
149 while (n) {
150 if (XMLUtils::getNodeName(n) == "Configuration") {
152 for (Size i = 0; i < marketObjectData.size(); ++i) {
153 tmp.setId(marketObjectData[i].obj,
154 XMLUtils::getChildValue(n, marketObjectData[i].xmlName + "Id", false));
156 }
157 } else {
158 Size i = 0;
159 for (; i < marketObjectData.size(); ++i) {
160 if (XMLUtils::getNodeName(n) == marketObjectData[i].xmlName) {
161 string id = XMLUtils::getAttribute(n, "id");
162 if (id == "")
164 // The XML schema for swap indices is different ...
165 if (marketObjectData[i].obj == MarketObject::SwapIndexCurve) {
166 vector<XMLNode*> nodes = XMLUtils::getChildrenNodes(n, marketObjectData[i].xmlSingleName.first);
167 map<string, string> swapIndices;
168 for (XMLNode* xn : nodes) {
169 string name = XMLUtils::getAttribute(xn, marketObjectData[i].xmlSingleName.second);
170 QL_REQUIRE(name != "", "no name given for SwapIndex");
171 QL_REQUIRE(swapIndices.find(name) == swapIndices.end(),
172 "Duplicate SwapIndex found for " << name);
173 string disc = XMLUtils::getChildValue(xn, "Discounting", true);
174 swapIndices[name] = disc; //.emplace(name, { ibor, disc }); won't work?
175 }
177
178 } else {
179 auto mp =
180 XMLUtils::getChildrenAttributesAndValues(n, marketObjectData[i].xmlSingleName.first,
181 marketObjectData[i].xmlSingleName.second, false);
182 // deprecated attribute currency for capfloor vols and swaption vols
183 if (marketObjectData[i].obj == MarketObject::CapFloorVol ||
184 marketObjectData[i].obj == MarketObject::SwaptionVol) {
186 n, marketObjectData[i].xmlSingleName.first, "currency", false);
187 if (!mp2.empty()) {
188 mp.insert(mp2.begin(), mp2.end());
189 WLOG("TodaysMarketParameters: the attribute 'currency' is deprecated for '" +
190 marketObjectData[i].xmlName + "', use 'key' instead.");
191 }
192 }
193 Size nc = XMLUtils::getChildrenNodes(n, "").size();
194 QL_REQUIRE(mp.size() == nc, "TodaysMarketParameters::fromXML(): possible duplicate entry in node "
195 << marketObjectData[i].xmlName << ", check for XMLUtils warnings.");
196 addMarketObject(marketObjectData[i].obj, id, mp);
197 }
198 break;
199 }
200 }
201 QL_REQUIRE(i < marketObjectData.size(),
202 "TodaysMarketParameters::fromXML(): node not recognized: " << XMLUtils::getNodeName(n));
203 }
205 } // while(n)
206}
207
209
210 XMLNode* todaysMarketNode = doc.allocNode("TodaysMarket");
211
212 // configurations
213 if (configurations_.size() > 0) {
214 for (auto iterator = configurations_.begin(); iterator != configurations_.end(); iterator++) {
215 XMLNode* configurationsNode = XMLUtils::addChild(doc, todaysMarketNode, "Configuration");
216 XMLUtils::addAttribute(doc, configurationsNode, "id", iterator->first.c_str());
217 for (Size i = 0; i < marketObjectData.size(); ++i) {
218 XMLUtils::addChild(doc, configurationsNode, marketObjectData[i].xmlName + "Id",
219 iterator->second(marketObjectData[i].obj)); // Added the "Id" for schema test
220 }
221 }
222 }
223
224 for (Size i = 0; i < marketObjectData.size(); ++i) {
225 if (marketObjects_.find(marketObjectData[i].obj) != marketObjects_.end()) {
226 auto mapping = marketObjects_.at(marketObjectData[i].obj);
227 for (auto mappingSetIterator = mapping.begin(); mappingSetIterator != mapping.end(); mappingSetIterator++) {
228
229 XMLNode* node = XMLUtils::addChild(doc, todaysMarketNode, marketObjectData[i].xmlName);
230 XMLUtils::addAttribute(doc, node, "id", mappingSetIterator->first.c_str());
231
232 for (auto singleMappingIterator = mappingSetIterator->second.begin();
233 singleMappingIterator != mappingSetIterator->second.end(); singleMappingIterator++) {
234 // Again, swap indices are different...
235 if (marketObjectData[i].obj == MarketObject::SwapIndexCurve) {
236 XMLNode* swapIndexNode = XMLUtils::addChild(doc, node, marketObjectData[i].xmlSingleName.first);
237 XMLUtils::addAttribute(doc, swapIndexNode, marketObjectData[i].xmlSingleName.second,
238 singleMappingIterator->first.c_str());
239 XMLUtils::addChild(doc, swapIndexNode, "Discounting",
240 (string)singleMappingIterator->second.c_str());
241 } else {
242 XMLNode* singleMappingNode =
243 doc.allocNode(marketObjectData[i].xmlSingleName.first, singleMappingIterator->second);
244 XMLUtils::appendNode(node, singleMappingNode);
245 XMLUtils::addAttribute(doc, singleMappingNode, marketObjectData[i].xmlSingleName.second,
246 singleMappingIterator->first);
247 }
248 }
249 }
250 }
251 }
252 return todaysMarketNode;
253}
254
255void TodaysMarketParameters::curveSpecs(const map<string, map<string, string>>& m, const string& id,
256 vector<string>& specs) const {
257 // extract all the curve specs
258 auto it = m.find(id);
259 if (it != m.end()) {
260 for (auto kv : it->second) {
261 specs.push_back(kv.second);
262 DLOG("Add spec " << kv.second);
263 }
264 }
265}
266
267vector<string> TodaysMarketParameters::curveSpecs(const string& configuration) const {
268 vector<string> specs;
269 for (Size i = 0; i < marketObjectData.size(); ++i) {
270 MarketObject mo = marketObjectData[i].obj;
271 // swap indices have to be excluded here...
272 if (mo != MarketObject::SwapIndexCurve && marketObjects_.find(mo) != marketObjects_.end()) {
273 curveSpecs(marketObjects_.at(mo), marketObjectId(mo, configuration), specs);
274 }
275 }
276 return specs;
277}
278
280 const map<string, string>& assignments) {
281
282 // check that we do not have an inconsistent mapping within one market object
283 auto mo = marketObjects_.find(o);
284 if (mo != marketObjects_.end()) {
285 auto mp = mo->second.find(id);
286 if (mp != mo->second.end()) {
287 for (auto const& m : mp->second) {
288 auto a = assignments.find(m.first);
289 if (a != assignments.end()) {
290 QL_REQUIRE(m.first != a->first || m.second == a->second,
291 "TodaysMarketParameters, inconsistent mapping is added for market object type "
292 << o << ", id " << id << ": " << a->first << " " << a->second << ", but have "
293 << m.first << " " << m.second << " already.");
294 }
295 }
296 }
297 }
298
299 // check that we do not have an overlap of names for yield curves and index curves
301 auto mo =
303 if (mo != marketObjects_.end()) {
304 auto mp = mo->second.find(id);
305 if (mp != mo->second.end()) {
306 for (auto const& m : mp->second) {
307 auto a = assignments.find(m.first);
308 QL_REQUIRE(a == assignments.end(),
309 "TodaysMarketParameters, overlap between YieldCurve and IndexCurve names, try to add "
310 "mapping for market object type "
311 << o << ", id " << id << ": " << a->first << " " << a->second << ", but have "
312 << m.first << " " << m.second << " already in other market object's mapping");
313 }
314 }
315 }
316 }
317
318 // add the mapping
319 marketObjects_[o][id].insert(assignments.begin(), assignments.end());
320 for (auto s : assignments)
321 DLOG("TodaysMarketParameters, add market objects of type " << o << ": " << id << " " << s.first << " "
322 << s.second);
323}
324
325const map<string, string>& TodaysMarketParameters::mapping(const MarketObject o, const string& configuration) const {
326 static map<string, string> empty;
327 QL_REQUIRE(hasConfiguration(configuration), "configuration " << configuration << " not found");
328 auto it = marketObjects_.find(o);
329 if (it != marketObjects_.end()) {
330 auto it2 = it->second.find(marketObjectId(o, configuration));
331 if (it2 != it->second.end()) {
332 return it2->second;
333 }
334 }
335 return empty;
336}
337
338map<string, string>& TodaysMarketParameters::mappingReference(const MarketObject o, const string& configuration) {
339 QL_REQUIRE(hasConfiguration(configuration), "configuration " << configuration << " not found");
340 auto it = marketObjects_.find(o);
341 if (it != marketObjects_.end()) {
342 auto it2 = it->second.find(marketObjectId(o, configuration));
343 if (it2 != it->second.end()) {
344 return it2->second;
345 } else {
346 return it->second[marketObjectId(o, configuration)];
347 }
348 } else {
349 return marketObjects_[o][marketObjectId(o, configuration)];
350 }
351}
352
353} // namespace data
354} // namespace ore
void setId(const MarketObject o, const string &id)
MarketConfiguration(map< MarketObject, string > marketObjectIds={})
map< MarketObject, string > marketObjectIds_
string operator()(const MarketObject o) const
void add(const MarketConfiguration &o)
static const string defaultConfiguration
Default configuration label.
Definition: market.hpp:296
vector< pair< string, MarketConfiguration > > configurations_
vector< string > curveSpecs(const string &configuration) const
Build a vector of all the curve specs (may contain duplicates)
bool hasConfiguration(const string &configuration) const
void addMarketObject(const MarketObject o, const string &id, const map< string, string > &assignments)
bool empty()
Check if any parameters.
const map< string, string > & mapping(const MarketObject o, const string &configuration) const
EUR => Yield/EUR/EUR6M, USD => Yield/USD/USD3M etc.
map< MarketObject, map< string, map< string, string > > > marketObjects_
void fromXML(XMLNode *node) override
XMLNode * toXML(XMLDocument &doc) const override
void addConfiguration(const string &name, const MarketConfiguration &configuration)
map< string, string > & mappingReference(const MarketObject o, const string &configuration)
return a mapping reference for modification
string marketObjectId(const MarketObject o, const string &configuration) const
Intermediate id for a given market object and configuration, see the description of configurations_ b...
Small XML Document wrapper class.
Definition: xmlutils.hpp:65
XMLNode * allocNode(const string &nodeName)
util functions that wrap rapidxml
Definition: xmlutils.cpp:132
static void addAttribute(XMLDocument &doc, XMLNode *node, const string &attrName, const string &attrValue)
Definition: xmlutils.cpp:412
static string getAttribute(XMLNode *node, const string &attrName)
Definition: xmlutils.cpp:419
static void checkNode(XMLNode *n, const string &expectedName)
Definition: xmlutils.cpp:175
static vector< XMLNode * > getChildrenNodes(XMLNode *node, const string &name)
Returns all the children with a given name.
Definition: xmlutils.cpp:428
static string getNodeName(XMLNode *n)
Get and set a node's name.
Definition: xmlutils.cpp:473
static map< string, string > getChildrenAttributesAndValues(XMLNode *parent, const string &names, const string &attributeName, bool mandatory=false)
Definition: xmlutils.cpp:365
static string getChildValue(XMLNode *node, const string &name, bool mandatory=false, const string &defaultValue=string())
Definition: xmlutils.cpp:277
static XMLNode * getChildNode(XMLNode *n, const string &name="")
Definition: xmlutils.cpp:387
static XMLNode * getNextSibling(XMLNode *node, const string &name="")
Get a node's next sibling node.
Definition: xmlutils.cpp:484
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
Definition: xmlutils.cpp:181
static void appendNode(XMLNode *parent, XMLNode *child)
Definition: xmlutils.cpp:406
Classes and functions for log message handling.
@ data
Definition: log.hpp:77
#define DLOG(text)
Logging Macro (Level = Debug)
Definition: log.hpp:554
#define WLOG(text)
Logging Macro (Level = Warning)
Definition: log.hpp:550
std::ostream & operator<<(std::ostream &out, EquityReturnType t)
MarketObject
Definition: market.hpp:65
std::set< MarketObject > getMarketObjectTypes()
Serializable Credit Default Swap.
Definition: namespaces.docs:23
pair< string, string > xmlSingleName
string name
string xmlName
MarketObject obj
A class to hold todays market configuration(s)