Skip to content

Commit c516e42

Browse files
mgronckijenkins
authored andcommitted
QPR-12437 xva sensitivity analytic
1 parent 56a53b8 commit c516e42

10 files changed

Lines changed: 109 additions & 33 deletions

File tree

OREAnalytics/orea/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ app/analytics/simmanalytic.cpp
3030
app/analytics/stresstestanalytic.cpp
3131
app/analytics/varanalytic.cpp
3232
app/analytics/xvaanalytic.cpp
33+
app/analytics/xvasensitivityanalytic.cpp
3334
app/analytics/xvastressanalytic.cpp
3435
app/analyticsmanager.cpp
3536
app/cleanupsingletons.cpp
@@ -188,6 +189,7 @@ app/analytics/simmanalytic.hpp
188189
app/analytics/stresstestanalytic.hpp
189190
app/analytics/varanalytic.hpp
190191
app/analytics/xvaanalytic.hpp
192+
app/analytics/xvasensitivityanalytic.hpp
191193
app/analytics/xvastressanalytic.hpp
192194
app/analyticsmanager.hpp
193195
app/cleanupsingletons.hpp

OREAnalytics/orea/app/analytics/xvasensitivityanalytic.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ void XvaSensitivityAnalyticImpl::runAnalytic(const QuantLib::ext::shared_ptr<ore
3939

4040
// basic setup
4141

42-
LOG("Running XVA Stress analytic.");
42+
LOG("Running XVA_SENSITIVITY analytic.");
4343

4444
Settings::instance().evaluationDate() = inputs_->asof();
4545

@@ -67,7 +67,7 @@ void XvaSensitivityAnalyticImpl::runAnalytic(const QuantLib::ext::shared_ptr<ore
6767
auto scenarioFactory = QuantLib::ext::make_shared<CloneScenarioFactory>(baseScenario);
6868
auto scenarioGenerator = QuantLib::ext::make_shared<SensitivityScenarioGenerator>(
6969
analytic()->configurations().sensiScenarioData, baseScenario, analytic()->configurations().simMarketParams,
70-
simMarket, scenarioFactory, simMarket->baseScenarioAbsolute());
70+
simMarket, scenarioFactory, false);
7171
simMarket->scenarioGenerator() = scenarioGenerator;
7272

7373
CONSOLE("OK");
@@ -147,7 +147,7 @@ void XvaSensitivityAnalyticImpl::setUpConfigurations() {
147147
}
148148

149149
XvaSensitivityAnalytic::XvaSensitivityAnalytic(const QuantLib::ext::shared_ptr<InputParameters>& inputs)
150-
: Analytic(std::make_unique<XvaSensitivityAnalyticImpl>(inputs), {"XVA_STRESS"}, inputs, true, false, false,
150+
: Analytic(std::make_unique<XvaSensitivityAnalyticImpl>(inputs), {"XVA_SENSITIVITY"}, inputs, true, false, false,
151151
false) {
152152
impl()->addDependentAnalytic("XVA", QuantLib::ext::make_shared<XvaAnalytic>(inputs));
153153
}

OREAnalytics/orea/app/analytics/xvasensitivityanalytic.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@
2323
#pragma once
2424

2525
#include <orea/app/analytic.hpp>
26+
#include <orea/scenario/sensitivityscenariogenerator.hpp>
2627
#include <ored/report/inmemoryreport.hpp>
2728

28-
2929
namespace ore {
3030
namespace analytics {
3131

3232
class XvaSensitivityAnalyticImpl : public Analytic::Impl {
3333
public:
34-
static constexpr const char* LABEL = "XVA_SENSI";
34+
static constexpr const char* LABEL = "XVA_SENSITIVITY";
3535
explicit XvaSensitivityAnalyticImpl(const QuantLib::ext::shared_ptr<InputParameters>& inputs);
3636
void runAnalytic(const QuantLib::ext::shared_ptr<ore::data::InMemoryLoader>& loader,
3737
const std::set<std::string>& runTypes = {}) override;

OREAnalytics/orea/app/initbuilders.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <orea/app/analytics/stresstestanalytic.hpp>
3333
#include <orea/app/analytics/varanalytic.hpp>
3434
#include <orea/app/analytics/xvaanalytic.hpp>
35+
#include <orea/app/analytics/xvasensitivityanalytic.hpp>
3536
#include <orea/app/analytics/xvastressanalytic.hpp>
3637

3738
#include <ored/utilities/databuilders.hpp>
@@ -66,6 +67,7 @@ void initBuilders(const bool registerOREAnalytics) {
6667
ORE_REGISTER_ANALYTIC_BUILDER("STRESS", {}, StressTestAnalytic, false);
6768
ORE_REGISTER_ANALYTIC_BUILDER("PARSTRESSCONVERSION", {}, ParStressConversionAnalytic, false);
6869
ORE_REGISTER_ANALYTIC_BUILDER("XVA_STRESS", {}, XvaStressAnalytic, false);
70+
ORE_REGISTER_ANALYTIC_BUILDER("XVA_SENSITIVITY", {}, XvaSensitivityAnalytic, false);
6971
}
7072
}
7173

OREAnalytics/orea/app/inputparameters.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,31 @@ void InputParameters::setXvaStressSensitivityScenarioDataFromFile(const std::str
327327
xvaStressSensitivityScenarioData_->fromFile(fileName);
328328
}
329329

330+
void InputParameters::setXvaSensiSimMarketParams(const std::string& xml) {
331+
xvaSensiSimMarketParams_ = QuantLib::ext::make_shared<ScenarioSimMarketParameters>();
332+
xvaSensiSimMarketParams_->fromXMLString(xml);
333+
}
334+
void InputParameters::setXvaSensiSimMarketParamsFromFile(const std::string& fileName) {
335+
xvaSensiSimMarketParams_ = QuantLib::ext::make_shared<ScenarioSimMarketParameters>();
336+
xvaSensiSimMarketParams_->fromFile(fileName);
337+
}
338+
void InputParameters::setXvaSensiScenarioData(const std::string& xml) {
339+
xvaSensiScenarioData_ = boost::make_shared<SensitivityScenarioData>();
340+
xvaSensiScenarioData_->fromXMLString(xml);
341+
}
342+
void InputParameters::setXvaSensiScenarioDataFromFile(const std::string& fileName) {
343+
xvaSensiScenarioData_ = boost::make_shared<SensitivityScenarioData>();
344+
xvaSensiScenarioData_->fromFile(fileName);
345+
}
346+
void InputParameters::setXvaSensiPricingEngine(const std::string& xml) {
347+
xvaSensiPricingEngine_ = QuantLib::ext::make_shared<EngineData>();
348+
xvaSensiPricingEngine_->fromXMLString(xml);
349+
}
350+
void InputParameters::setXvaSensiPricingEngineFromFile(const std::string& fileName) {
351+
xvaSensiPricingEngine_ = QuantLib::ext::make_shared<EngineData>();
352+
xvaSensiPricingEngine_->fromFile(fileName);
353+
}
354+
330355
void InputParameters::setAmcPricingEngineFromFile(const std::string& fileName) {
331356
amcPricingEngine_ = QuantLib::ext::make_shared<EngineData>();
332357
amcPricingEngine_->fromFile(fileName);

OREAnalytics/orea/app/inputparameters.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,18 @@ class InputParameters {
319319
void setXvaStressSensitivityScenarioData(const std::string& xml);
320320
void setXvaStressSensitivityScenarioDataFromFile(const std::string& fileName);
321321
void setXvaStressWriteCubes(const bool writeCubes) { xvaStressWriteCubes_ = writeCubes; }
322+
323+
// Setters for xvaStress
324+
void setXvaSensiSimMarketParams(const std::string& xml);
325+
void setXvaSensiSimMarketParamsFromFile(const std::string& fileName);
326+
void setXvaSensiScenarioData(const std::string& xml);
327+
void setXvaSensiScenarioDataFromFile(const std::string& fileName);
328+
void setXvaSensiPricingEngine(const std::string& xml);
329+
void setXvaSensiPricingEngineFromFile(const std::string& fileName);
330+
void setXvaSensiPricingEngine(const QuantLib::ext::shared_ptr<EngineData>& engineData) {
331+
sensiPricingEngine_ = engineData;
332+
}
333+
322334
// Setters for SIMM
323335
void setSimmVersion(const std::string& s) { simmVersion_ = s; }
324336

OREAnalytics/orea/app/oreapp.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,10 @@ void OREAppInputParameters::loadParameters() {
13791379
if (!tmp.empty() && parseBool(tmp))
13801380
insertAnalytic("XVA_STRESS");
13811381

1382+
tmp = params_->get("xvaSensitivity", "active", false);
1383+
if (!tmp.empty() && parseBool(tmp))
1384+
insertAnalytic("XVA_SENSITIVITY");
1385+
13821386
tmp = params_->get("simulation", "salvageCorrelationMatrix", false);
13831387
if (tmp != "")
13841388
setSalvageCorrelationMatrix(parseBool(tmp));
@@ -1407,7 +1411,8 @@ void OREAppInputParameters::loadParameters() {
14071411
setExposureBaseCurrency(baseCurrency());
14081412

14091413
if (analytics().find("EXPOSURE") != analytics().end() || analytics().find("XVA") != analytics().end() ||
1410-
analytics().find("XVA_STRESS") != analytics().end()) {
1414+
analytics().find("XVA_STRESS") != analytics().end() ||
1415+
analytics().find("XVA_SENSITIVITY") != analytics().end()) {
14111416
tmp = params_->get("simulation", "simulationConfigFile", false);
14121417
if (tmp != "") {
14131418
string simulationConfigFile = (inputPath / tmp).generic_string();
@@ -1505,7 +1510,8 @@ void OREAppInputParameters::loadParameters() {
15051510
}
15061511
}
15071512

1508-
if (analytics().find("XVA") != analytics().end() || analytics().find("XVA_STRESS") != analytics().end()) {
1513+
if (analytics().find("XVA") != analytics().end() || analytics().find("XVA_STRESS") != analytics().end() ||
1514+
analytics().find("XVA_SENSITIVITY") != analytics().end()) {
15091515
tmp = params_->get("xva", "csaFile", false);
15101516
QL_REQUIRE(tmp != "", "Netting set manager is required for XVA");
15111517
string csaFile = (inputPath / tmp).generic_string();
@@ -1818,6 +1824,30 @@ void OREAppInputParameters::loadParameters() {
18181824
}
18191825
}
18201826

1827+
/*************
1828+
* XVA Sensi
1829+
*************/
1830+
1831+
if (analytics().find("XVA_SENSITIVITY") != analytics().end()) {
1832+
tmp = params_->get("xvaSensitivity", "marketConfigFile", false);
1833+
if (!tmp.empty()) {
1834+
string file = (inputPath / tmp).generic_string();
1835+
LOG("Loading xva stress test scenario sim market parameters from file" << file);
1836+
setXvaSensiSimMarketParamsFromFile(file);
1837+
} else {
1838+
WLOG("ScenarioSimMarket parameters for xva stress testing not loaded");
1839+
}
1840+
1841+
tmp = params_->get("xvaStress", "sensitivityConfigFile", false);
1842+
if (!tmp.empty()) {
1843+
string file = (inputPath / tmp).generic_string();
1844+
LOG("Load xav stress test scenario data from file" << file);
1845+
setXvaSensiScenarioDataFromFile(file);
1846+
} else {
1847+
WLOG("Xva Stress scenario data not loaded");
1848+
}
1849+
}
1850+
18211851
/*************
18221852
* cashflow npv and dynamic backtesting
18231853
*************/

OREAnalytics/orea/orea.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <orea/app/analytics/stresstestanalytic.hpp>
3636
#include <orea/app/analytics/varanalytic.hpp>
3737
#include <orea/app/analytics/xvaanalytic.hpp>
38+
#include <orea/app/analytics/xvasensitivityanalytic.hpp>
3839
#include <orea/app/analytics/xvastressanalytic.hpp>
3940
#include <orea/app/analyticsmanager.hpp>
4041
#include <orea/app/cleanupsingletons.hpp>

OREData/ored/report/utilities.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,34 @@ addColumnToExisitingReport(const std::string& columnName, const std::string& val
4747
return newReport;
4848
}
4949

50+
QuantLib::ext::shared_ptr<ore::data::InMemoryReport>
51+
addColumnsToExisitingReport(const QuantLib::ext::shared_ptr<ore::data::InMemoryReport>& newColsReport,
52+
const QuantLib::ext::shared_ptr<ore::data::InMemoryReport>& report) {
53+
QuantLib::ext::shared_ptr<ore::data::InMemoryReport> newReport =
54+
QuantLib::ext::make_shared<ore::data::InMemoryReport>();
55+
if (report != nullptr && newColsReport->rows() == 1) {
56+
57+
for (size_t i = 0; i < newColsReport->columns(); ++i) {
58+
newReport->addColumn(newColsReport->header(i), newColsReport->columnType(i),
59+
newColsReport->columnPrecision(i));
60+
}
61+
for (size_t i = 0; i < report->columns(); i++) {
62+
newReport->addColumn(report->header(i), report->columnType(i), report->columnPrecision(i));
63+
}
64+
for (size_t row = 0; row < report->rows(); row++) {
65+
newReport->next();
66+
for (size_t i = 0; i < newColsReport->columns(); ++i) {
67+
newReport->add(newColsReport->data(i)[0]);
68+
}
69+
for (size_t col = 0; col < report->columns(); col++) {
70+
newReport->add(report->data(col)[row]);
71+
}
72+
}
73+
newReport->end();
74+
}
75+
return newReport;
76+
}
77+
5078
QuantLib::ext::shared_ptr<ore::data::InMemoryReport>
5179
concatenateReports(const std::vector<QuantLib::ext::shared_ptr<ore::data::InMemoryReport>>& reports) {
5280
if (!reports.empty() && reports.front() != nullptr) {

OREData/ored/report/utilities.hpp

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,32 +37,8 @@ addColumnToExisitingReport(const std::string& columnName, const std::string& val
3737

3838
QuantLib::ext::shared_ptr<ore::data::InMemoryReport>
3939
addColumnsToExisitingReport(const QuantLib::ext::shared_ptr<ore::data::InMemoryReport>& newColsReport,
40-
const QuantLib::ext::shared_ptr<ore::data::InMemoryReport>& report) {
41-
QuantLib::ext::shared_ptr<ore::data::InMemoryReport> newReport =
42-
QuantLib::ext::make_shared<ore::data::InMemoryReport>();
43-
if (report != nullptr && newColsReport->rows() == 1) {
44-
45-
for (size_t i = 0; i < newColsReport->columns(); ++i) {
46-
newReport->addColumn(newColsReport->header(i), newColsReport->columnType(i),
47-
newColsReport->columnPrecision(i));
48-
}
49-
for (size_t i = 0; i < report->columns(); i++) {
50-
newReport->addColumn(report->header(i), report->columnType(i), report->columnPrecision(i));
51-
}
52-
for (size_t row = 0; row < report->rows(); row++) {
53-
newReport->next();
54-
for (size_t i = 0; i < newColsReport->columns(); ++i) {
55-
newReport->add(newColsReport->data(i)[0]);
56-
}
57-
for (size_t col = 0; col < report->columns(); col++) {
58-
newReport->add(report->data(col)[row]);
59-
}
60-
}
61-
newReport->end();
62-
}
63-
return newReport;
64-
}
65-
40+
const QuantLib::ext::shared_ptr<ore::data::InMemoryReport>& report);
41+
6642
QuantLib::ext::shared_ptr<ore::data::InMemoryReport>
6743
concatenateReports(const std::vector<QuantLib::ext::shared_ptr<ore::data::InMemoryReport>>& reports);
6844

0 commit comments

Comments
 (0)