Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
cube.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
19#include <boost/filesystem.hpp>
20#include <boost/test/unit_test.hpp>
22#include <orea/cube/cube_io.hpp>
23#include <orea/cube/npvcube.hpp>
50#include <ql/math/randomnumbers/mt19937uniformrng.hpp>
51#include <ql/time/calendars/target.hpp>
52#include <ql/time/date.hpp>
53#include <ql/time/daycounters/actualactual.hpp>
54#include <oret/toplevelfixture.hpp>
56
57#include "testmarket.hpp"
58
59using namespace ore::analytics;
60using namespace boost::unit_test_framework;
61using std::string;
62using std::vector;
63
64namespace {
65
66void initCube(NPVCube& cube) {
67 // Set every (i,j,k,d) node to be i*1000000 + j + (k/1000000) + d*3
68 for (Size i = 0; i < cube.numIds(); ++i) {
69 for (Size j = 0; j < cube.numDates(); ++j) {
70 for (Size k = 0; k < cube.samples(); ++k) {
71 for (Size d = 0; d < cube.depth(); ++d) {
72 cube.set(i * 1000000.0 + j + k / 1000000.0 + d * 3, i, j, k, d);
73 }
74 }
75 }
76 }
77}
78
79void checkCube(NPVCube& cube, Real tolerance) {
80 // Now check each value
81 for (Size i = 0; i < cube.numIds(); ++i) {
82 for (Size j = 0; j < cube.numDates(); ++j) {
83 for (Size k = 0; k < cube.samples(); ++k) {
84 for (Size d = 0; d < cube.depth(); ++d) {
85 Real expected = i * 1000000.0 + j + k / 1000000.0 + d * 3;
86 Real actual = cube.get(i, j, k, d);
87 BOOST_CHECK_CLOSE(expected, actual, tolerance);
88 }
89 }
90 }
91 }
92}
93
94void testCube(NPVCube& cube, const std::string& cubeName, Real tolerance) {
95 BOOST_TEST_MESSAGE("Testing cube " << cubeName);
96
97 initCube(cube);
98
99 // Check we can't set anything out of bounds
100 BOOST_CHECK_THROW(cube.set(1.0, cube.numIds(), 0, 0), std::exception);
101 BOOST_CHECK_THROW(cube.set(1.0, 0, cube.numDates(), 0), std::exception);
102 BOOST_CHECK_THROW(cube.set(1.0, 0, 0, cube.samples()), std::exception);
103 BOOST_CHECK_THROW(cube.set(1.0, "test_id", Date::todaysDate(), 0), std::exception);
104
105 // Check we can't get anything out of bounds
106 BOOST_CHECK_THROW(cube.get(cube.numIds(), 0, 0), std::exception);
107 BOOST_CHECK_THROW(cube.get(0, cube.numDates(), 0), std::exception);
108 BOOST_CHECK_THROW(cube.get(0, 0, cube.samples()), std::exception);
109 BOOST_CHECK_THROW(cube.get("test_id", Date::todaysDate(), 0), std::exception);
110
111 checkCube(cube, tolerance);
112 // All done
113}
114
115template <class T>
116void testCubeFileIO(QuantLib::ext::shared_ptr<NPVCube> cube, const std::string& cubeName, Real tolerance,
117 bool doublePrecision) {
118
119 initCube(*cube);
120
121 // get a random filename
122 string filename = boost::filesystem::unique_path().string();
123 BOOST_TEST_MESSAGE("Saving cube " << cubeName << " to file " << filename);
124 saveCube(filename, NPVCubeWithMetaData{cube, nullptr, boost::none, boost::none}, doublePrecision);
125
126 // Create a new Cube and load it
127 BOOST_TEST_MESSAGE("Loading from file " << filename);
128 auto cube2 = loadCube(filename, doublePrecision).cube;
129 BOOST_TEST_MESSAGE("Cube " << cubeName << " loaded from file.");
130
131 // Delete the file to make sure all reads are from memory
132 boost::filesystem::remove(filename);
133
134 // Check dimensions match
135 BOOST_CHECK_EQUAL(cube->numIds(), cube->numIds());
136 BOOST_CHECK_EQUAL(cube->numDates(), cube->numDates());
137 BOOST_CHECK_EQUAL(cube->samples(), cube->samples());
138 BOOST_CHECK_EQUAL(cube->depth(), cube->depth());
139
140 // check all values
141 checkCube(*cube2, tolerance);
142}
143
144void testCubeGetSetbyDateID(NPVCube& cube, Real tolerance) {
145 std::map<string, Size> ids = cube.idsAndIndexes();
146 vector<Date> dates = cube.dates();
147 // set value for each cube entry
148 Real i = 1.0;
149 for (auto [id, pos] : ids) {
150 for (auto dt : dates) {
151 cube.set(i, id, dt, 0);
152 i++;
153 }
154 }
155 // check the cube returns as expected
156 Real j = 1.0;
157 for (const auto& [id, pos]: ids) {
158 for (auto dt : dates) {
159 Real actual = cube.get(id, dt, 0);
160 BOOST_CHECK_CLOSE(j, actual, tolerance);
161 j++;
162 }
163 }
164}
165
166void initCube(NPVCube& cube, QuantLib::ext::shared_ptr<Portfolio>& portfolio, QuantLib::ext::shared_ptr<DateGrid>& dg) {
167 // Set every (i,j,k,d) node to be i*1000000 + j + (k/1000000) + d*3
168 for (const auto& [id, i]: cube.idsAndIndexes()) {
169 Size dateLen = 0;
170 Date tradeMaturity = portfolio->get(id)->maturity();
171 while (dateLen < dg->dates().size() && dg->dates()[dateLen] < tradeMaturity) {
172 dateLen++;
173 }
174 for (Size j = 0; j < dateLen; ++j) {
175 for (Size k = 0; k < cube.samples(); ++k) {
176 for (Size d = 0; d < cube.depth(); ++d) {
177 cube.set(i * 1000000.0 + j + k / 1000000.0 + d * 3, i, j, d, k);
178 }
179 }
180 }
181 }
182}
183
184void checkCube(NPVCube& cube, Real tolerance, QuantLib::ext::shared_ptr<Portfolio>& portfolio,
185 QuantLib::ext::shared_ptr<DateGrid>& dg) {
186 // Now check each value
187 for (const auto& [id, i] : cube.idsAndIndexes()) {
188 Size dateLen = 0;
189 Date tradeMaturity = portfolio->get(id)->maturity();
190 while (dateLen < dg->dates().size() && dg->dates()[dateLen] < tradeMaturity) {
191 dateLen++;
192 }
193 for (Size j = 0; j < dateLen; ++j) {
194 for (Size k = 0; k < cube.samples(); ++k) {
195 for (Size d = 0; d < cube.depth(); ++d) {
196 Real expected = i * 1000000.0 + j + k / 1000000.0 + d * 3;
197 Real actual = cube.get(i, j, d, k);
198 BOOST_CHECK_CLOSE(expected, actual, tolerance);
199 }
200 }
201 }
202 }
203}
204
205void testCube(NPVCube& cube, const std::string& cubeName, Real tolerance, QuantLib::ext::shared_ptr<Portfolio>& portfolio,
206 QuantLib::ext::shared_ptr<DateGrid>& d) {
207 BOOST_TEST_MESSAGE("Testing cube " << cubeName);
208 initCube(cube, portfolio, d);
209 // Check we can't set anything out of bounds
210 BOOST_CHECK_THROW(cube.set(1.0, cube.numIds(), 0, 0), std::exception);
211 BOOST_CHECK_THROW(cube.set(1.0, 0, cube.numDates(), 0), std::exception);
212 BOOST_CHECK_THROW(cube.set(1.0, 0, 0, cube.samples()), std::exception);
213
214 // Check we can't get anything out of bounds
215 BOOST_CHECK_THROW(cube.get(cube.numIds(), 0, 0), std::exception);
216 BOOST_CHECK_THROW(cube.get(0, cube.numDates(), 0), std::exception);
217 BOOST_CHECK_THROW(cube.get(0, 0, cube.samples()), std::exception);
218 checkCube(cube, tolerance, portfolio, d);
219 // All done
220}
221
222template <class T>
223void testCubeFileIO(QuantLib::ext::shared_ptr<NPVCube> cube, const std::string& cubeName, Real tolerance,
224 QuantLib::ext::shared_ptr<Portfolio>& portfolio, QuantLib::ext::shared_ptr<DateGrid>& d, bool doublePrecision) {
225
226 initCube(*cube, portfolio, d);
227
228 // get a random filename
229 string filename = boost::filesystem::unique_path().string();
230 BOOST_TEST_MESSAGE("Saving cube " << cubeName << " to file " << filename);
231 saveCube(filename, NPVCubeWithMetaData{cube, nullptr, boost::none, boost::none}, doublePrecision);
232
233 // Create a new Cube and load it
234 auto cube2 = QuantLib::ext::make_shared<T>();
235 BOOST_TEST_MESSAGE("Loading from file " << filename);
236 cube2 = loadCube(filename, doublePrecision).cube;
237 BOOST_TEST_MESSAGE("Cube " << cubeName << " loaded from file.");
238
239 // Delete the file to make sure all reads are from memory
240 boost::filesystem::remove(filename);
241
242 // Check dimensions match
243 BOOST_CHECK_EQUAL(cube->numIds(), cube2->numIds());
244 BOOST_CHECK_EQUAL(cube->numDates(), cube2->numDates());
245 BOOST_CHECK_EQUAL(cube->samples(), cube2->samples());
246 BOOST_CHECK_EQUAL(cube->depth(), cube2->depth());
247
248 // check all values
249 checkCube(*cube2, tolerance, portfolio, d);
250}
251
252} // namespace
253
254// Returns an int in the interval [min, max]. Inclusive.
255inline unsigned long randInt(MersenneTwisterUniformRng& rng, Size min, Size max) {
256 return min + (rng.nextInt32() % (max + 1 - min));
257}
258
259inline const string& randString(MersenneTwisterUniformRng& rng, const vector<string>& strs) {
260 return strs[randInt(rng, 0, strs.size() - 1)];
261}
262inline bool randBoolean(MersenneTwisterUniformRng& rng) { return randInt(rng, 0, 1) == 1; }
263
264QuantLib::ext::shared_ptr<Portfolio> buildPortfolio(Size portfolioSize, QuantLib::ext::shared_ptr<EngineFactory>& factory) {
265
266 QuantLib::ext::shared_ptr<Portfolio> portfolio(new Portfolio());
267
268 vector<string> ccys = {"EUR", "USD", "GBP", "JPY", "CHF"};
269
270 map<string, vector<string>> indices = {{"EUR", {"EUR-EURIBOR-6M"}},
271 {"USD", {"USD-LIBOR-3M"}},
272 {"GBP", {"GBP-LIBOR-6M"}},
273 {"CHF", {"CHF-LIBOR-6M"}},
274 {"JPY", {"JPY-LIBOR-6M"}}};
275
276 vector<string> fixedTenors = {"6M", "1Y"};
277
278 Size minTerm = 2;
279 Size maxTerm = 30;
280
281 Size minFixedBps = 10;
282 Size maxFixedBps = 400;
283
284 Size seed = 5; // keep this constant to ensure portfolio doesn't change
285 MersenneTwisterUniformRng rng(seed);
286
287 Date today = Settings::instance().evaluationDate();
288 Calendar cal = TARGET();
289 string calStr = "TARGET";
290 string conv = "MF";
291 string rule = "Forward";
292 Size days = 2;
293 string fixDC = "30/360";
294 string floatDC = "ACT/365";
295
296 vector<double> notional(1, 1000000);
297 vector<double> spread(1, 0);
298
299 for (Size i = 0; i < portfolioSize; i++) {
300 Size term = portfolioSize == 1 ? 20 : randInt(rng, minTerm, maxTerm);
301
302 // Start today +/- 1 Year
303 Date startDate = portfolioSize == 1 ? cal.adjust(today) : cal.adjust(today - 365 + randInt(rng, 0, 730));
304 Date endDate = cal.adjust(startDate + term * Years);
305
306 // date 2 string
307 std::ostringstream oss;
308 oss << io::iso_date(startDate);
309 string start(oss.str());
310 oss.str("");
311 oss.clear();
312 oss << io::iso_date(endDate);
313 string end(oss.str());
314
315 // ccy + index
316 string ccy = portfolioSize == 1 ? "EUR" : randString(rng, ccys);
317 string index = portfolioSize == 1 ? "EUR-EURIBOR-6M" : randString(rng, indices[ccy]);
318 string floatFreq = portfolioSize == 1 ? "6M" : index.substr(index.find('-', 4) + 1);
319
320 // fixed details
321 Real fixedRate = portfolioSize == 1 ? 0.02 : randInt(rng, minFixedBps, maxFixedBps) / 100.0;
322 string fixFreq = portfolioSize == 1 ? "1Y" : randString(rng, fixedTenors);
323
324 // envelope
325 Envelope env("CP");
326
327 // Schedules
328 ScheduleData floatSchedule(ScheduleRules(start, end, floatFreq, calStr, conv, conv, rule));
329 ScheduleData fixedSchedule(ScheduleRules(start, end, fixFreq, calStr, conv, conv, rule));
330
331 bool isPayer = randBoolean(rng);
332
333 // fixed Leg - with dummy rate
334 LegData fixedLeg(QuantLib::ext::make_shared<FixedLegData>(vector<double>(1, fixedRate)), isPayer, ccy, fixedSchedule,
335 fixDC, notional);
336
337 // float Leg
338 vector<double> spreads(1, 0);
339 LegData floatingLeg(QuantLib::ext::make_shared<FloatingLegData>(index, days, false, spread), !isPayer, ccy,
340 floatSchedule, floatDC, notional);
341
342 QuantLib::ext::shared_ptr<Trade> swap(new ore::data::Swap(env, floatingLeg, fixedLeg));
343
344 // id
345 oss.clear();
346 oss.str("");
347 oss << "Trade_" << i + 1;
348 swap->id() = oss.str();
349
350 portfolio->add(swap);
351 }
352 // portfolio->save("port.xml");
353
354 portfolio->build(factory);
355
356 if (portfolio->size() != portfolioSize)
357 BOOST_ERROR("Failed to build portfolio (got " << portfolio->size() << " expected " << portfolioSize << ")");
358
359 // Dump stats about portfolio
360 Time maturity = 0;
361 DayCounter dc = ActualActual(ActualActual::ISDA);
362 map<string, Size> fixedFreqs;
363 map<string, Size> floatFreqs;
364 for (const auto& [tradeId, trade] : portfolio->trades()) {
365 maturity += dc.yearFraction(today, trade->maturity());
366
367 // fixed Freq
368 QuantLib::ext::shared_ptr<ore::data::Swap> swap = QuantLib::ext::dynamic_pointer_cast<ore::data::Swap>(trade);
369 string floatFreq = swap->legData()[0].schedule().rules().front().tenor();
370 string fixFreq = swap->legData()[1].schedule().rules().front().tenor();
371 QL_REQUIRE(swap->legData()[0].legType() == "Floating" && swap->legData()[1].legType() == "Fixed", "Leg mixup");
372 if (fixedFreqs.find(fixFreq) == fixedFreqs.end())
373 fixedFreqs[fixFreq] = 1;
374 else
375 fixedFreqs[fixFreq]++;
376 if (floatFreqs.find(floatFreq) == floatFreqs.end())
377 floatFreqs[floatFreq] = 1;
378 else
379 floatFreqs[floatFreq]++;
380 }
381 maturity /= portfolioSize;
382 BOOST_TEST_MESSAGE("Portfolio Size : " << portfolioSize);
383 BOOST_TEST_MESSAGE("Average Maturity : " << maturity);
384 std::ostringstream oss;
385 for (Size i = 0; i < ccys.size(); i++)
386 oss << ccys[i] << " ";
387 BOOST_TEST_MESSAGE("Currencies : " << oss.str());
388 // dump % breakdown of tenors
389 map<string, Size>::iterator it;
390 BOOST_TEST_MESSAGE("Fixed Tenors : ");
391 for (it = fixedFreqs.begin(); it != fixedFreqs.end(); ++it) {
392 Real perc = 100 * it->second / (Real)portfolioSize;
393 BOOST_TEST_MESSAGE(" " << it->first << " " << perc << " %");
394 }
395 BOOST_TEST_MESSAGE("Floating Tenors : ");
396 for (it = floatFreqs.begin(); it != floatFreqs.end(); ++it) {
397 Real perc = 100 * it->second / (Real)portfolioSize;
398 BOOST_TEST_MESSAGE(" " << it->first << " " << perc << " %");
399 }
400
401 return portfolio;
402}
403
404BOOST_FIXTURE_TEST_SUITE(OREAnalyticsTestSuite, ore::test::OreaTopLevelFixture)
405
406BOOST_AUTO_TEST_SUITE(CubeTest)
407
408BOOST_AUTO_TEST_CASE(testSinglePrecisionInMemoryCube) {
409 // trades, dates, samples
410 std::set<string> ids {string("id")}; // the overlap doesn't matter
411 vector<Date> dates(100, Date());
412 Size samples = 1000;
413 SinglePrecisionInMemoryCube c(Date(), ids, dates, samples);
414 testCube(c, "SinglePrecisionInMemoryCube", 1e-5);
415}
416
417BOOST_AUTO_TEST_CASE(testDoublePrecisionInMemoryCube) {
418 std::set<string> ids{string("id")}; // the overlap doesn't matter
419 vector<Date> dates(100, Date());
420 Size samples = 1000;
421 DoublePrecisionInMemoryCube c(Date(), ids, dates, samples);
422 testCube(c, "DoublePrecisionInMemoryCube", 1e-14);
423}
424
425BOOST_AUTO_TEST_CASE(testSinglePrecisionInMemoryCubeN) {
426 std::set<string> ids{string("id")}; // the overlap doesn't matter
427 vector<Date> dates(50, Date());
428 Size samples = 200;
429 Size depth = 6;
430 SinglePrecisionInMemoryCubeN c(Date(), ids, dates, samples, depth);
431 testCube(c, "SinglePrecisionInMemoryCubeN", 1e-5);
432}
433
434BOOST_AUTO_TEST_CASE(testDoublePrecisionInMemoryCubeN) {
435 std::set<string> ids{string("id")}; // the overlap doesn't matter
436 vector<Date> dates(50, Date());
437 Size samples = 200;
438 Size depth = 6;
439 DoublePrecisionInMemoryCubeN c(Date(), ids, dates, samples, depth);
440 testCube(c, "DoublePrecisionInMemoryCubeN", 1e-14);
441}
442
443BOOST_AUTO_TEST_CASE(testDoublePrecisionInMemoryCubeFileIO) {
444 std::set<string> ids{string("id")}; // the overlap doesn't matter
445 Date d(1, QuantLib::Jan, 2016); // need a real date here
446 vector<Date> dates(100, d);
447 Size samples = 1000;
448 auto c = QuantLib::ext::make_shared<DoublePrecisionInMemoryCube>(d, ids, dates, samples);
449 testCubeFileIO<DoublePrecisionInMemoryCube>(c, "DoublePrecisionInMemoryCube", 1e-14, true);
450}
451
452BOOST_AUTO_TEST_CASE(testDoublePrecisionInMemoryCubeFileNIO) {
453 std::set<string> ids{string("id")}; // the overlap doesn't matter
454 Date d(1, QuantLib::Jan, 2016); // need a real date here
455 vector<Date> dates(50, d);
456 Size samples = 200;
457 Size depth = 6;
458 auto c = QuantLib::ext::make_shared<DoublePrecisionInMemoryCubeN>(d, ids, dates, samples, depth);
459 testCubeFileIO<DoublePrecisionInMemoryCubeN>(c, "DoublePrecisionInMemoryCubeN", 1e-14, true);
460}
461
462BOOST_AUTO_TEST_CASE(testInMemoryCubeGetSetbyDateID) {
463 std::set<string> ids = {"id1", "id2", "id3"}; // the overlap doesn't matter
464 Date today = Date::todaysDate();
465 vector<Date> dates = {today + QuantLib::Period(1, QuantLib::Days), today + QuantLib::Period(2, QuantLib::Days),
466 today + QuantLib::Period(3, QuantLib::Days)};
467 Size samples = 1;
468 DoublePrecisionInMemoryCube cube(Date(), ids, dates, samples);
469 testCubeGetSetbyDateID(cube, 1e-14);
470}
471
472BOOST_AUTO_TEST_CASE(testSinglePrecisionJaggedCube) {
473
474 SavedSettings backup;
475
476 Size portfolioSize = 100;
477 Size depth = 10;
478
479 Date today = Date(15, December, 2016);
480 Settings::instance().evaluationDate() = today;
481 string dateGridStr = "270,2W";
482 QuantLib::ext::shared_ptr<DateGrid> d = QuantLib::ext::make_shared<DateGrid>(dateGridStr);
483
484 QuantLib::ext::shared_ptr<EngineData> data = QuantLib::ext::make_shared<EngineData>();
485
486 // Init Market
487 QuantLib::ext::shared_ptr<Market> initMarket = QuantLib::ext::make_shared<testsuite::TestMarket>(today);
488
489 data->model("EuropeanSwaption") = "BlackBachelier";
490 data->engine("EuropeanSwaption") = "BlackBachelierSwaptionEngine";
491 data->model("Swap") = "DiscountedCashflows";
492 data->engine("Swap") = "DiscountingSwapEngine";
493 data->model("FxOption") = "GarmanKohlhagen";
494 data->engine("FxOption") = "AnalyticEuropeanEngine";
495
496 QuantLib::ext::shared_ptr<EngineFactory> factory = QuantLib::ext::make_shared<EngineFactory>(data, initMarket);
497
498 QuantLib::ext::shared_ptr<Portfolio> portfolio = buildPortfolio(portfolioSize, factory);
499
500 Size samples = 10;
501 JaggedCube<float> jaggedCube(today, portfolio, d->dates(), samples, depth);
502 testCube(jaggedCube, "SinglePrecisionJaggedCube", 1e-5, portfolio, d);
503 IndexManager::instance().clearHistories();
504}
505
506BOOST_AUTO_TEST_CASE(testDoublePrecisionJaggedCube) {
507
508 SavedSettings backup;
509
510 Size portfolioSize = 100;
511 Size depth = 10;
512
513 Date today = Date(15, December, 2016);
514 Settings::instance().evaluationDate() = today;
515 string dateGridStr = "270,2W";
516 QuantLib::ext::shared_ptr<DateGrid> d = QuantLib::ext::make_shared<DateGrid>(dateGridStr);
517
518 QuantLib::ext::shared_ptr<EngineData> data = QuantLib::ext::make_shared<EngineData>();
519
520 // Init Market
521 QuantLib::ext::shared_ptr<Market> initMarket = QuantLib::ext::make_shared<testsuite::TestMarket>(today);
522
523 data->model("EuropeanSwaption") = "BlackBachelier";
524 data->engine("EuropeanSwaption") = "BlackBachelierSwaptionEngine";
525 data->model("Swap") = "DiscountedCashflows";
526 data->engine("Swap") = "DiscountingSwapEngine";
527 data->model("FxOption") = "GarmanKohlhagen";
528 data->engine("FxOption") = "AnalyticEuropeanEngine";
529
530 QuantLib::ext::shared_ptr<EngineFactory> factory = QuantLib::ext::make_shared<EngineFactory>(data, initMarket);
531
532 QuantLib::ext::shared_ptr<Portfolio> portfolio = buildPortfolio(portfolioSize, factory);
533
534 Size samples = 10;
535 JaggedCube<double> jaggedCube(today, portfolio, d->dates(), samples, depth);
536 testCube(jaggedCube, "DoublePrecisionJaggedCube", 1e-5, portfolio, d);
537 IndexManager::instance().clearHistories();
538}
539
540BOOST_AUTO_TEST_SUITE_END()
541
542BOOST_AUTO_TEST_SUITE_END()
InMemoryCube of fixed depth 1.
InMemoryCube of variable depth.
JaggedCube stores the cube in memory using a vector of trade specific blocks.
Definition: jaggedcube.hpp:140
NPV Cube class stores both future and current NPV values.
Definition: npvcube.hpp:53
virtual Size numDates() const =0
virtual Size samples() const =0
virtual Real get(Size id, Size date, Size sample, Size depth=0) const =0
Get a value from the cube using index.
virtual void set(Real value, Size id, Size date, Size sample, Size depth=0)=0
Set a value in the cube using index.
virtual Size numIds() const =0
Return the length of each dimension.
virtual Size depth() const =0
virtual const std::vector< QuantLib::Date > & dates() const =0
Get the vector of dates for this cube.
virtual const std::map< std::string, Size > & idsAndIndexes() const =0
Get a map of id and their index position in this cube.
OREAnalytics Top level fixture.
Scenario generation using cross asset model paths.
unsigned long randInt(MersenneTwisterUniformRng &rng, Size min, Size max)
Definition: cube.cpp:255
bool randBoolean(MersenneTwisterUniformRng &rng)
Definition: cube.cpp:262
const string & randString(MersenneTwisterUniformRng &rng, const vector< string > &strs)
Definition: cube.cpp:259
QuantLib::ext::shared_ptr< Portfolio > buildPortfolio(Size portfolioSize, QuantLib::ext::shared_ptr< EngineFactory > &factory)
Definition: cube.cpp:264
BOOST_AUTO_TEST_CASE(testSinglePrecisionInMemoryCube)
Definition: cube.cpp:408
load / save cubes and agg scen data from / to disk
Class that wraps a sensitivity stream and filters out negligible records.
A cube implementation that stores the cube in memory.
A cube implementation that stores the cube in memory.
data
Time maturity
RandomVariable max(RandomVariable x, const RandomVariable &y)
RandomVariable min(RandomVariable x, const RandomVariable &y)
void saveCube(const std::string &filename, const NPVCubeWithMetaData &cube, const bool doublePrecision)
Definition: cube_io.cpp:167
NPVCubeWithMetaData loadCube(const std::string &filename, const bool doublePrecision)
Definition: cube_io.cpp:63
Size size(const ValueType &v)
The base NPV cube class.
Singleton class to hold global Observation Mode.
Fixture that can be used at top level of OREAnalytics test suites.
Perform parametric var calculation for a given portfolio.
risk class and type filter
A Market class that can be updated by Scenarios.
A class to hold Scenario parameters for scenarioSimMarket.
Class for aggregating SensitivityRecords.
Perform sensitivity analysis for a given portfolio.
Class for streaming SensitivityRecords from a SensitivityCube.
Class for streaming SensitivityRecords from file.
Class for streaming SensitivityRecords from in-memory container.
Struct for holding a sensitivity record.
Base class for sensitivity record streamer.
factory classes for simple scenarios
perform a stress testing analysis for a given portfolio.
QuantLib::ext::shared_ptr< NPVCube > cube
Definition: cube_io.hpp:39
The counterparty cube calculator interface.
The cube valuation core.