Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
pnlexplainanalytic.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2024 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
28
29using namespace ore::data;
30
31namespace ore {
32namespace analytics {
33
37 analytic()->configurations().todaysMarketParams = inputs_->todaysMarketParams();
38 analytic()->configurations().simMarketParams = inputs_->scenarioSimMarketParams();
39 analytic()->configurations().sensiScenarioData = inputs_->sensiScenarioData();
40}
41
42void PnlExplainAnalyticImpl::runAnalytic(const QuantLib::ext::shared_ptr<ore::data::InMemoryLoader>& loader,
43 const std::set<std::string>& runTypes) {
44
45 CONSOLEW("PNL Explain: Build Market");
46 analytic()->buildMarket(loader);
47 CONSOLE("OK");
48
49 CONSOLEW("PNL Explain: Build Portfolio");
51 CONSOLE("OK");
52
53 auto pnlexplainAnalytic = static_cast<PnlExplainAnalytic*>(analytic());
54 QL_REQUIRE(pnlexplainAnalytic, "Analytic must be of type PnlExplainAnalytic");
55
56 auto pnlAnalytic = dependentAnalytic(pnlLookupKey);
57 pnlAnalytic->runAnalytic(loader);
58 auto pnlReport = pnlAnalytic->reports().at("PNL").at("pnl");
59
60 auto sensiAnalytic = dependentAnalytic(sensiLookupKey);
61
62 // Explicitily set the sensi threshold to 0.0 for sensi analysis, this ensures we get a felta entry for each gamma
63 // TODO: Pass the threshold into the sensi analytic
64 inputs_->setSensiThreshold(QuantLib::Null<QuantLib::Real>());
65 sensiAnalytic->runAnalytic(loader, {"SENSITIVITY"});
66
67 auto sensireport = sensiAnalytic->reports().at("SENSITIVITY").at("sensitivity");
68 analytic()->reports()[label_]["sensitivity"] = sensireport;
69 ext::shared_ptr<SensitivityStream> ss = ext::make_shared<SensitivityReportStream>(sensiAnalytic->reports().at("SENSITIVITY").at("sensitivity"));
70 ss = ext::make_shared<FilteredSensitivityStream>(ss, 1e-6);
71
72 auto sensiReports = sensiAnalytic->reports();
73
74 QuantLib::ext::shared_ptr<ore::data::AdjustmentFactors> adjFactors;
75 if (auto adjLoader = QuantLib::ext::dynamic_pointer_cast<AdjustedInMemoryLoader>(loader))
76 adjFactors = QuantLib::ext::make_shared<ore::data::AdjustmentFactors>(adjLoader->adjustmentFactors());
77
78 // dates needed for scenarios
79 set<Date> pnlDates;
80 pnlDates.insert(inputs_->asof());
81 pnlDates.insert(inputs_->mporDate());
82 TimePeriod period({inputs_->asof(), inputs_->mporDate()});
83
84 QuantLib::ext::shared_ptr<HistoricalScenarioGenerator> scenarios;
85 if (!inputs_->historicalScenarioReader()) {
86
87 auto pnlImpl = static_cast<PnlAnalyticImpl*>(pnlAnalytic->impl().get());
88 QL_REQUIRE(pnlImpl, "Impl must of type PNLAnalyticImpl");
89 auto t0Scenario = pnlImpl->t0Scenario();
90 auto t1Scenario = pnlImpl->t1Scenario();
91
92 analytic()->reports()[label_]["pnl_scenario_t0"] = pnlAnalytic->reports().at("PNL").at("pnl_scenario_t0");
93 analytic()->reports()[label_]["pnl_scenario_t1"] = pnlAnalytic->reports().at("PNL").at("pnl_scenario_t1");
94
95 vector<QuantLib::ext::shared_ptr<ore::analytics::Scenario>> histScens = {t0Scenario, t1Scenario};
96
97 QuantLib::ext::shared_ptr<HistoricalScenarioLoader> scenarioLoader =
98 QuantLib::ext::make_shared<HistoricalScenarioLoader>(histScens, pnlDates);
99
100 scenarios = QuantLib::ext::make_shared<HistoricalScenarioGenerator>(
101 scenarioLoader, QuantLib::ext::make_shared<SimpleScenarioFactory>(), adjFactors,
102 ReturnConfiguration(), "hs_");
103 } else {
104 auto scenarios = buildHistoricalScenarioGenerator(inputs_->historicalScenarioReader(), adjFactors, pnlDates,
105 analytic()->configurations().simMarketParams,
106 analytic()->configurations().todaysMarketParams);
107 }
108
109 auto simMarket = QuantLib::ext::make_shared<ScenarioSimMarket>(
110 analytic()->market(), analytic()->configurations().simMarketParams, Market::defaultConfiguration,
111 *analytic()->configurations().curveConfig, *analytic()->configurations().todaysMarketParams, true, true,
112 false, false, *inputs_->iborFallbackConfig());
113 simMarket->scenarioGenerator() = scenarios;
114 scenarios->baseScenario() = simMarket->baseScenario();
115
116 ext::shared_ptr<ScenarioShiftCalculator> shiftCalculator = ext::make_shared<ScenarioShiftCalculator>(
117 analytic()->configurations().sensiScenarioData, analytic()->configurations().simMarketParams);
118
119 std::unique_ptr<MarketRiskReport::SensiRunArgs> sensiArgs =
120 std::make_unique<MarketRiskReport::SensiRunArgs>(ss, shiftCalculator);
121
122 auto pnlExplainReport =
123 ext::make_shared<PnlExplainReport>(inputs_->baseCurrency(), analytic()->portfolio(), inputs_->portfolioFilter(),
124 period, pnlReport, scenarios, std::move(sensiArgs), nullptr, nullptr, true);
125
126 LOG("Call PNL Explain calculation");
127 CONSOLEW("Risk: PNL Explain Calculation");
128 ext::shared_ptr<MarketRiskReport::Reports> reports = ext::make_shared<MarketRiskReport::Reports>();
129 QuantLib::ext::shared_ptr<InMemoryReport> pnlExplainOutput = QuantLib::ext::make_shared<InMemoryReport>();
130 reports->add(pnlReport);
131
132 pnlExplainReport->calculate(reports);
133 analytic()->reports()[label_]["pnl"] = pnlReport;
134 analytic()->reports()[label_]["pnl_explain"] = pnlReport;
135}
136
137} // namespace analytics
138} // namespace ore
Analytic * analytic() const
Definition: analytic.hpp:193
std::string label_
label for logging purposes primarily
Definition: analytic.hpp:219
QuantLib::ext::shared_ptr< T > dependentAnalytic(const std::string &key) const
Definition: analytic.hpp:251
QuantLib::ext::shared_ptr< InputParameters > inputs_
Definition: analytic.hpp:216
analytic_reports & reports()
Result reports.
Definition: analytic.hpp:131
Configurations & configurations()
Definition: analytic.hpp:128
virtual void buildMarket(const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &loader, const bool marketRequired=true)
Definition: analytic.cpp:178
virtual void buildPortfolio()
Definition: analytic.cpp:222
static constexpr const char * sensiLookupKey
virtual void runAnalytic(const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &loader, const std::set< std::string > &runTypes={}) override
static constexpr const char * pnlLookupKey
Return type for historical scenario generation (absolute, relative, log)
static const string defaultConfiguration
Class that wraps a sensitivity stream and filters out negligible records.
#define LOG(text)
#define CONSOLEW(text)
#define CONSOLE(text)
QuantLib::ext::shared_ptr< HistoricalScenarioGenerator > buildHistoricalScenarioGenerator(const QuantLib::ext::shared_ptr< HistoricalScenarioReader > &hsr, const QuantLib::ext::shared_ptr< ore::data::AdjustmentFactors > &adjFactors, const TimePeriod &period, Calendar calendar, Size mporDays, const QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > &simParams, const QuantLib::ext::shared_ptr< TodaysMarketParameters > &marketParams, const bool overlapping)
Class for calculating the shift multiple between two scenarios for a given key.
Class for streaming SensitivityRecords from a report.
Simple scenario class.
factory classes for simple scenarios
QuantLib::ext::shared_ptr< ore::analytics::SensitivityScenarioData > sensiScenarioData
Definition: analytic.hpp:70
QuantLib::ext::shared_ptr< ore::data::TodaysMarketParameters > todaysMarketParams
Definition: analytic.hpp:68
bool simulationConfigRequired
Booleans to determine if these configs are needed.
Definition: analytic.hpp:64
QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarketParameters > simMarketParams
Definition: analytic.hpp:69