Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
utilities.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
32
35
36#include <ql/math/matrixutilities/symmetricschurdecomposition.hpp>
37#include <ql/utilities/null.hpp>
38
39#include <boost/make_shared.hpp>
40#include <boost/regex.hpp>
41
42#include <fstream>
43
44using std::map;
45using std::set;
46using std::string;
47using namespace ore::data;
48
49namespace ore {
50namespace analytics {
51
52using QuantLib::Null;
53using QuantLib::Size;
54
55std::vector<std::string> loadFactorList(const std::string& inputFileName, const char delim) {
56 LOG("Load factor list from file " << inputFileName);
57 std::ifstream file;
58 file.open(inputFileName);
59 QL_REQUIRE(file.is_open(), "error opening file " << inputFileName);
60 std::vector<string> result;
61 try {
62 while (!file.eof()) {
63 std::string line;
64 getline(file, line, delim);
65 if (line.size() == 0)
66 continue;
67 result.push_back(line);
68 }
69 } catch (std::exception& e) {
70 file.close();
71 QL_FAIL("error during reading file: " << e.what());
72 }
73
74 LOG("Loaded factor list of size " << result.size());
75 return result;
76} // loadFactorList
77
78std::vector<std::vector<double>> loadScenarios(const std::string& inputFileName, const char delim) {
79 LOG("Load scenarios from file " << inputFileName);
80 std::ifstream file;
81 file.open(inputFileName);
82 QL_REQUIRE(file.is_open(), "error opening file " << inputFileName);
83 std::vector<std::vector<double>> result;
84 try {
85 while (!file.eof()) {
86 Size currentScenario = Null<Size>(); //, currentFactor;// = Null<Size>();
87 std::string line;
88 getline(file, line, delim);
89 if (line.size() == 0)
90 continue;
91 std::vector<string> tokens;
92 boost::trim(line);
93 boost::split(tokens, line, boost::is_any_of(",;\t "), boost::token_compress_off);
94 QL_REQUIRE(tokens.size() == 3, "loadScenarios, expected 3 tokens in line: " << line);
95 Size tmpSc = parseInteger(tokens[0]);
96 // Size tmpFc = parseInteger(tokens[1]);
97 if (currentScenario != tmpSc) {
98 result.push_back(std::vector<double>());
99 currentScenario = tmpSc;
100 }
101 // currentFactor = tmpFc;
102 double move = parseReal(tokens[2]);
103 result.back().push_back(move);
104 }
105 } catch (std::exception& e) {
106 file.close();
107 QL_FAIL("error during reading file: " << e.what());
108 }
109
110 LOG("Loaded " << result.size() << " scenarios, first entry contains " << result.front().size() << " factors");
111 return result;
112} // loadScenarios
113
114Matrix loadCovarianceMatrix(const std::string& inputFileName, const char delim) {
115 LOG("Load covariance matrix from file " << inputFileName);
116 std::ifstream file;
117 file.open(inputFileName);
118 QL_REQUIRE(file.is_open(), "error opening file " << inputFileName);
119 std::vector<std::pair<Size, Size>> pos;
120 std::vector<double> val;
121 Size maxI = 0, maxJ = 0;
122 try {
123 while (!file.eof()) {
124 std::string line;
125 getline(file, line, delim);
126 if (line.size() == 0)
127 continue;
128 std::vector<string> tokens;
129 boost::trim(line);
130 boost::split(tokens, line, boost::is_any_of(",;\t "), boost::token_compress_off);
131 QL_REQUIRE(tokens.size() == 3, "loadCovarianceMatrix, expected 3 tokens in line: " << line);
132 Size i = parseInteger(tokens[0]);
133 Size j = parseInteger(tokens[1]);
134 double tmp = parseReal(tokens[2]);
135 pos.push_back(std::make_pair(i, j));
136 val.push_back(tmp);
137 maxI = std::max(maxI, i);
138 maxJ = std::max(maxJ, j);
139 }
140 } catch (std::exception& e) {
141 file.close();
142 QL_FAIL("error during reading file: " << e.what());
143 }
144
145 LOG("Loaded " << val.size() << " data points, dimension of matrix is " << maxI + 1 << "x" << maxJ + 1);
146 QL_REQUIRE(maxI == maxJ, "Expected quadratic matrix");
147
148 Matrix result(maxI + 1, maxI + 1);
149 for (Size i = 0; i < pos.size(); ++i) {
150 result[pos[i].first][pos[i].second] = val[i];
151 result[pos[i].second][pos[i].first] = val[i];
152 }
153
154 // log the eigenvalues
155 QuantLib::SymmetricSchurDecomposition ssd(result);
156 for (Size i = 0; i < ssd.eigenvalues().size(); ++i) {
157 LOG("Eigenvalue " << i << " = " << ssd.eigenvalues()[i]);
158 }
159 return result;
160} // load CovarianceMatrix
161
162SimmVersion parseSimmVersion(const string& version) {
163 static map<string, SimmVersion> versionMap = {{"1.0", SimmVersion::V1_0},
164 {"1.1", SimmVersion::V1_1},
165 {"1.2", SimmVersion::V1_2},
166 {"1.3", SimmVersion::V1_3},
167 {"1.3.38", SimmVersion::V1_3_38},
168 {"2.0", SimmVersion::V2_0},
169 {"2.1", SimmVersion::V2_1},
170 {"2.2", SimmVersion::V2_2},
171 {"2.3", SimmVersion::V2_3},
172 {"2.3.8", SimmVersion::V2_3_8},
173 {"2.5", SimmVersion::V2_5},
174 {"2.5A", SimmVersion::V2_5A},
175 {"2.5.6", SimmVersion::V2_6},
176 // alias
177 {"2.4", SimmVersion::V2_3_8},
178 {"2.6", SimmVersion::V2_6},
179 // old names for backwards compatibility
180 {"ISDA_V315", SimmVersion::V1_0},
181 {"ISDA_V329", SimmVersion::V1_3},
182 {"ISDA_V338", SimmVersion::V1_3_38},
183 {"ISDA_V344", SimmVersion::V2_0}};
184
185 QL_REQUIRE(versionMap.count(version) > 0,
186 "Could not parse SIMM version string " << version << " to a valid version");
187
188 return versionMap.at(version);
189}
190
191QuantLib::ext::shared_ptr<SimmConfiguration> buildSimmConfiguration(const string& simmVersion,
192 const QuantLib::ext::shared_ptr<SimmBucketMapper>& simmBucketMapper,
193 const QuantLib::ext::shared_ptr<SimmCalibrationData>& simmCalibrationData,
194 const Size& mporDays) {
195
196 // Check first if the SIMM calibration has the requested simmVersion
197 if (simmCalibrationData) {
198 const auto& simmCalibration = simmCalibrationData->getBySimmVersion(simmVersion);
199 if (simmCalibration) {
200 auto simmConfiguration = QuantLib::ext::make_shared<SimmConfigurationCalibration>(simmBucketMapper, simmCalibration, mporDays);
201 return simmConfiguration;
202 }
203 }
204
205 auto version = parseSimmVersion(simmVersion);
206
207 switch (version) {
209 return QuantLib::ext::make_shared<SimmConfiguration_ISDA_V1_0>(simmBucketMapper);
210 break;
212 return QuantLib::ext::make_shared<SimmConfiguration_ISDA_V1_3>(simmBucketMapper);
213 break;
215 return QuantLib::ext::make_shared<SimmConfiguration_ISDA_V1_3_38>(simmBucketMapper);
216 break;
218 return QuantLib::ext::make_shared<SimmConfiguration_ISDA_V2_0>(simmBucketMapper);
219 break;
221 return QuantLib::ext::make_shared<SimmConfiguration_ISDA_V2_1>(simmBucketMapper);
222 break;
224 return QuantLib::ext::make_shared<SimmConfiguration_ISDA_V2_2>(simmBucketMapper, mporDays);
225 break;
227 return QuantLib::ext::make_shared<SimmConfiguration_ISDA_V2_3>(simmBucketMapper, mporDays);
228 break;
230 return QuantLib::ext::make_shared<SimmConfiguration_ISDA_V2_3_8>(simmBucketMapper, mporDays);
231 break;
233 return QuantLib::ext::make_shared<SimmConfiguration_ISDA_V2_5>(simmBucketMapper, mporDays);
234 break;
236 return QuantLib::ext::make_shared<SimmConfiguration_ISDA_V2_5A>(simmBucketMapper, mporDays);
237 break;
239 return QuantLib::ext::make_shared<SimmConfiguration_ISDA_V2_6>(simmBucketMapper, mporDays);
240 break;
241 default:
242 break;
243 }
244
245 QL_FAIL("SIMM configuration for version '" << simmVersion << "' cannot be built");
246}
247
248std::string escapeCommaSeparatedList(const std::string& str, const char& csvQuoteChar) {
249 std::string result = str;
250 if (result.find(',') != string::npos && csvQuoteChar == '\0') {
251 result = '\"' + result + '\"';
252 }
253 return result;
254}
255
256} // namespace analytics
257} // namespace ore
Real parseReal(const string &s)
Integer parseInteger(const string &s)
#define LOG(text)
std::vector< std::vector< double > > loadScenarios(const std::string &inputFileName, const char delim)
Definition: utilities.cpp:78
std::vector< std::string > loadFactorList(const std::string &inputFileName, const char delim)
Definition: utilities.cpp:55
SimmVersion
Ordered SIMM versions.
Definition: utilities.hpp:43
std::string escapeCommaSeparatedList(const std::string &str, const char &csvQuoteChar)
Definition: utilities.cpp:248
SimmVersion parseSimmVersion(const string &version)
Definition: utilities.cpp:162
QuantLib::ext::shared_ptr< SimmConfiguration > buildSimmConfiguration(const string &simmVersion, const QuantLib::ext::shared_ptr< SimmBucketMapper > &simmBucketMapper, const QuantLib::ext::shared_ptr< SimmCalibrationData > &simmCalibrationData, const Size &mporDays)
Definition: utilities.cpp:191
Matrix loadCovarianceMatrix(const std::string &inputFileName, const char delim)
Definition: utilities.cpp:114
Size size(const ValueType &v)
SIMM configuration built for SIMM calibration.
SIMM configuration for SIMM version R1.0 (v3.15)
SIMM configuration for SIMM version R1.3 (3.29)
SIMM configuration for SIMM version 1.3.38.
SIMM configuration for SIMM version 2.0 (1.3.44)
SIMM configuration for SIMM version 2.1 (2.0.6)
SIMM configuration for SIMM version 2.2.
SIMM configuration for SIMM version 2.3.
SIMM configuration for SIMM version 2.3.8.
SIMM configuration for SIMM version 2.5.
SIMM configuration for SIMM version 2.5A.
SIMM configuration for SIMM version 2.6.
supporting utilities