Skip to content

Commit 29b7df6

Browse files
pcaspersjenkins
authored andcommitted
QPR-12349 always write out the union over keys available in all scenarios
1 parent 47cc093 commit 29b7df6

3 files changed

Lines changed: 30 additions & 14 deletions

File tree

OREAnalytics/orea/app/reportwriter.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2152,10 +2152,14 @@ void ReportWriter::writeHistoricalScenarioDistributions(
21522152

21532153
void ReportWriter::writeHistoricalScenarios(const boost::shared_ptr<HistoricalScenarioLoader>& hsloader,
21542154
const boost::shared_ptr<ore::data::Report>& report) {
2155-
ScenarioWriter sw(nullptr, report);
2156-
auto scenarios = hsloader->historicalScenarios();
2155+
// each scenario might have a different set of keys, so we collect the union of all keys
2156+
// and write them out (missing keys will be written as NA to the report)
2157+
std::set<RiskFactorKey> allKeys;
2158+
for (const auto& s : hsloader->historicalScenarios())
2159+
allKeys.insert(s->keys().begin(), s->keys().end());
2160+
ScenarioWriter sw(nullptr, report, std::vector<RiskFactorKey>(allKeys.begin(), allKeys.end()));
21572161
bool writeHeader = true;
2158-
for (const auto& s : scenarios) {
2162+
for (const auto& s : hsloader->historicalScenarios()) {
21592163
sw.writeScenario(s, writeHeader);
21602164
writeHeader = false;
21612165
}

OREAnalytics/orea/scenario/scenariowriter.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,21 @@ namespace ore {
2525
namespace analytics {
2626

2727
ScenarioWriter::ScenarioWriter(const boost::shared_ptr<ScenarioGenerator>& src, const std::string& filename,
28-
const char sep, const string& filemode)
29-
: src_(src), fp_(nullptr), i_(0), sep_(sep) {
28+
const char sep, const string& filemode, const std::vector<RiskFactorKey>& headerKeys)
29+
: src_(src), fp_(nullptr), i_(0), sep_(sep), headerKeys_(headerKeys) {
3030
open(filename, filemode);
3131
}
3232

33-
ScenarioWriter::ScenarioWriter(const std::string& filename, const char sep, const string& filemode)
34-
: fp_(nullptr), i_(0), sep_(sep) {
33+
ScenarioWriter::ScenarioWriter(const std::string& filename, const char sep, const string& filemode,
34+
const std::vector<RiskFactorKey>& headerKeys)
35+
: fp_(nullptr), i_(0), sep_(sep), headerKeys_(headerKeys) {
3536
open(filename, filemode);
3637
}
3738

38-
ScenarioWriter::ScenarioWriter(const boost::shared_ptr<ScenarioGenerator>& src, boost::shared_ptr<ore::data::Report> report)
39-
: src_(src), report_(report), fp_(nullptr), i_(0), sep_(',') {}
39+
ScenarioWriter::ScenarioWriter(const boost::shared_ptr<ScenarioGenerator>& src,
40+
boost::shared_ptr<ore::data::Report> report,
41+
const std::vector<RiskFactorKey>& headerKeys)
42+
: src_(src), report_(report), fp_(nullptr), i_(0), sep_(','), headerKeys_(headerKeys) {}
4043

4144
void ScenarioWriter::open(const std::string& filename, const std::string& filemode) {
4245
fp_ = fopen(filename.c_str(), filemode.c_str());
@@ -96,6 +99,8 @@ void ScenarioWriter::writeScenario(const boost::shared_ptr<Scenario>& s, const b
9699
if (report_) {
97100
if (writeHeader) {
98101
QL_REQUIRE(keys_.size() > 0, "No keys in scenario");
102+
if (headerKeys_.empty())
103+
headerKeys_ = keys_;
99104
report_->addColumn("Date", string());
100105
report_->addColumn("Scenario", Size());
101106
report_->addColumn("Numeraire", double(), 8);
@@ -110,8 +115,12 @@ void ScenarioWriter::writeScenario(const boost::shared_ptr<Scenario>& s, const b
110115
report_->add(to_string(d));
111116
report_->add(i_);
112117
report_->add(s->getNumeraire());
113-
for (auto k : keys_)
114-
report_->add(s->get(k));
118+
for (auto k : headerKeys_) {
119+
if (s->has(k))
120+
report_->add(s->get(k));
121+
else
122+
report_->add(Null<Real>());
123+
}
115124
}
116125
}
117126

OREAnalytics/orea/scenario/scenariowriter.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,15 @@ class ScenarioWriter : public ScenarioGenerator {
3535
public:
3636
//! Constructor
3737
ScenarioWriter(const boost::shared_ptr<ScenarioGenerator>& src, const std::string& filename, const char sep = ',',
38-
const string& filemode = "w+");
38+
const string& filemode = "w+", const std::vector<RiskFactorKey>& headerKeys = {});
3939

4040
//! Constructor to write single scenarios
41-
ScenarioWriter(const std::string& filename, const char sep = ',', const string& filemode = "w+");
41+
ScenarioWriter(const std::string& filename, const char sep = ',', const string& filemode = "w+",
42+
const std::vector<RiskFactorKey>& headerKeys = {});
4243

4344
//! Constructor to write into an in-memory report for later io
44-
ScenarioWriter(const boost::shared_ptr<ScenarioGenerator>& src, boost::shared_ptr<ore::data::Report> report);
45+
ScenarioWriter(const boost::shared_ptr<ScenarioGenerator>& src, boost::shared_ptr<ore::data::Report> report,
46+
const std::vector<RiskFactorKey>& headerKeys = {});
4547

4648
//! Destructor
4749
virtual ~ScenarioWriter();
@@ -68,6 +70,7 @@ class ScenarioWriter : public ScenarioGenerator {
6870
Date firstDate_;
6971
Size i_;
7072
const char sep_ = ',';
73+
std::vector<RiskFactorKey> headerKeys_;
7174
};
7275
} // namespace analytics
7376
} // namespace ore

0 commit comments

Comments
 (0)