Skip to content

Commit 2285189

Browse files
committed
QPR-13719 add cube npv overlay
1 parent 775d177 commit 2285189

6 files changed

Lines changed: 52 additions & 3 deletions

File tree

OREAnalytics/orea/app/analytics/pricinganalytic.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ namespace analytics {
3333
* PRICING Analytic: NPV, CASHFLOW, CASHFLOWNPV, SENSITIVITY, STRESS
3434
*******************************************************************/
3535

36+
void PricingAnalyticImpl::overwriteResultCurrency(const std::string& ccy) { overwriteResultCurrency_ = ccy; }
37+
3638
void PricingAnalyticImpl::setUpConfigurations() {
3739
if (find(begin(analytic()->analyticTypes()), end(analytic()->analyticTypes()), "SENSITIVITY") !=
3840
end(analytic()->analyticTypes())) {
@@ -83,8 +85,12 @@ void PricingAnalyticImpl::runAnalytic(
8385
if (runTypes.find(type) == runTypes.end())
8486
continue;
8587

86-
std::string effectiveResultCurrency =
87-
inputs_->resultCurrency().empty() ? inputs_->baseCurrency() : inputs_->resultCurrency();
88+
std::string effectiveResultCurrency = inputs_->baseCurrency();
89+
if (inputs_->resultCurrency().empty())
90+
effectiveResultCurrency = inputs_->resultCurrency();
91+
if (overwriteResultCurrency_) {
92+
effectiveResultCurrency = *overwriteResultCurrency_;
93+
}
8894
auto marketConfig = inputs_->marketConfig("pricing");
8995
if (type == "NPV") {
9096
CONSOLEW("Pricing: NPV Report");

OREAnalytics/orea/app/analytics/pricinganalytic.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,16 @@ class PricingAnalyticImpl : public Analytic::Impl {
5252
offsetSimMarketParams_ = offsetSimMarketParams;
5353
}
5454

55+
void overwriteResultCurrency(const std::string& ccy);
56+
5557
private:
5658
QuantLib::ext::shared_ptr<SensitivityAnalysis> sensiAnalysis_;
5759
QuantLib::ext::shared_ptr<ParSensitivityAnalysis> parAnalysis_;
5860

5961
protected:
6062
QuantLib::ext::shared_ptr<Scenario> offsetScenario_;
6163
QuantLib::ext::shared_ptr<ScenarioSimMarketParameters> offsetSimMarketParams_;
64+
std::optional<std::string> overwriteResultCurrency_;
6265
};
6366

6467
static const std::set<std::string> pricingAnalyticSubAnalytics {"NPV", "CASHFLOW", "CASHFLOWNPV", "SENSITIVITY"};

OREAnalytics/orea/app/analytics/xvaanalytic.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <orea/app/reportwriter.hpp>
2828
#include <orea/app/structuredanalyticserror.hpp>
2929
#include <orea/app/structuredanalyticswarning.hpp>
30+
#include <orea/cube/overlaynpvcube.hpp>
3031
#include <orea/cube/jointnpvcube.hpp>
3132
#include <orea/cube/npvcube.hpp>
3233
#include <orea/cube/sparsenpvcube.hpp>
@@ -93,6 +94,13 @@ void XvaAnalyticImpl::buildDependencies() {
9394
if (correlationAnalytic.second)
9495
addDependentAnalytic(corrLookupKey, correlationAnalytic.second);
9596
}
97+
if (inputs_->cubeNpvOverlay()) {
98+
if (auto pricingAnalytic =
99+
AnalyticFactory::instance().build("PRICING", inputs_, analytic()->analyticsManager(), false);
100+
pricingAnalytic.second) {
101+
addDependentAnalytic("PRICING", pricingAnalytic.second);
102+
}
103+
}
96104
}
97105

98106
void XvaAnalyticImpl::feedCorrelationToCAM(const std::map<std::pair<RiskFactorKey, RiskFactorKey>, Real>& corrData){
@@ -969,6 +977,22 @@ void XvaAnalyticImpl::runAnalytic(const QuantLib::ext::shared_ptr<ore::data::InM
969977
Settings::instance().includeReferenceDateEvents() = localIncRefDateEvents;
970978
LOG("Simulation IncludeReferenceDateEvents is set to " << (localIncRefDateEvents ? "true" : "false"));
971979

980+
std::map<std::string, double> cubeNpvOverlay;
981+
if (inputs_->cubeNpvOverlay()) {
982+
auto pricingAnalytic = dependentAnalytic("PRICING");
983+
static_cast<PricingAnalyticImpl*>(pricingAnalytic->impl().get())
984+
->overwriteResultCurrency(analytic()->configurations().simMarketParams->baseCcy());
985+
pricingAnalytic->runAnalytic(loader,{"NPV"});
986+
auto npvReport = pricingAnalytic->reports().at("NPV").at("npv");
987+
// FIXME ensure base currency matches sim market base ccy
988+
std::size_t colTradeId = npvReport->columnPosition("TradeId");
989+
std::size_t colNpvBase = npvReport->columnPosition("NPV(Base)");
990+
for (Size r = 0; r < npvReport->rows(); ++r) {
991+
cubeNpvOverlay[boost::get<std::string>(npvReport->data(colTradeId, r))] =
992+
boost::get<double>(npvReport->data(colNpvBase, r));
993+
}
994+
}
995+
972996
if(inputs_->generateCorrelations()){
973997
auto corrAnalytic = dependentAnalytic(corrLookupKey);
974998
corrAnalytic->runAnalytic(loader,{"CORRELATION"});
@@ -1108,11 +1132,19 @@ void XvaAnalyticImpl::runAnalytic(const QuantLib::ext::shared_ptr<ore::data::InM
11081132
LOG("We have generated an AMC cube only");
11091133
cube_ = amcCube_;
11101134
} else {
1111-
WLOG("We have generated a classic cube only");
1135+
LOG("We have generated a classic cube only");
11121136
}
11131137

11141138
LOG("NPV cube generation completed");
11151139

1140+
/************************************************************
1141+
* Apply correction pricing t0 npv - sim t0 npv if requested
1142+
************************************************************/
1143+
1144+
if (!cubeNpvOverlay.empty()) {
1145+
cube_ = QuantLib::ext::make_shared<OverlayNPVCube>(cube_, cubeNpvOverlay);
1146+
}
1147+
11161148
/***********************************************************************
11171149
* We may have two non-empty portfolios to be merged for post processing
11181150
***********************************************************************/

OREAnalytics/orea/app/inputparameters.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ class InputParameters {
332332
void setStoreSurvivalProbabilities(bool b) { storeSurvivalProbabilities_ = b; }
333333
void setWriteCube(bool b) { writeCube_ = b; }
334334
void setWriteScenarios(bool b) { writeScenarios_ = b; }
335+
void setCubeNpvOverlay(bool b) { cubeNpvOverlay_ = b; }
335336
void setExposureSimMarketParams(const std::string& xml);
336337
void setExposureSimMarketParamsFromFile(const std::string& fileName);
337338
void setScenarioGeneratorData(const std::string& xml);
@@ -823,6 +824,7 @@ class InputParameters {
823824
bool writeCube() const { return writeCube_; }
824825
bool writeScenarios() const { return writeScenarios_; }
825826
bool generateCorrelations() const {return generateCorrelations_;}
827+
bool cubeNpvOverlay() const { return cubeNpvOverlay_; }
826828
const QuantLib::ext::shared_ptr<ore::analytics::ScenarioSimMarketParameters>& exposureSimMarketParams() const { return exposureSimMarketParams_; }
827829
const QuantLib::ext::shared_ptr<ScenarioGeneratorData> scenarioGeneratorData() const { return scenarioGeneratorData_; }
828830
const QuantLib::ext::shared_ptr<CrossAssetModelData>& crossAssetModelData() const { return crossAssetModelData_; }
@@ -1316,6 +1318,7 @@ class InputParameters {
13161318
bool writeCube_ = false;
13171319
bool writeScenarios_ = false;
13181320
bool generateCorrelations_ = false;
1321+
bool cubeNpvOverlay_ = false;
13191322
QuantLib::ext::shared_ptr<ore::analytics::ScenarioSimMarketParameters> exposureSimMarketParams_;
13201323
QuantLib::ext::shared_ptr<ScenarioGeneratorData> scenarioGeneratorData_;
13211324
QuantLib::ext::shared_ptr<CrossAssetModelData> crossAssetModelData_;

OREAnalytics/orea/app/oreapp.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2103,6 +2103,10 @@ void OREAppInputParameters::loadParameters() {
21032103
if (tmp != "")
21042104
setWriteCube(true);
21052105

2106+
tmp = params_->get("simulation", "cubeNpvOverlay", false);
2107+
if (tmp != "")
2108+
setCubeNpvOverlay(parseBool(tmp));
2109+
21062110
tmp = params_->get("simulation", "scenariodump", false);
21072111
if (tmp != "")
21082112
setWriteScenarios(true);

OREAnalytics/orea/orea.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
#include <orea/cube/jointnpvsensicube.hpp>
8484
#include <orea/cube/npvcube.hpp>
8585
#include <orea/cube/npvsensicube.hpp>
86+
#include <orea/cube/overlaynpvcube.hpp>
8687
#include <orea/cube/sensicube.hpp>
8788
#include <orea/cube/sensitivitycube.hpp>
8889
#include <orea/cube/sparsenpvcube.hpp>

0 commit comments

Comments
 (0)