Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
convertiblebonddata.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2021 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
23
24namespace ore {
25namespace data {
26
27using namespace ore::data;
28
29namespace {
30template <typename T> std::string toCommaSeparatedList(const std::vector<T>& d) {
31 std::ostringstream o;
32 for (Size i = 0; i < d.size(); ++i)
33 o << d[i] << (i < d.size() - 1 ? "," : "");
34 return o.str();
35}
36} // namespace
37
39 XMLUtils::checkNode(node, "ConversionRatioIncrease");
40 cap_ = XMLUtils::getChildValue(node, "Cap", false);
41 stockPrices_ = parseListOfValues<double>(XMLUtils::getChildValue(node, "StockPrices"), &parseReal);
42 std::vector<std::string> tmp = XMLUtils::getChildrenValuesWithAttributes(node, "CrIncreases", "CrIncrease",
43 "startDate", crIncreaseDates_, true);
44 for (auto const& t : tmp) {
45 crIncrease_.push_back(parseListOfValues<double>(t, &parseReal));
46 }
47 initialised_ = true;
48}
49
51 XMLNode* node = doc.allocNode("ConversionRatioIncrease");
52 if (!cap_.empty()) {
53 XMLUtils::addChild(doc, node, "Cap", cap_);
54 }
55 XMLUtils::addChild(doc, node, "StockPrices", toCommaSeparatedList(stockPrices_));
56 std::vector<std::string> tmp;
57 for (auto const& d : crIncrease_) {
58 tmp.push_back(toCommaSeparatedList(d));
59 }
60 XMLUtils::addChildrenWithAttributes(doc, node, "CrIncreases", "CrIncrease", tmp, "startDate", crIncreaseDates_);
61 return node;
62}
63
65 XMLUtils::checkNode(node, "MakeWhole");
66 if (auto tmp = XMLUtils::getChildNode(node, "ConversionRatioIncrease")) {
68 }
69 initialised_ = true;
70}
71
73 XMLNode* node = doc.allocNode("MakeWhole");
76 }
77 return node;
78}
79
82 dates_.fromXML(XMLUtils::getChildNode(node, "ScheduleData"));
83 styles_ = XMLUtils::getChildrenValuesWithAttributes(node, "Styles", "Style", "startDate", styleDates_, true);
84 prices_ = XMLUtils::getChildrenValuesWithAttributes<double>(node, "Prices", "Price", "startDate", priceDates_,
85 &parseReal, true);
87 XMLUtils::getChildrenValuesWithAttributes(node, "PriceTypes", "PriceType", "startDate", priceTypeDates_, true);
88 includeAccrual_ = XMLUtils::getChildrenValuesWithAttributes<bool>(
89 node, "IncludeAccruals", "IncludeAccrual", "startDate", includeAccrualDates_, &parseBool, true);
90 isSoft_ = XMLUtils::getChildrenValuesWithAttributes<bool>(node, "Soft", "Soft", "startDate", isSoftDates_,
91 &parseBool, false);
92 triggerRatios_ = XMLUtils::getChildrenValuesWithAttributes<double>(
93 node, "TriggerRatios", "TriggerRatio", "startDate", triggerRatioDates_, &parseReal, false);
94 nOfMTriggers_ = XMLUtils::getChildrenValuesWithAttributes(node, "NofMTriggers", "NofMTrigger", "startDate",
95 nOfMTriggerDates_, false);
96 if (auto tmp = XMLUtils::getChildNode(node, "MakeWhole")) {
98 }
99 initialised_ = true;
100}
101
103 XMLNode* node = doc.allocNode(nodeName_);
105 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "Styles", "Style", styles_, "startDate", styleDates_);
106 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "Prices", "Price", prices_, "startDate", priceDates_);
107 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "PriceTypes", "PriceType", priceTypes_, "startDate",
109 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "IncludeAccruals", "IncludeAccrual", includeAccrual_,
110 "startDate", includeAccrualDates_);
111 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "Soft", "Soft", isSoft_, "startDate", isSoftDates_);
112 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "TriggerRatios", "TriggerRatio", triggerRatios_, "startDate",
114 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "NOfMTriggers", "NOfMTrigger", nOfMTriggers_, "startDate",
118 }
119 return node;
120}
121
123 XMLUtils::checkNode(node, "ContingentConversion");
124 observations_ = XMLUtils::getChildrenValuesWithAttributes(node, "Observations", "Observation", "startDate",
125 observationDates_, true);
126 barriers_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node, "Barriers", "Barrier", "startDate", barrierDates_,
127 &parseReal, true);
128 initialised_ = true;
129}
130
132 XMLNode* node = doc.allocNode("ContingentConversion");
133 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "Observations", "Observation", observations_, "startDate",
134 observationDates_);
135 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "Barriers", "Barrier", barriers_, "startDate",
136 barrierDates_);
137 return node;
138}
139
141 XMLUtils::checkNode(node, "PepsData");
142 upperBarrier_ = XMLUtils::getChildValueAsDouble(node, "UpperBarrier", true);
143 lowerBarrier_ = XMLUtils::getChildValueAsDouble(node, "LowerBarrier", true);
144 upperConversionRatio_ = XMLUtils::getChildValueAsDouble(node, "UpperConversionRatio", true);
145 lowerConversionRatio_ = XMLUtils::getChildValueAsDouble(node, "LowerConversionRatio", true);
146 initialised_ = true;
147}
148
150 XMLNode* node = doc.allocNode("PepsData");
151 XMLUtils::addChild(doc, node, "UpperBarrier", upperBarrier_);
152 XMLUtils::addChild(doc, node, "LowerBarrier", upperBarrier_);
153 XMLUtils::addChild(doc, node, "UpperConversionRatio", upperConversionRatio_);
154 XMLUtils::addChild(doc, node, "LowerConversionRatio", lowerConversionRatio_);
155 return node;
156}
157
159 XMLUtils::checkNode(node, "MandatoryConversion");
160 date_ = XMLUtils::getChildValue(node, "Date", true);
161 type_ = XMLUtils::getChildValue(node, "Type", true);
162 if (auto tmp = XMLUtils::getChildNode(node, "PepsData")) {
163 if (!XMLUtils::getChildrenNodes(tmp, "").empty())
164 pepsData_.fromXML(tmp);
165 }
166 initialised_ = true;
167}
168
170 XMLNode* node = doc.allocNode("MandatoryConversion");
171 XMLUtils::addChild(doc, node, "Date", date_);
172 XMLUtils::addChild(doc, node, "Type", type_);
173 if (pepsData_.initialised())
174 XMLUtils::appendNode(node, pepsData_.toXML(doc));
175 return node;
176}
177
179 XMLUtils::checkNode(node, "ConversionResets");
180 dates_.fromXML(XMLUtils::getChildNode(node, "ScheduleData"));
181 references_ =
182 XMLUtils::getChildrenValuesWithAttributes(node, "References", "Reference", "startDate", referenceDates_, true);
183 thresholds_ = XMLUtils::getChildrenValuesWithAttributes<double>(node, "Thresholds", "Threshold", "startDate",
184 thresholdDates_, &parseReal, true);
185 gearings_ = XMLUtils::getChildrenValuesWithAttributes<double>(node, "Gearings", "Gearing", "startDate",
186 gearingDates_, &parseReal, true);
187 floors_ = XMLUtils::getChildrenValuesWithAttributes<double>(node, "Floors", "Floor", "startDate", floorDates_,
188 &parseReal, false);
189 globalFloors_ = XMLUtils::getChildrenValuesWithAttributes<double>(node, "GlobalFloors", "GlobalFloor", "startDate",
190 globalFloorDates_, &parseReal, false);
191
192 initialised_ = true;
193}
194
196 XMLNode* node = doc.allocNode("ConversionResets");
198 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "References", "Reference", references_, "startDate",
199 referenceDates_);
200 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "Thresholds", "Threshold", thresholds_, "startDate",
201 thresholdDates_);
202 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "Gearings", "Gearing", gearings_, "startDate",
203 gearingDates_);
204 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "Floors", "Floor", floors_, "startDate", floorDates_);
205 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "GlobalFloors", "GlobalFloor", globalFloors_, "startDate",
206 globalFloorDates_);
207 return node;
208}
209
211 XMLUtils::checkNode(node, "Exchangeable");
212 isExchangeable_ = XMLUtils::getChildValueAsBool(node, "IsExchangeable", true);
213 equityCreditCurve_ = XMLUtils::getChildValue(node, "EquityCreditCurve", isExchangeable_);
214 secured_ = false;
215 if (auto tmp = XMLUtils::getChildNode(node, "Secured")) {
216 if (!XMLUtils::getNodeValue(tmp).empty())
217 secured_ = parseBool(XMLUtils::getNodeValue(tmp));
218 }
219 initialised_ = true;
220}
221
223 XMLNode* node = doc.allocNode("Exchangeable");
224 XMLUtils::addChild(doc, node, "IsExchangeable", isExchangeable_);
225 XMLUtils::addChild(doc, node, "EquityCreditCurve", equityCreditCurve_);
226 XMLUtils::addChild(doc, node, "Secured", secured_);
227 return node;
228}
229
231 XMLUtils::checkNode(node, "FixedAmountConversion");
232 currency_ = XMLUtils::getChildValue(node, "Currency", true);
233 amounts_ = XMLUtils::getChildrenValuesWithAttributes<double>(node, "Amounts", "Amount", "startDate", amountDates_,
234 &parseReal, true);
235 initialised_ = true;
236}
237
239 XMLNode* node = doc.allocNode("FixedAmountConversion");
240 XMLUtils::addChild(doc, node, "Currency", currency_);
241 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "Amounts", "Amount", amounts_, "startDate", amountDates_);
242 return node;
243}
244
246 XMLUtils::checkNode(node, "ConversionData");
247 if (auto tmp = XMLUtils::getChildNode(node, "ScheduleData"))
248 dates_.fromXML(tmp);
249 styles_ = XMLUtils::getChildrenValuesWithAttributes(node, "Styles", "Style", "startDate", styleDates_, false);
250 conversionRatios_ = XMLUtils::getChildrenValuesWithAttributes<double>(
251 node, "ConversionRatios", "ConversionRatio", "startDate", conversionRatioDates_, &parseReal, false);
252 if (auto tmp = XMLUtils::getChildNode(node, "ContingentConversion")) {
253 if (!XMLUtils::getChildrenNodes(tmp, "").empty())
254 contingentConversionData_.fromXML(tmp);
255 }
256 if (auto tmp = XMLUtils::getChildNode(node, "MandatoryConversion")) {
257 if (!XMLUtils::getChildrenNodes(tmp, "").empty())
258 mandatoryConversionData_.fromXML(tmp);
259 }
260 if (auto tmp = XMLUtils::getChildNode(node, "ConversionResets")) {
261 if (!XMLUtils::getChildrenNodes(tmp, "").empty())
262 conversionResetData_.fromXML(tmp);
263 }
264 if (auto tmp = XMLUtils::getChildNode(node, "Underlying")) {
265 equityUnderlying_.fromXML(tmp);
266 }
267 fxIndex_ = XMLUtils::getChildValue(node, "FXIndex", false);
268 if (XMLUtils::getChildNode(node, "FXIndexFixingDays")) {
269 WLOG("ConvertibleBondData::fromXML, node FXIndexFixingDays has been deprecated, fixing days are "
270 "taken from conventions.");
271 }
272 if (XMLUtils::getChildNode(node, "FXIndexCalendar")) {
273 WLOG("ConvertibleBondData::fromXML, node FXIndexCalendar has been deprecated, fixing calendar is "
274 "taken from conventions.");
275 }
276 if (auto tmp = XMLUtils::getChildNode(node, "Exchangeable")) {
277 if (!XMLUtils::getChildrenNodes(tmp, "").empty())
278 exchangeableData_.fromXML(tmp);
279 }
280 if (auto tmp = XMLUtils::getChildNode(node, "FixedAmountConversion")) {
281 if (!XMLUtils::getChildrenNodes(tmp, "").empty())
282 fixedAmountConversionData_.fromXML(tmp);
283 }
284 initialised_ = true;
285}
286
288 XMLNode* node = doc.allocNode("ConversionData");
290 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "Styles", "Style", styles_, "startDate", styleDates_);
291 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "ConversionRatios", "ConversionRatio", conversionRatios_,
292 "startDate", conversionRatioDates_);
293 if (contingentConversionData_.initialised())
294 XMLUtils::appendNode(node, contingentConversionData_.toXML(doc));
295 if (mandatoryConversionData_.initialised())
296 XMLUtils::appendNode(node, mandatoryConversionData_.toXML(doc));
297 if (conversionResetData_.initialised())
298 XMLUtils::appendNode(node, conversionResetData_.toXML(doc));
299 XMLUtils::appendNode(node, equityUnderlying_.toXML(doc));
300 if (!fxIndex_.empty())
301 XMLUtils::addChild(doc, node, "FXIndex", fxIndex_);
302 if (exchangeableData_.initialised())
303 XMLUtils::appendNode(node, exchangeableData_.toXML(doc));
304 if (fixedAmountConversionData_.initialised())
305 XMLUtils::appendNode(node, fixedAmountConversionData_.toXML(doc));
306 return node;
307}
308
310 XMLUtils::checkNode(node, "DividendProtectionData");
311 dates_.fromXML(XMLUtils::getChildNode(node, "ScheduleData"));
312 adjustmentStyles_ = XMLUtils::getChildrenValuesWithAttributes(node, "AdjustmentStyles", "AdjustmentStyle",
313 "startDate", adjustmentStyleDates_, true);
314 dividendTypes_ = XMLUtils::getChildrenValuesWithAttributes(node, "DividendTypes", "DividendType", "startDate",
315 dividendTypeDates_, true);
316 thresholds_ = XMLUtils::getChildrenValuesWithAttributes<double>(node, "Thresholds", "Threshold", "startDate",
317 thresholdDates_, &parseReal, true);
318 initialised_ = true;
319}
320
322 XMLNode* node = doc.allocNode("DividendProtectionData");
324 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "AdjustmentStyles", "AdjustmentStyle", adjustmentStyles_,
325 "startDate", adjustmentStyleDates_);
326 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "DividendTypes", "DividendType", dividendTypes_, "startDate",
327 dividendTypeDates_);
328 XMLUtils::addChildrenWithOptionalAttributes(doc, node, "Thresholds", "Threshold", thresholds_, "startDate",
329 thresholdDates_);
330 return node;
331}
332
334 XMLUtils::checkNode(node, "ConvertibleBondData");
335 bondData_.fromXML(XMLUtils::getChildNode(node, "BondData"));
336 if (auto tmp = XMLUtils::getChildNode(node, "CallData")) {
337 if (!XMLUtils::getChildrenNodes(tmp, "").empty()) {
338 callData_.fromXML(tmp);
339 }
340 }
341 if (auto tmp = XMLUtils::getChildNode(node, "PutData")) {
342 if (!XMLUtils::getChildrenNodes(tmp, "").empty())
343 putData_.fromXML(tmp);
344 }
345 if (auto tmp = XMLUtils::getChildNode(node, "ConversionData")) {
346 if (!XMLUtils::getChildrenNodes(tmp, "").empty())
348 }
349 if (auto tmp = XMLUtils::getChildNode(node, "DividendProtectionData")) {
350 if (!XMLUtils::getChildrenNodes(tmp, "").empty())
352 }
353 detachable_ = XMLUtils::getChildValue(node, "Detachable");
354}
355
357 XMLNode* node = doc.allocNode("ConvertibleBondData");
361 if (putData_.initialised())
367 if (!detachable_.empty())
368 XMLUtils::addChild(doc, node, "Detachable", detachable_);
369 return node;
370}
371
373 const QuantLib::ext::shared_ptr<ore::data::ReferenceDataManager>& referenceData) {
374
375 QL_REQUIRE(!bondData_.securityId().empty(),
376 "ConvertibleBondData::populateFromBondReferenceData(): no security id given");
377 if (!referenceData || !referenceData->hasData(ConvertibleBondReferenceDatum::TYPE, bondData_.securityId())) {
378 DLOG("could not get ConvertibleBondReferenceDatum for name " << bondData_.securityId()
379 << " leave data in trade unchanged");
380 } else {
381 auto bondRefData = QuantLib::ext::dynamic_pointer_cast<ConvertibleBondReferenceDatum>(
382 referenceData->getData(ConvertibleBondReferenceDatum::TYPE, bondData_.securityId()));
383 QL_REQUIRE(bondRefData, "could not cast to ConvertibleBondReferenceDatum, this is unexpected");
384 DLOG("Got ConvertibleBondReferenceDatum for name " << bondData_.securityId()
385 << " overwrite empty elements in trade");
387 QuantLib::ext::make_shared<BondReferenceDatum>(bondData_.securityId(), bondRefData->bondData()));
388 if (!callData_.initialised()) {
389 DLOG("overwrite CallData from reference data")
390 callData_ = bondRefData->callData();
391 }
392 if (!putData_.initialised()) {
393 DLOG("overwrite PutData from reference data")
394 putData_ = bondRefData->putData();
395 }
397 DLOG("overwrite ConversionData from reference data")
398 conversionData_ = bondRefData->conversionData();
399 }
401 DLOG("overwrite DividendProtectionData from reference data")
402 dividendProtectionData_ = bondRefData->dividendProtectionData();
403 }
404 if (detachable_.empty()) {
405 DLOG("overwrite detachable from reference data");
406 detachable_ = bondRefData->detachable();
407 }
408 }
409}
410
411} // namespace data
412} // namespace ore
const string & securityId() const
Definition: bond.hpp:84
void populateFromBondReferenceData(const QuantLib::ext::shared_ptr< BondReferenceDatum > &referenceDatum, const std::string &startDate="", const std::string &endDate="")
populate data from reference datum and check data for completeness
Definition: bond.cpp:175
virtual void fromXML(XMLNode *node) override
XMLSerializable interface.
Definition: bond.cpp:59
virtual XMLNode * toXML(XMLDocument &doc) const override
Definition: bond.cpp:95
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
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
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
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
DividendProtectionData dividendProtectionData_
void populateFromBondReferenceData(const QuantLib::ext::shared_ptr< ore::data::ReferenceDataManager > &referenceData)
virtual void fromXML(XMLNode *node) override
Definition: schedule.cpp:179
virtual XMLNode * toXML(XMLDocument &doc) const override
Definition: schedule.cpp:198
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 addChildrenWithAttributes(XMLDocument &doc, XMLNode *n, const string &names, const string &name, const vector< T > &values, const string &attrName, const vector< string > &attrs)
Definition: xmlutils.cpp:510
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 Real getChildValueAsDouble(XMLNode *node, const string &name, bool mandatory=false, double defaultValue=0.0)
Definition: xmlutils.cpp:286
static string getChildValue(XMLNode *node, const string &name, bool mandatory=false, const string &defaultValue=string())
Definition: xmlutils.cpp:277
static bool getChildValueAsBool(XMLNode *node, const string &name, bool mandatory=false, bool defaultValue=true)
Definition: xmlutils.cpp:296
static XMLNode * getChildNode(XMLNode *n, const string &name="")
Definition: xmlutils.cpp:387
static void addChildrenWithOptionalAttributes(XMLDocument &doc, XMLNode *n, const string &names, const string &name, const vector< T > &values, const string &attrName, const vector< string > &attrs)
Definition: xmlutils.cpp:542
static string getNodeValue(XMLNode *node)
Get a node's value.
Definition: xmlutils.cpp:489
static vector< string > getChildrenValuesWithAttributes(XMLNode *node, const string &names, const string &name, const string &attrName, vector< string > &attrs, bool mandatory=false)
Definition: xmlutils.cpp:563
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
convertible bond data model and serialization
bool parseBool(const string &s)
Convert text to bool.
Definition: parsers.cpp:144
Real parseReal(const string &s)
Convert text to Real.
Definition: parsers.cpp:112
@ 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
Serializable Credit Default Swap.
Definition: namespaces.docs:23
Map text representations to QuantLib/QuantExt types.