Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
irhwmodeldata.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2022 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
24
25#include <ql/quotes/simplequote.hpp>
26#include <ql/utilities/dataformatters.hpp>
27
28#include <boost/algorithm/string/case_conv.hpp>
29#include <boost/lexical_cast.hpp>
30
31namespace ore {
32namespace data {
33
35
40 return false;
41 }
42 return true;
43}
44
45bool HwModelData::operator!=(const HwModelData& rhs) { return !(*this == rhs); }
46
48 optionExpiries_.clear();
49 optionTerms_.clear();
50 optionStrikes_.clear();
51}
52
56 calibrateKappa_ = false;
58 kappaTimes_ = {};
59 kappaValues_ = {Array(1, 0.01)};
60 calibrateSigma_ = false;
62 sigmaTimes_ = {};
63 sigmaValues_ = {Matrix(1, 1, 0.03)};
64}
65
67
69 if (qualifier_.empty()) {
70 std::string ccy = XMLUtils::getAttribute(node, "ccy");
71 if (!ccy.empty()) {
73 WLOG("HwModelData: attribute ccy is deprecated, use key instead.");
74 }
75 }
76 LOG("HwModelData with attribute (key) = " << qualifier_);
77
78 // Mean reversion config
79
80 XMLNode* reversionNode = XMLUtils::getChildNode(node, "Reversion");
81
82 calibrateKappa_ = XMLUtils::getChildValueAsBool(reversionNode, "Calibrate", true);
83 LOG("Hull White mean reversion calibrate = " << calibrateKappa_);
84 QL_REQUIRE(!calibrateKappa_, "Calibration of kappa not supported yet");
85
86 std::string kappaCalibrationString = XMLUtils::getChildValue(reversionNode, "ParamType", true);
87 kappaType_ = parseParamType(kappaCalibrationString);
88 LOG("Hull White Kappa param type = " << kappaCalibrationString);
89 QL_REQUIRE(kappaType_ == ParamType::Constant, "Only constant mean reversion supported at the moment");
90
91 kappaTimes_ = XMLUtils::getChildrenValuesAsDoublesCompact(reversionNode, "TimeGrid", true);
92 LOG("Hull White Reversion time grid size = " << kappaTimes_.size());
93
94 XMLNode* initialValuesNode = XMLUtils::getChildNode(reversionNode, "InitialValue");
95 for (XMLNode* child = XMLUtils::getChildNode(initialValuesNode, "Kappa"); child;
96 child = XMLUtils::getNextSibling(child, "Kappa")) {
97 auto kappa_t = XMLUtils::getNodeValueAsDoublesCompact(child);
98 kappaValues_.push_back(Array(kappa_t.begin(), kappa_t.end()));
99 }
100
101 QL_REQUIRE(!kappaValues_.empty(), "No initial mean reversion values given");
102 size_t nFactors = kappaValues_.front().size();
103 for (size_t i = 1; i < kappaValues_.size(); ++i) {
104 QL_REQUIRE(nFactors == kappaValues_[i].size(), "expect " << nFactors << " factors but got "
105 << kappaValues_[i].size() << " at time "
106 << kappaTimes_[i]);
107 }
108
109 // Volatility config
110
111 XMLNode* volatilityNode = XMLUtils::getChildNode(node, "Volatility");
112
113 calibrateSigma_ = XMLUtils::getChildValueAsBool(volatilityNode, "Calibrate", true);
114 LOG("Hull White volatility calibrate = " << calibrateSigma_);
115 QL_REQUIRE(!calibrateSigma_, "Calibration of kappa not supported yet");
116
117 std::string sigmaParameterTypeString = XMLUtils::getChildValue(volatilityNode, "ParamType", true);
118 sigmaType_ = parseParamType(sigmaParameterTypeString);
119 LOG("Hull White Volatility param type = " << sigmaParameterTypeString);
120 QL_REQUIRE(sigmaType_ == ParamType::Constant, "Only constant constant supported at the moment");
121
122 sigmaTimes_ = XMLUtils::getChildrenValuesAsDoublesCompact(volatilityNode, "TimeGrid", true);
123 LOG("Hull White volatility time grid size = " << sigmaTimes_.size());
124
125 XMLNode* initialSigmasNode = XMLUtils::getChildNode(volatilityNode, "InitialValue");
126 for (XMLNode* sigmaNode = XMLUtils::getChildNode(initialSigmasNode, "Sigma"); sigmaNode;
127 sigmaNode = XMLUtils::getNextSibling(sigmaNode, "Sigma")) {
128 std::vector<std::vector<double>> matrix;
129 for (XMLNode* rowNode = XMLUtils::getChildNode(sigmaNode, "Row"); rowNode;
130 rowNode = XMLUtils::getNextSibling(rowNode, "Row")) {
131 matrix.push_back(XMLUtils::getNodeValueAsDoublesCompact(rowNode));
132 QL_REQUIRE(matrix.back().size() == nFactors, "Mismatch between kappa and sigma");
133 }
134 QL_REQUIRE(!matrix.empty(), "Sigma not provided");
135 QL_REQUIRE(!matrix.front().empty(), "Sigma not provided");
136 Matrix sigma(matrix.size(), matrix.front().size(), 0.0);
137 for (size_t i = 0; i < matrix.size(); ++i) {
138 for (size_t j = 0; j < nFactors; ++j)
139 sigma[i][j] = matrix[i][j];
140 }
141 sigmaValues_.push_back(sigma);
142 }
143
144 QL_REQUIRE(!sigmaValues_.empty(), "need at least one sigma matrix");
145 size_t m_brownians = sigmaValues_.front().rows();
146 for (size_t i = 0; i < sigmaValues_.size(); ++i) {
147 QL_REQUIRE(sigmaValues_[i].rows() == m_brownians, "all sigma matrixes need to have the same row dimension");
148 }
149
151 LOG("HwModelData done");
152}
153
155
156 XMLNode* hwModelNode = IrModelData::toXML(doc);
157 // reversion
158 XMLNode* reversionNode = XMLUtils::addChild(doc, hwModelNode, "Reversion");
159 XMLUtils::addChild(doc, reversionNode, "Calibrate", calibrateKappa_);
160 XMLUtils::addGenericChild(doc, reversionNode, "ParamType", kappaType_);
161 XMLUtils::addGenericChildAsList(doc, reversionNode, "TimeGrid", kappaTimes_);
162
163 auto kappaNode = XMLUtils::addChild(doc, reversionNode, "InitialValue");
164 for (const auto& kappa : kappaValues_) {
165 std::ostringstream oss;
166 if (kappa.size() == 0) {
167 oss << "";
168 } else {
169 oss << kappa[0];
170 for (Size i = 1; i < kappa.size(); i++) {
171 oss << ", " << kappa[i];
172 }
173 }
174 XMLUtils::addChild(doc, kappaNode, "Kappa", oss.str());
175 }
176 // volatility
177 XMLNode* volatilityNode = XMLUtils::addChild(doc, hwModelNode, "Volatility");
178 XMLUtils::addChild(doc, volatilityNode, "Calibrate", calibrateSigma_);
179
180 XMLUtils::addGenericChild(doc, volatilityNode, "ParamType", sigmaType_);
181 XMLUtils::addGenericChildAsList(doc, volatilityNode, "TimeGrid", sigmaTimes_);
182
183 auto sigmaValues = XMLUtils::addChild(doc, reversionNode, "InitialValue");
184 for (const auto& sigma : sigmaValues_) {
185 auto sigmaNode = XMLUtils::addChild(doc, sigmaValues, "Sigma");
186 for (size_t row = 0; row < sigma.rows(); ++row) {
187 std::ostringstream oss;
188 if (sigma.columns() == 0) {
189 oss << "";
190 } else {
191 oss << sigma[row][0];
192 for (Size col = 0; col < sigma.columns(); col++) {
193 oss << ", " << sigma[row][col];
194 }
195 }
196 XMLUtils::addChild(doc, sigmaNode, "Row", oss.str());
197 }
198 }
199 return hwModelNode;
200}
201
202} // namespace data
203} // namespace ore
Hull White Model Parameters.
std::vector< QuantLib::Matrix > & sigmaValues()
std::vector< QuantLib::Array > kappaValues_
std::vector< std::string > optionTerms_
bool operator==(const HwModelData &rhs)
std::vector< std::string > optionExpiries_
std::vector< QuantLib::Matrix > sigmaValues_
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
std::vector< Time > kappaTimes_
std::vector< Time > sigmaTimes_
bool operator!=(const HwModelData &rhs)
void reset() override
Reset member variables to defaults.
void clear() override
Clear list of calibration instruments.
std::vector< std::string > optionStrikes_
CalibrationType calibrationType_
virtual std::string ccy() const
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
virtual void reset()
Reset member variables to defaults.
Small XML Document wrapper class.
Definition: xmlutils.hpp:65
static string getAttribute(XMLNode *node, const string &attrName)
Definition: xmlutils.cpp:419
static void addGenericChildAsList(XMLDocument &doc, XMLNode *n, const string &name, const vector< T > &values, const string &attrName="", const string &attr="")
Definition: xmlutils.hpp:144
static void addGenericChild(XMLDocument &doc, XMLNode *n, const char *name, const T &value)
Adds <Name>p1,p2,p3</Name>
Definition: xmlutils.hpp:137
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 XMLNode * getNextSibling(XMLNode *node, const string &name="")
Get a node's next sibling node.
Definition: xmlutils.cpp:484
static vector< Real > getChildrenValuesAsDoublesCompact(XMLNode *node, const string &name, bool mandatory=false)
Definition: xmlutils.cpp:327
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
Definition: xmlutils.cpp:181
static vector< Real > getNodeValueAsDoublesCompact(XMLNode *node)
Get a node's compact values as vector of doubles.
Definition: xmlutils.cpp:332
configuration class for building correlation matrices
Hull White model data.
Classes and functions for log message handling.
@ data
Definition: log.hpp:77
#define LOG(text)
Logging Macro (Level = Notice)
Definition: log.hpp:552
#define WLOG(text)
Logging Macro (Level = Warning)
Definition: log.hpp:550
ParamType parseParamType(const string &s)
Convert parameter type string into enumerated class value.
Definition: irmodeldata.cpp:38
Size size(const ValueType &v)
Definition: value.cpp:145
Serializable Credit Default Swap.
Definition: namespaces.docs:23
Map text representations to QuantLib/QuantExt types.
string conversion utilities