Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Public Member Functions | Static Public Attributes | Private Attributes | List of all members
PnlAnalyticImpl Class Reference

#include <orea/app/analytics/pnlanalytic.hpp>

+ Inheritance diagram for PnlAnalyticImpl:
+ Collaboration diagram for PnlAnalyticImpl:

Public Member Functions

 PnlAnalyticImpl (const QuantLib::ext::shared_ptr< InputParameters > &inputs)
 
void runAnalytic (const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &loader, const std::set< std::string > &runTypes={}) override
 
void setUpConfigurations () override
 
bool useSpreadedTermStructures () const
 
const QuantLib::Date & mporDate () const
 
std::vector< QuantLib::Date > additionalMarketDates () const override
 
const QuantLib::ext::shared_ptr< ore::analytics::Scenario > & t0Scenario () const
 
const QuantLib::ext::shared_ptr< ore::analytics::Scenario > & t1Scenario () const
 
void setT0Scenario (const QuantLib::ext::shared_ptr< ore::analytics::Scenario > &scenario)
 
void setT1Scenario (const QuantLib::ext::shared_ptr< ore::analytics::Scenario > &scenario)
 
- Public Member Functions inherited from Analytic::Impl
 Impl ()
 
 Impl (const QuantLib::ext::shared_ptr< InputParameters > &inputs)
 
virtual ~Impl ()
 
virtual void runAnalytic (const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &loader, const std::set< std::string > &runTypes={})=0
 
virtual void setUpConfigurations ()
 
virtual QuantLib::ext::shared_ptr< ore::data::EngineFactoryengineFactory ()
 build an engine factory More...
 
void setLabel (const string &label)
 
const std::string & label () const
 
void setAnalytic (Analytic *analytic)
 
Analyticanalytic () const
 
void setInputs (const QuantLib::ext::shared_ptr< InputParameters > &inputs)
 
bool generateAdditionalResults () const
 
void setGenerateAdditionalResults (const bool generateAdditionalResults)
 
bool hasDependentAnalytic (const std::string &key)
 
template<class T >
QuantLib::ext::shared_ptr< T > dependentAnalytic (const std::string &key) const
 
QuantLib::ext::shared_ptr< AnalyticdependentAnalytic (const std::string &key) const
 
const std::map< std::string, QuantLib::ext::shared_ptr< Analytic > > & dependentAnalytics () const
 
void addDependentAnalytic (const std::string &key, const QuantLib::ext::shared_ptr< Analytic > &analytic)
 
std::vector< QuantLib::ext::shared_ptr< Analytic > > allDependentAnalytics () const
 
virtual std::vector< QuantLib::Date > additionalMarketDates () const
 

Static Public Attributes

static constexpr const char * LABEL = "PNL"
 
static constexpr const char * mporLookupKey = "MPOR"
 

Private Attributes

bool useSpreadedTermStructures_ = true
 
QuantLib::Date mporDate_
 
QuantLib::ext::shared_ptr< ore::analytics::Scenariot0Scenario_
 
QuantLib::ext::shared_ptr< ore::analytics::Scenariot1Scenario_
 

Additional Inherited Members

- Protected Attributes inherited from Analytic::Impl
QuantLib::ext::shared_ptr< InputParametersinputs_
 
std::string label_
 label for logging purposes primarily More...
 
std::map< std::string, QuantLib::ext::shared_ptr< Analytic > > dependentAnalytics_
 

Detailed Description

Definition at line 32 of file pnlanalytic.hpp.

Constructor & Destructor Documentation

◆ PnlAnalyticImpl()

PnlAnalyticImpl ( const QuantLib::ext::shared_ptr< InputParameters > &  inputs)

Definition at line 37 of file pnlanalytic.hpp.

38 : Analytic::Impl(inputs), useSpreadedTermStructures_(true) {
40 mporDate_ = inputs_->mporDate() != Date()
41 ? inputs_->mporDate()
42 : inputs_->mporCalendar().advance(inputs_->asof(), int(inputs_->mporDays()), QuantExt::Days);
43 LOG("ASOF date " << io::iso_date(inputs_->asof()));
44 LOG("MPOR date " << io::iso_date(mporDate_));
45
46 auto mporAnalytic = AnalyticFactory::instance().build("SCENARIO", inputs);
47 if (mporAnalytic.second) {
48 auto sai = static_cast<ScenarioAnalyticImpl*>(mporAnalytic.second->impl().get());
49 sai->setUseSpreadedTermStructures(true);
50 addDependentAnalytic(mporLookupKey, mporAnalytic.second);
51 }
52 }
void setLabel(const string &label)
Definition: analytic.hpp:189
void addDependentAnalytic(const std::string &key, const QuantLib::ext::shared_ptr< Analytic > &analytic)
Definition: analytic.hpp:209
QuantLib::ext::shared_ptr< InputParameters > inputs_
Definition: analytic.hpp:216
static constexpr const char * mporLookupKey
Definition: pnlanalytic.hpp:35
static constexpr const char * LABEL
Definition: pnlanalytic.hpp:34
#define LOG(text)
+ Here is the call graph for this function:

Member Function Documentation

◆ runAnalytic()

void runAnalytic ( const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &  loader,
const std::set< std::string > &  runTypes = {} 
)
overridevirtual

Implements Analytic::Impl.

Definition at line 43 of file pnlanalytic.cpp.

44 {
45
46 if (!analytic()->match(runTypes))
47 return;
48
49 Settings::instance().evaluationDate() = inputs_->asof();
51 ObservationMode::instance().setMode(inputs_->observationModel());
52
53 QL_REQUIRE(inputs_->portfolio(), "PnlAnalytic::run: No portfolio loaded.");
54 QL_REQUIRE(inputs_->portfolio()->size() > 0, "PnlAnalytic::run: Portfolio is empty.");
55
56 std::string effectiveResultCurrency =
57 inputs_->resultCurrency().empty() ? inputs_->baseCurrency() : inputs_->resultCurrency();
58
59 /*******************************
60 *
61 * 0. Build market and portfolio
62 *
63 *******************************/
64
65 analytic()->buildMarket(loader);
66
67 /****************************************************
68 *
69 * 1. Write the t0 NPV and Additional Results reports
70 *
71 ****************************************************/
72
73 // Build a simMarket on the asof date
74 QL_REQUIRE(analytic()->configurations().simMarketParams, "scenario sim market parameters not set");
75 QL_REQUIRE(analytic()->configurations().todaysMarketParams, "today's market parameters not set");
76
77 auto simMarket = QuantLib::ext::make_shared<ScenarioSimMarket>(
78 analytic()->market(), analytic()->configurations().simMarketParams, inputs_->marketConfig("pricing"),
79 *analytic()->configurations().curveConfig, *analytic()->configurations().todaysMarketParams,
80 inputs_->continueOnError(), useSpreadedTermStructures(), false, false, *inputs_->iborFallbackConfig());
81 auto sgen = QuantLib::ext::make_shared<StaticScenarioGenerator>();
82 simMarket->scenarioGenerator() = sgen;
83
84 analytic()->setMarket(simMarket);
86
87 boost::shared_ptr<InMemoryReport> t0NpvReport = boost::make_shared<InMemoryReport>();
88 ReportWriter(inputs_->reportNaString())
89 .writeNpv(*t0NpvReport, effectiveResultCurrency, analytic()->market(), inputs_->marketConfig("pricing"),
90 analytic()->portfolio());
91 analytic()->reports()[LABEL]["pnl_npv_t0"] = t0NpvReport;
92
93 if (inputs_->outputAdditionalResults()) {
94 CONSOLEW("Pricing: Additional t0 Results");
95 boost::shared_ptr<InMemoryReport> t0AddReport = boost::make_shared<InMemoryReport>();
96 ReportWriter(inputs_->reportNaString())
97 .writeAdditionalResultsReport(*t0AddReport, analytic()->portfolio(), analytic()->market(),
98 effectiveResultCurrency);
99 analytic()->reports()[LABEL]["pnl_additional_results_t0"] = t0AddReport;
100 CONSOLE("OK");
101 }
102
103 /****************************************************
104 *
105 * 2. Write cash flow report for the clean actual P&L
106 *
107 ****************************************************/
108
109 boost::shared_ptr<InMemoryReport> t0CashFlowReport = boost::make_shared<InMemoryReport>();
110 string marketConfig = inputs_->marketConfig("pricing");
111 ReportWriter(inputs_->reportNaString())
112 .writeCashflow(*t0CashFlowReport, effectiveResultCurrency, analytic()->portfolio(),
113 analytic()->market(),
114 marketConfig, inputs_->includePastCashflows());
115 analytic()->reports()[LABEL]["pnl_cashflow"] = t0CashFlowReport;
116
117 /*******************************************************************************************
118 *
119 * 3. Prepare "NPV lagged" calculations by creating shift scenarios
120 * - to price the t0 portfolio as of t0 using the t1 market (risk hypothetical clean P&L)
121 * - to price the t0 portfolio as of t1 using the t0 market (theta, time decay)
122 *
123 *******************************************************************************************/
124
125 // Set eveluationDate to t1 > t0
126 Settings::instance().evaluationDate() = mporDate();
127
128 // Set the configurations asof date for the mpor analytic to t1, too
129 auto mporAnalytic = dependentAnalytic(mporLookupKey);
130 mporAnalytic->configurations().asofDate = mporDate();
131 mporAnalytic->configurations().todaysMarketParams = analytic()->configurations().todaysMarketParams;
132 mporAnalytic->configurations().simMarketParams = analytic()->configurations().simMarketParams;
133
134 // Run the mpor analytic to generate the market scenario as of t1
135 mporAnalytic->runAnalytic(loader);
136
137 // Set the evaluation date back to t0
138 Settings::instance().evaluationDate() = inputs_->asof();
139
140 QuantLib::ext::shared_ptr<Scenario> asofBaseScenario = simMarket->baseScenarioAbsolute();
141 auto sai = static_cast<ScenarioAnalyticImpl*>(mporAnalytic->impl().get());
142 QuantLib::ext::shared_ptr<Scenario> mporBaseScenario = sai->scenarioSimMarket()->baseScenarioAbsolute();
143
144 QuantLib::ext::shared_ptr<ore::analytics::Scenario> t0Scenario =
145 getDifferenceScenario(asofBaseScenario, mporBaseScenario, inputs_->asof(), 1.0);
146 setT0Scenario(asofBaseScenario);
147
148 // Create the inverse shift scenario as spread between t0 market and t1 market, to be applied to t1
149
150 QuantLib::ext::shared_ptr<ore::analytics::Scenario> t1Scenario =
151 getDifferenceScenario(mporBaseScenario, asofBaseScenario, mporDate(), 1.0);
152 setT1Scenario(mporBaseScenario);
153
154 /********************************************************************************************
155 *
156 * 4. Price the t0 portfolio as of t0 using the t1 market for the risk-hypothetical clean P&L
157 *
158 ********************************************************************************************/
159
160 // Now update simMarket on asof date t0, with the t0 shift scenario
161 sgen->setScenario(t0Scenario);
162 simMarket->update(simMarket->asofDate());
163 analytic()->setMarket(simMarket);
164
165 // Build the portfolio, linked to the shifted market
167
168 // This hook allows modifying the portfolio in derived classes before running the analytics below
170
171 QuantLib::ext::shared_ptr<InMemoryReport> t0NpvLaggedReport = QuantLib::ext::make_shared<InMemoryReport>();
172 ReportWriter(inputs_->reportNaString())
173 .writeNpv(*t0NpvLaggedReport, effectiveResultCurrency, analytic()->market(), inputs_->marketConfig("pricing"),
174 analytic()->portfolio());
175
176 if (inputs_->outputAdditionalResults()) {
177 CONSOLEW("Pricing: Additional Results, t0 lagged");
178 boost::shared_ptr<InMemoryReport> t0LaggedAddReport = boost::make_shared<InMemoryReport>();
179 ReportWriter(inputs_->reportNaString())
180 .writeAdditionalResultsReport(*t0LaggedAddReport, analytic()->portfolio(), analytic()->market(),
181 effectiveResultCurrency);
182 analytic()->reports()[LABEL]["pnl_additional_results_lagged_t0"] = t0LaggedAddReport;
183 CONSOLE("OK");
184 }
185 analytic()->reports()[LABEL]["pnl_npv_lagged_t0"] = t0NpvLaggedReport;
186
187 /***********************************************************************************************
188 *
189 * 5. Price the t0 portfolio as of t1 using the t0 market for the theta / time decay calculation
190 * Reusing the mpor analytic setup here which is as of t1 already.
191 *
192 ***********************************************************************************************/
193
194 Date d1 = mporDate();
195 Settings::instance().evaluationDate() = d1;
197 auto simMarket1 = sai->scenarioSimMarket();
198 auto sgen1 = QuantLib::ext::make_shared<StaticScenarioGenerator>();
199 analytic()->setMarket(simMarket1);
200 sgen1->setScenario(t1Scenario);
201 simMarket1->scenarioGenerator() = sgen1;
202 simMarket1->update(d1);
204
205 QuantLib::ext::shared_ptr<InMemoryReport> t1NpvLaggedReport = QuantLib::ext::make_shared<InMemoryReport>();
206 ReportWriter(inputs_->reportNaString())
207 .writeNpv(*t1NpvLaggedReport, effectiveResultCurrency, analytic()->market(), inputs_->marketConfig("pricing"),
208 analytic()->portfolio());
209
210 analytic()->reports()[LABEL]["pnl_npv_lagged_t1"] = t1NpvLaggedReport;
211
212 if (inputs_->outputAdditionalResults()) {
213 CONSOLEW("Pricing: Additional Results t1");
214 boost::shared_ptr<InMemoryReport> t1AddReport = boost::make_shared<InMemoryReport>();
215 ReportWriter(inputs_->reportNaString())
216 .writeAdditionalResultsReport(*t1AddReport, analytic()->portfolio(), analytic()->market(),
217 effectiveResultCurrency);
218 analytic()->reports()[LABEL]["pnl_additional_results_lagged_t1"] = t1AddReport;
219 CONSOLE("OK");
220 }
221
222 /***************************************************************************************
223 *
224 * 6. Price the t0 portfolio as of t1 using the t1 market for the actual P&L calculation
225 * TODO: This should use the t1 portfolio instead.
226 *
227 ***************************************************************************************/
228
229 sgen1->setScenario(sai->scenarioSimMarket()->baseScenario());
230 simMarket1->scenarioGenerator() = sgen1;
231 simMarket1->update(d1);
233
234 QuantLib::ext::shared_ptr<InMemoryReport> t1NpvReport = QuantLib::ext::make_shared<InMemoryReport>();
235 ReportWriter(inputs_->reportNaString())
236 .writeNpv(*t1NpvReport, effectiveResultCurrency, analytic()->market(), inputs_->marketConfig("pricing"),
237 analytic()->portfolio());
238
239 analytic()->reports()[LABEL]["pnl_npv_t1"] = t1NpvReport;
240
241 if (inputs_->outputAdditionalResults()) {
242 CONSOLEW("Pricing: Additional t1 Results");
243 boost::shared_ptr<InMemoryReport> t1AddReport = boost::make_shared<InMemoryReport>();
244 ReportWriter(inputs_->reportNaString())
245 .writeAdditionalResultsReport(*t1AddReport, analytic()->portfolio(), analytic()->market(),
246 effectiveResultCurrency);
247 analytic()->reports()[LABEL]["pnl_additional_results_t1"] = t1AddReport;
248 CONSOLE("OK");
249 }
250
251 /****************************
252 *
253 * 7. Generate the P&L report
254 *
255 ****************************/
256
257 // FIXME: check which market and which portfolio to pass to the report writer
258 QuantLib::ext::shared_ptr<InMemoryReport> pnlReport = QuantLib::ext::make_shared<InMemoryReport>();
259 ReportWriter(inputs_->reportNaString())
260 .writePnlReport(*pnlReport, t0NpvReport, t0NpvLaggedReport, t1NpvLaggedReport, t1NpvReport,
261 t0CashFlowReport, inputs_->asof(), mporDate(),
262 effectiveResultCurrency, analytic()->market(), inputs_->marketConfig("pricing"), analytic()->portfolio());
263 analytic()->reports()[LABEL]["pnl"] = pnlReport;
264
265 /***************************
266 *
267 * 8. Write Scenario Reports
268 *
269 ***************************/
270
271 boost::shared_ptr<InMemoryReport> t0ScenarioReport = boost::make_shared<InMemoryReport>();
272 auto t0sw = ScenarioWriter(nullptr, t0ScenarioReport);
273 t0sw.writeScenario(asofBaseScenario, true);
274 analytic()->reports()[label()]["pnl_scenario_t0"] = t0ScenarioReport;
275
276 boost::shared_ptr<InMemoryReport> t1ScenarioReport = boost::make_shared<InMemoryReport>();
277 auto t1sw = ScenarioWriter(nullptr, t1ScenarioReport);
278 t1sw.writeScenario(mporBaseScenario, true);
279 analytic()->reports()[label()]["pnl_scenario_t1"] = t1ScenarioReport;
280}
Analytic * analytic() const
Definition: analytic.hpp:193
const std::string & label() const
Definition: analytic.hpp:190
QuantLib::ext::shared_ptr< T > dependentAnalytic(const std::string &key) const
Definition: analytic.hpp:251
analytic_reports & reports()
Result reports.
Definition: analytic.hpp:131
Configurations & configurations()
Definition: analytic.hpp:128
virtual void modifyPortfolio()
Definition: analytic.hpp:110
virtual void buildMarket(const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &loader, const bool marketRequired=true)
Definition: analytic.cpp:178
void setMarket(const QuantLib::ext::shared_ptr< ore::data::Market > &market)
Definition: analytic.hpp:124
virtual void buildPortfolio()
Definition: analytic.cpp:222
const QuantLib::ext::shared_ptr< ore::analytics::Scenario > & t1Scenario() const
Definition: pnlanalytic.hpp:62
void setT1Scenario(const QuantLib::ext::shared_ptr< ore::analytics::Scenario > &scenario)
Definition: pnlanalytic.hpp:64
void setT0Scenario(const QuantLib::ext::shared_ptr< ore::analytics::Scenario > &scenario)
Definition: pnlanalytic.hpp:63
const QuantLib::Date & mporDate() const
Definition: pnlanalytic.hpp:58
const QuantLib::ext::shared_ptr< ore::analytics::Scenario > & t0Scenario() const
Definition: pnlanalytic.hpp:61
#define CONSOLEW(text)
#define CONSOLE(text)
Real getDifferenceScenario(const RiskFactorKey::KeyType keyType, const Real v1, const Real v2)
QuantLib::ext::shared_ptr< ore::data::TodaysMarketParameters > todaysMarketParams
Definition: analytic.hpp:68
QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarketParameters > simMarketParams
Definition: analytic.hpp:69
+ Here is the call graph for this function:

◆ setUpConfigurations()

void setUpConfigurations ( )
overridevirtual

Reimplemented from Analytic::Impl.

Definition at line 34 of file pnlanalytic.cpp.

34 {
36
37 analytic()->configurations().todaysMarketParams = inputs_->todaysMarketParams();
38 analytic()->configurations().simMarketParams = inputs_->scenarioSimMarketParams();
39
41}
void setGenerateAdditionalResults(const bool generateAdditionalResults)
Definition: analytic.hpp:197
bool simulationConfigRequired
Booleans to determine if these configs are needed.
Definition: analytic.hpp:64
+ Here is the call graph for this function:

◆ useSpreadedTermStructures()

bool useSpreadedTermStructures ( ) const

Definition at line 57 of file pnlanalytic.hpp.

+ Here is the caller graph for this function:

◆ mporDate()

const QuantLib::Date & mporDate ( ) const

Definition at line 58 of file pnlanalytic.hpp.

58{ return mporDate_; }
+ Here is the caller graph for this function:

◆ additionalMarketDates()

std::vector< QuantLib::Date > additionalMarketDates ( ) const
overridevirtual

Reimplemented from Analytic::Impl.

Definition at line 59 of file pnlanalytic.hpp.

59{ return {mporDate_}; }

◆ t0Scenario()

const QuantLib::ext::shared_ptr< ore::analytics::Scenario > & t0Scenario ( ) const

Definition at line 61 of file pnlanalytic.hpp.

61{ return t0Scenario_; }
QuantLib::ext::shared_ptr< ore::analytics::Scenario > t0Scenario_
Definition: pnlanalytic.hpp:69
+ Here is the caller graph for this function:

◆ t1Scenario()

const QuantLib::ext::shared_ptr< ore::analytics::Scenario > & t1Scenario ( ) const

Definition at line 62 of file pnlanalytic.hpp.

62{ return t1Scenario_; }
QuantLib::ext::shared_ptr< ore::analytics::Scenario > t1Scenario_
Definition: pnlanalytic.hpp:69
+ Here is the caller graph for this function:

◆ setT0Scenario()

void setT0Scenario ( const QuantLib::ext::shared_ptr< ore::analytics::Scenario > &  scenario)

Definition at line 63 of file pnlanalytic.hpp.

63{ t0Scenario_ = scenario; }
+ Here is the caller graph for this function:

◆ setT1Scenario()

void setT1Scenario ( const QuantLib::ext::shared_ptr< ore::analytics::Scenario > &  scenario)

Definition at line 64 of file pnlanalytic.hpp.

64{ t1Scenario_ = scenario; }
+ Here is the caller graph for this function:

Member Data Documentation

◆ LABEL

constexpr const char* LABEL = "PNL"
staticconstexpr

Definition at line 34 of file pnlanalytic.hpp.

◆ mporLookupKey

constexpr const char* mporLookupKey = "MPOR"
staticconstexpr

Definition at line 35 of file pnlanalytic.hpp.

◆ useSpreadedTermStructures_

bool useSpreadedTermStructures_ = true
private

Definition at line 67 of file pnlanalytic.hpp.

◆ mporDate_

QuantLib::Date mporDate_
private

Definition at line 68 of file pnlanalytic.hpp.

◆ t0Scenario_

QuantLib::ext::shared_ptr<ore::analytics::Scenario> t0Scenario_
private

Definition at line 69 of file pnlanalytic.hpp.

◆ t1Scenario_

QuantLib::ext::shared_ptr<ore::analytics::Scenario> t1Scenario_
private

Definition at line 69 of file pnlanalytic.hpp.