Skip to content

Commit 89db757

Browse files
pcaspersjenkins
authored andcommitted
QPR-11659 add historical scenario details report
1 parent 078e631 commit 89db757

2 files changed

Lines changed: 66 additions & 1 deletion

File tree

OREAnalytics/orea/scenario/historicalscenariogenerator.cpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,23 @@ Real ReturnConfiguration::applyReturn(const RiskFactorKey& key, const Real baseV
137137
return value;
138138
}
139139

140+
const std::map<RiskFactorKey::KeyType, ReturnConfiguration::ReturnType> ReturnConfiguration::returnTypes() const {
141+
return returnType_;
142+
}
143+
144+
std::ostream& operator<<(std::ostream& out, const ReturnConfiguration::ReturnType t) {
145+
switch (t) {
146+
case ReturnConfiguration::ReturnType::Absolute:
147+
return out << "Absolute";
148+
case ReturnConfiguration::ReturnType::Relative:
149+
return out << "Relative";
150+
case ReturnConfiguration::ReturnType::Log:
151+
return out << "Log";
152+
default:
153+
return out << "Unknown ReturnType (" << static_cast<int>(t) << ")";
154+
}
155+
}
156+
140157
void ReturnConfiguration::check(const RiskFactorKey& key) const {
141158

142159
auto keyType = key.keytype;
@@ -223,6 +240,8 @@ boost::shared_ptr<Scenario> HistoricalScenarioGenerator::next(const Date& d) {
223240
boost::shared_ptr<Scenario> scen = scenarioFactory_->buildScenario(d, "", 1.0);
224241

225242
// loop over all keys
243+
calculationDetails_.resize(baseScenario_->keys().size());
244+
Size calcDetailsCounter = 0;
226245
for (auto key : baseScenario_->keys()) {
227246
Real base = baseScenario_->get(key);
228247
Real v1 = 1.0, v2 = 1.0;
@@ -238,14 +257,29 @@ boost::shared_ptr<Scenario> HistoricalScenarioGenerator::next(const Date& d) {
238257
// Calculate the returned value
239258
Real returnVal = returnConfiguration_.returnValue(key, v1, v2, s1->asof(), s2->asof());
240259
// Adjust return for any scaling
241-
returnVal = returnVal * scaling(key, returnVal);
260+
Real scaling = this->scaling(key, returnVal);
261+
returnVal = returnVal * scaling;
242262
// Calculate the shifted value
243263
value = returnConfiguration_.applyReturn(key, base, returnVal);
244264
if (std::isinf(value)) {
245265
ALOG("Value is inf for " << key << " from date " << s1->asof() << " to " << s2->asof());
246266
}
247267
// Add it
248268
scen->add(key, value);
269+
// Populate calculation details
270+
calculationDetails_[calcDetailsCounter].scenarioDate1 = s1->asof();
271+
calculationDetails_[calcDetailsCounter].scenarioDate2 = s2->asof();
272+
calculationDetails_[calcDetailsCounter].key = key;
273+
calculationDetails_[calcDetailsCounter].baseValue = base;
274+
calculationDetails_[calcDetailsCounter].adjustmentFactor1 = adjFactors_->getFactor(key.name, s1->asof());
275+
calculationDetails_[calcDetailsCounter].adjustmentFactor2 = adjFactors_->getFactor(key.name, s2->asof());
276+
calculationDetails_[calcDetailsCounter].scenarioValue1 = v1;
277+
calculationDetails_[calcDetailsCounter].scenarioValue2 = v2;
278+
calculationDetails_[calcDetailsCounter].returnType = returnConfiguration_.returnTypes().at(key.keytype);
279+
calculationDetails_[calcDetailsCounter].scaling = scaling;
280+
calculationDetails_[calcDetailsCounter].returnValue = returnVal;
281+
calculationDetails_[calcDetailsCounter].scenarioValue = value;
282+
++calcDetailsCounter;
249283
}
250284

251285
// Label the scenario
@@ -258,6 +292,11 @@ boost::shared_ptr<Scenario> HistoricalScenarioGenerator::next(const Date& d) {
258292
return scen;
259293
}
260294

295+
const std::vector<HistoricalScenarioGenerator::HistoricalScenarioCalculationDetails>&
296+
HistoricalScenarioGenerator::lastHistoricalScenarioCalculationDetails() const {
297+
return calculationDetails_;
298+
}
299+
261300
Size HistoricalScenarioGenerator::numScenarios() const {
262301
// We have a start date for each valid scenario
263302
return startDates_.size();

OREAnalytics/orea/scenario/historicalscenariogenerator.hpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,18 @@ class ReturnConfiguration {
5858
QuantLib::Real applyReturn(const RiskFactorKey& key, const QuantLib::Real baseValue,
5959
const QuantLib::Real returnValue) const;
6060

61+
//! get return types
62+
const std::map<RiskFactorKey::KeyType, ReturnType> returnTypes() const;
63+
6164
private:
6265
const std::map<RiskFactorKey::KeyType, ReturnType> returnType_;
6366

6467
//! Perform checks on key
6568
void check(const RiskFactorKey& key) const;
6669
};
6770

71+
std::ostream& operator<<(std::ostream& out, const ReturnConfiguration::ReturnType t);
72+
6873
//! Historical Scenario Generator
6974
/*! A Scenario Generator that takes historical scenarios and builds new scenarios by applying historical shifts to the
7075
* base scenario (which typically comes from todays market).
@@ -78,6 +83,21 @@ class ReturnConfiguration {
7883
*/
7984
class HistoricalScenarioGenerator : public ScenarioGenerator {
8085
public:
86+
struct HistoricalScenarioCalculationDetails {
87+
Date scenarioDate1;
88+
Date scenarioDate2;
89+
RiskFactorKey key;
90+
double baseValue;
91+
double adjustmentFactor1;
92+
double adjustmentFactor2;
93+
double scenarioValue1;
94+
double scenarioValue2;
95+
ReturnConfiguration::ReturnType returnType;
96+
double scaling;
97+
double returnValue;
98+
double scenarioValue;
99+
};
100+
81101
//! Default constructor
82102
HistoricalScenarioGenerator(
83103
//! Historical Scenario Loader containing all scenarios
@@ -125,6 +145,9 @@ class HistoricalScenarioGenerator : public ScenarioGenerator {
125145
*/
126146
boost::shared_ptr<Scenario> next(const QuantLib::Date& d) override;
127147

148+
//! Return the calculation details of the last generated scenario */
149+
const std::vector<HistoricalScenarioCalculationDetails>& lastHistoricalScenarioCalculationDetails() const;
150+
128151
//! Reset the generator so calls to next() return the first scenario.
129152
/*! This allows re-generation of scenarios if required. */
130153
void reset() override { i_ = 0; }
@@ -174,6 +197,9 @@ class HistoricalScenarioGenerator : public ScenarioGenerator {
174197
Only handles equity spot adjustments at the moment */
175198
QuantLib::Real adjustedPrice(RiskFactorKey key, QuantLib::Date d, QuantLib::Real price);
176199

200+
// details on the last generated scenario
201+
std::vector<HistoricalScenarioCalculationDetails> calculationDetails_;
202+
177203
private:
178204
QuantLib::Calendar cal_;
179205
boost::shared_ptr<ore::data::AdjustmentFactors> adjFactors_;

0 commit comments

Comments
 (0)