Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
jointnpvsensicube.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
20
21#include <ql/errors.hpp>
22
23#include <numeric>
24#include <set>
25
26namespace ore {
27namespace analytics {
28
29JointNPVSensiCube::JointNPVSensiCube(const QuantLib::ext::shared_ptr<NPVSensiCube>& cube1,
30 const QuantLib::ext::shared_ptr<NPVSensiCube>& cube2, const std::set<std::string>& ids)
31 : JointNPVSensiCube({cube1, cube2}, ids) {}
32
33JointNPVSensiCube::JointNPVSensiCube(const std::vector<QuantLib::ext::shared_ptr<NPVSensiCube>>& cubes,
34 const std::set<std::string>& ids)
35 : NPVSensiCube(), cubes_(cubes) {
36
37 // check we have at least one input cube
38
39 QL_REQUIRE(!cubes.empty(), "JointNPVSensiCube: at least one cube must be given");
40
41 // check that the dimensions are consistent
42
43 for (Size i = 1; i < cubes.size(); ++i) {
44 QL_REQUIRE(cubes_[i]->numDates() == cubes_[0]->numDates(),
45 "JointNPVSensiCube: numDates do not match for cube #"
46 << i << " (" << cubes[i]->numDates() << " vs. cube #0 (" << cubes_[0]->numDates() << ")");
47 QL_REQUIRE(cubes_[i]->samples() == cubes_[0]->samples(),
48 "JointNPVSensiCube: samples do not match for cube #"
49 << i << " (" << cubes_[i]->samples() << " vs. cube #0 (" << cubes_[0]->samples() << ")");
50 QL_REQUIRE(cubes_[i]->depth() == cubes_[0]->depth(), "JointNPVSensiCube: depth do not match for cube #"
51 << i << " (" << cubes_[i]->depth() << " vs. cube #0 ("
52 << cubes[0]->depth() << ")");
53 }
54
55 std::set<std::string> allIds;
56 if (!ids.empty()) {
57 // if ids are given, these define the ids in the result cube
58 allIds = ids;
59 } else {
60 // otherwise the ids in the source cubes define the ids in the result cube
61 for (Size i = 0; i < cubes_.size(); ++i) {
62 for (auto const& [id, ignored] : cubes_[i]->idsAndIndexes()) {
63 const auto& [ignored2, success] = allIds.insert(id);
64 QL_REQUIRE(success,
65 "JointNPVSensiCube: input cubes have duplicate id '" << id << "', this is not allowed");
66 }
67 }
68 }
69
70 // build list of result cube ids
71 Size pos = 0;
72 for (const auto& id : allIds) {
73 idIdx_[id] = pos++;
74 }
75
76 // populate cubeAndId_ vector which is the basis for the lookup
77 cubeAndId_.resize(idIdx_.size());
78 for (const auto& [id, jointPos] : idIdx_) {
79 for (auto const& c : cubes_) {
80 auto searchIt = c->idsAndIndexes().find(id);
81 if (searchIt != c->idsAndIndexes().end()) {
82 QL_REQUIRE(cubeAndId_[jointPos].first == nullptr,
83 "JointNPVSensiCube: input cubes have duplicate id '" << id << "', this is not allowed");
84 cubeAndId_[jointPos] = std::make_pair(c, searchIt->second);
85 }
86 }
87 }
88}
89
90Size JointNPVSensiCube::numIds() const { return idIdx_.size(); }
91
92Size JointNPVSensiCube::numDates() const { return cubes_[0]->numDates(); }
93
94Size JointNPVSensiCube::samples() const { return cubes_[0]->samples(); }
95
96Size JointNPVSensiCube::depth() const { return cubes_[0]->depth(); }
97
98const std::map<std::string, Size>& JointNPVSensiCube::idsAndIndexes() const { return idIdx_; }
99
100const std::vector<QuantLib::Date>& JointNPVSensiCube::dates() const { return cubes_[0]->dates(); }
101
102QuantLib::Date JointNPVSensiCube::asof() const { return cubes_[0]->asof(); }
103
104const std::pair<QuantLib::ext::shared_ptr<NPVSensiCube>, Size>& JointNPVSensiCube::cubeAndId(Size id) const {
105 QL_REQUIRE(id < cubeAndId_.size(),
106 "JointNPVSensiCube: id (" << id << ") out of range, have " << cubeAndId_.size() << " ids");
107 return cubeAndId_[id];
108}
109
110Real JointNPVSensiCube::getT0(Size id, Size depth) const {
111 const auto& c = cubeAndId(id);
112 return c.first->getT0(c.second, depth);
113}
114
115void JointNPVSensiCube::setT0(Real value, Size id, Size depth) {
116 const auto& c = cubeAndId(id);
117 c.first->setT0(value, c.second, depth);
118}
119
120Real JointNPVSensiCube::get(Size id, Size date, Size sample, Size depth) const {
121 const auto& c = cubeAndId(id);
122 return c.first->get(c.second, date, sample, depth);
123}
124
125void JointNPVSensiCube::set(Real value, Size id, Size date, Size sample, Size depth) {
126 const auto& c = cubeAndId(id);
127 c.first->set(value, c.second, date, sample, depth);
128}
129
130std::map<QuantLib::Size, QuantLib::Real> JointNPVSensiCube::getTradeNPVs(Size tradeIdx) const {
131 const auto& c = cubeAndId(tradeIdx);
132 return c.first->getTradeNPVs(c.second);
133}
134
135std::set<QuantLib::Size> JointNPVSensiCube::relevantScenarios() const {
136 std::set<QuantLib::Size> tmp;
137 for (auto const& c : cubes_) {
138 auto r = c->relevantScenarios();
139 tmp.insert(r.begin(), r.end());
140 }
141 return tmp;
142}
143
145 const auto& c = cubeAndId(id);
146 c.first->remove(c.second);
147}
148
149void JointNPVSensiCube::remove(Size id, Size sample) {
150 const auto& c = cubeAndId(id);
151 c.first->remove(c.second, sample);
152}
153
154} // namespace analytics
155} // namespace ore
void set(Real value, Size id, Size date, Size sample, Size depth=0) override
Set a value in the cube using index.
std::set< QuantLib::Size > relevantScenarios() const override
const std::map< std::string, Size > & idsAndIndexes() const override
Get a map of id and their index position in this cube.
Real getT0(Size id, Size depth=0) const override
Get a T0 value from the cube using index.
std::vector< std::pair< QuantLib::ext::shared_ptr< NPVSensiCube >, Size > > cubeAndId_
Size numIds() const override
Return the length of each dimension.
const std::pair< QuantLib::ext::shared_ptr< NPVSensiCube >, Size > & cubeAndId(Size id) const
const std::vector< QuantLib::ext::shared_ptr< NPVSensiCube > > cubes_
JointNPVSensiCube(const QuantLib::ext::shared_ptr< NPVSensiCube > &cube1, const QuantLib::ext::shared_ptr< NPVSensiCube > &cube2, const std::set< std::string > &ids={})
const std::vector< QuantLib::Date > & dates() const override
Get the vector of dates for this cube.
QuantLib::Date asof() const override
Return the asof date (T0 date)
std::map< QuantLib::Size, QuantLib::Real > getTradeNPVs(Size tradeIdx) const override
std::map< std::string, Size > idIdx_
void setT0(Real value, Size id, Size depth=0) override
Set a value in the cube using index.
Real get(Size id, Size date, Size sample, Size depth=0) const override
Get a value from the cube using index.
const std::set< std::string > ids() const
Get a set of all ids in the cube.
Definition: npvcube.hpp:75
NPVSensiCube class stores NPVs resulting from risk factor shifts on an as of date.
SafeStack< ValueType > value
join n sensi cubes in terms of stored ids