27#include <ql/errors.hpp>
29#include <boost/lexical_cast.hpp>
40 const QuantLib::ext::shared_ptr<ore::data::Market>& market,
const string& marketConfiguration,
41 const QuantLib::ext::shared_ptr<ore::data::EngineData>& engineData,
42 const QuantLib::ext::shared_ptr<ScenarioSimMarketParameters>& simMarketData,
43 const QuantLib::ext::shared_ptr<StressTestScenarioData>& stressData,
45 QuantLib::ext::shared_ptr<ScenarioFactory> scenarioFactory,
46 const QuantLib::ext::shared_ptr<ReferenceDataManager>& referenceData,
49 LOG(
"Run Stress Test");
50 DLOG(
"Build Simulation Market");
51 QuantLib::ext::shared_ptr<ScenarioSimMarket> simMarket = QuantLib::ext::make_shared<ScenarioSimMarket>(
52 market, simMarketData, marketConfiguration,
curveConfigs, todaysMarketParams, continueOnError,
53 stressData->useSpreadedTermStructures(),
false,
false, iborFallbackConfig,
true);
55 DLOG(
"Build Stress Scenario Generator");
56 Date
asof = market->asofDate();
57 QuantLib::ext::shared_ptr<Scenario> baseScenario = simMarket->baseScenario();
58 scenarioFactory = scenarioFactory ? scenarioFactory : QuantLib::ext::make_shared<CloneScenarioFactory>(baseScenario);
59 QuantLib::ext::shared_ptr<StressScenarioGenerator> scenarioGenerator = QuantLib::ext::make_shared<StressScenarioGenerator>(
60 stressData, baseScenario, simMarketData, simMarket, scenarioFactory, simMarket->baseScenarioAbsolute());
61 simMarket->scenarioGenerator() = scenarioGenerator;
63 DLOG(
"Build Engine Factory");
64 map<MarketContext, string> configurations;
65 configurations[MarketContext::pricing] = marketConfiguration;
66 auto ed = QuantLib::ext::make_shared<EngineData>(*engineData);
67 ed->globalParameters()[
"RunType"] =
"Stress";
68 QuantLib::ext::shared_ptr<EngineFactory> factory =
69 QuantLib::ext::make_shared<EngineFactory>(ed, simMarket, configurations, referenceData, iborFallbackConfig);
71 DLOG(
"Reset and Build Portfolio");
73 portfolio->build(factory,
"stress analysis");
75 DLOG(
"Build the cube object to store sensitivities");
76 QuantLib::ext::shared_ptr<NPVCube> cube = QuantLib::ext::make_shared<DoublePrecisionInMemoryCube>(
77 asof, portfolio->ids(), vector<Date>(1,
asof), scenarioGenerator->samples());
79 DLOG(
"Run Stress Scenarios");
80 QuantLib::ext::shared_ptr<DateGrid> dg = QuantLib::ext::make_shared<DateGrid>(
"1,0W", NullCalendar());
81 vector<QuantLib::ext::shared_ptr<ValuationCalculator>> calculators;
82 calculators.push_back(QuantLib::ext::make_shared<NPVCalculator>(simMarketData->baseCcy()));
86 engine.
buildCube(portfolio, cube, calculators);
96 for (
auto const& [tradeId, trade] : portfolio->trades()) {
97 auto index = cube->idsAndIndexes().find(tradeId);
98 if (index == cube->idsAndIndexes().end()) {
99 ALOG(
"cube does not contain tradeId '" << tradeId <<
"'");
102 Real npv0 = cube->getT0(index->second, 0);
105 for (Size j = 0; j < scenarioGenerator->samples(); ++j) {
106 const string& label = scenarioGenerator->scenarios()[j]->label();
107 TLOG(
"Adding stress test result for trade '" << tradeId <<
"' and scenario #" << j <<
" '" << label <<
"'");
108 Real npv = cube->get(index->second, 0, j, 0);
109 pair<string, string> p(tradeId, label);
115 LOG(
"Stress testing done");
120 report->addColumn(
"TradeId",
string());
121 report->addColumn(
"ScenarioLabel",
string());
122 report->addColumn(
"Base NPV",
double(), 2);
123 report->addColumn(
"Scenario NPV",
double(), 2);
124 report->addColumn(
"Sensitivity",
double(), 2);
127 string tradeId =
id.first;
128 string factor =
id.second;
130 Real sensi = npv - base;
131 TLOG(
"Adding stress report result for tradeId '" << tradeId <<
"' and scenario '" << factor <<
": sensi = "
132 << sensi <<
", threshold = " << outputThreshold);
133 if (fabs(sensi) > outputThreshold || QuantLib::close_enough(sensi, outputThreshold)) {
135 report->add(tradeId);
std::map< std::pair< string, string >, Real > delta_
void writeReport(const QuantLib::ext::shared_ptr< ore::data::Report > &report, Real outputThreshold=0.0)
Write NPV by trade/scenario to a file (base and shifted NPVs, delta)
std::map< std::pair< string, string >, Real > shiftedNPV_
std::set< std::string > labels_
StressTest(const QuantLib::ext::shared_ptr< ore::data::Portfolio > &portfolio, const QuantLib::ext::shared_ptr< ore::data::Market > &market, const string &marketConfiguration, const QuantLib::ext::shared_ptr< ore::data::EngineData > &engineData, const QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > &simMarketData, const QuantLib::ext::shared_ptr< StressTestScenarioData > &stressData, const ore::data::CurveConfigurations &curveConfigs=ore::data::CurveConfigurations(), const ore::data::TodaysMarketParameters &todaysMarketParams=ore::data::TodaysMarketParameters(), QuantLib::ext::shared_ptr< ScenarioFactory > scenarioFactory={}, const QuantLib::ext::shared_ptr< ReferenceDataManager > &referenceData=nullptr, const IborFallbackConfig &iborFallbackConfig=IborFallbackConfig::defaultConfig(), bool continueOnError=false)
Constructor.
std::map< std::string, Real > baseNPV_
std::set< std::string > trades_
void buildCube(const QuantLib::ext::shared_ptr< data::Portfolio > &portfolio, QuantLib::ext::shared_ptr< analytics::NPVCube > outputCube, std::vector< QuantLib::ext::shared_ptr< ValuationCalculator > > calculators, bool mporStickyDate=true, QuantLib::ext::shared_ptr< analytics::NPVCube > outputCubeNettingSet=nullptr, QuantLib::ext::shared_ptr< analytics::NPVCube > outputCptyCube=nullptr, std::vector< QuantLib::ext::shared_ptr< CounterpartyCalculator > > cptyCalculators={}, bool dryRun=false)
Build NPV cube.
void registerProgressIndicator(const QuantLib::ext::shared_ptr< ProgressIndicator > &indicator)
factory class for cloning a cached scenario
A cube implementation that stores the cube in memory.
perform a stress testing analysis for a given portfolio.
vector< string > curveConfigs
The counterparty cube calculator interface.