Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
analytic.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2022 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
19#include <orea/app/analytic.hpp>
31
40
41#include <boost/timer/timer.hpp>
42
43#include <iostream>
44
45using namespace ore::data;
46using namespace boost::filesystem;
47using boost::timer::cpu_timer;
48using boost::timer::default_places;
49
50namespace ore {
51namespace analytics {
52
53Analytic::Analytic(std::unique_ptr<Impl> impl,
54 const std::set<std::string>& analyticTypes,
55 const QuantLib::ext::shared_ptr<InputParameters>& inputs,
56 bool simulationConfig,
57 bool sensitivityConfig,
58 bool scenarioGeneratorConfig,
59 bool crossAssetModelConfig)
60 : impl_(std::move(impl)), types_(analyticTypes), inputs_(inputs) {
61
62 configurations().asofDate = inputs->asof();
63
64 // set these here, can be overwritten in setUpConfigurations
65 if (inputs->curveConfigs().has())
66 configurations().curveConfig = inputs->curveConfigs().get();
67 if (inputs->pricingEngine())
68 configurations().engineData = inputs->pricingEngine();
69
70 configurations().simulationConfigRequired = simulationConfig;
71 configurations().sensitivityConfigRequired = sensitivityConfig;
72 configurations().scenarioGeneratorConfigRequired = scenarioGeneratorConfig;
73 configurations().crossAssetModelConfigRequired = crossAssetModelConfig;
74
75 if (impl_) {
76 impl_->setAnalytic(this);
77 impl_->setGenerateAdditionalResults(inputs_->outputAdditionalResults());
78 }
79
81}
82
83void Analytic::runAnalytic(const QuantLib::ext::shared_ptr<ore::data::InMemoryLoader>& loader,
84 const std::set<std::string>& runTypes) {
86 if (impl_) {
87 impl_->runAnalytic(loader, runTypes);
89 }
90}
91
93 if (impl_)
94 impl_->setUpConfigurations();
95}
96
97std::vector<QuantLib::ext::shared_ptr<Analytic>> Analytic::Impl::allDependentAnalytics() const {
98 std::vector<QuantLib::ext::shared_ptr<Analytic>> analytics;
99 for (const auto& [_, a] : dependentAnalytics_) {
100 analytics.push_back(a);
101 auto das = a->allDependentAnalytics();
102 analytics.insert(end(analytics), begin(das), end(das));
103 }
104 return analytics;
105}
106
107QuantLib::ext::shared_ptr<Analytic> Analytic::Impl::dependentAnalytic(const std::string& key) const {
108 auto it = dependentAnalytics_.find(key);
109 QL_REQUIRE(it != dependentAnalytics_.end(), "Could not find dependent Analytic " << key);
110 return it->second;
111}
112
113const std::string Analytic::label() const {
114 return impl_ ? impl_->label() : string();
115}
116
117// Analytic
118bool Analytic::match(const std::set<std::string>& runTypes) {
119 if (runTypes.size() == 0)
120 return true;
121
122 for (const auto& rt : runTypes) {
123 if (types_.find(rt) != types_.end()) {
124 LOG("Requested analytics " << to_string(runTypes) << " match analytic class " << label());
125 return true;
126 }
127 }
128 return false;
129}
130
131std::vector<QuantLib::ext::shared_ptr<Analytic>> Analytic::allDependentAnalytics() const {
132 return impl_->allDependentAnalytics();
133}
134
135std::set<QuantLib::Date> Analytic::marketDates() const {
136 std::set<QuantLib::Date> mds = {inputs_->asof()};
137 auto addDates = impl_->additionalMarketDates();
138 mds.insert(addDates.begin(), addDates.end());
139
140 for (const auto& a : impl_->dependentAnalytics()) {
141 addDates = a.second->impl()->additionalMarketDates();
142 mds.insert(addDates.begin(), addDates.end());
143 }
144 return mds;
145}
146
147std::vector<QuantLib::ext::shared_ptr<ore::data::TodaysMarketParameters>> Analytic::todaysMarketParams() {
149 std::vector<QuantLib::ext::shared_ptr<ore::data::TodaysMarketParameters>> tmps;
151 tmps.push_back(configurations().todaysMarketParams);
152
153 for (const auto& a : impl_->dependentAnalytics()) {
154 auto ctmps = a.second->todaysMarketParams();
155 tmps.insert(end(tmps), begin(ctmps), end(ctmps));
156 }
157
158 return tmps;
159}
160
161QuantLib::ext::shared_ptr<EngineFactory> Analytic::Impl::engineFactory() {
162 LOG("Analytic::engineFactory() called");
163 // Note: Calling the constructor here with empty extry builders
164 // Override this function in case you have got extra ones
165 QuantLib::ext::shared_ptr<EngineData> edCopy = QuantLib::ext::make_shared<EngineData>(*inputs_->pricingEngine());
166 edCopy->globalParameters()["GenerateAdditionalResults"] = to_string(generateAdditionalResults());
167 edCopy->globalParameters()["RunType"] = "NPV";
168 map<MarketContext, string> configurations;
169 configurations[MarketContext::irCalibration] = inputs_->marketConfig("lgmcalibration");
170 configurations[MarketContext::fxCalibration] = inputs_->marketConfig("fxcalibration");
171 configurations[MarketContext::pricing] = inputs_->marketConfig("pricing");
172 LOG("MarketContext::pricing = " << inputs_->marketConfig("pricing"));
173 return QuantLib::ext::make_shared<EngineFactory>(edCopy, analytic()->market(), configurations,
174 inputs_->refDataManager(),
175 *inputs_->iborFallbackConfig());
176}
177
178void Analytic::buildMarket(const QuantLib::ext::shared_ptr<ore::data::InMemoryLoader>& loader,
179 const bool marketRequired) {
180 LOG("Analytic::buildMarket called");
181 cpu_timer mtimer;
182
183 QL_REQUIRE(loader, "market data loader not set");
184 QL_REQUIRE(configurations().curveConfig, "curve configurations not set");
185
186 // first build the market if we have a todaysMarketParams
188 try {
189 // imply bond spreads (no exclusion of securities in ore, just in ore+) and add results to loader
191 loader, configurations_.curveConfig, std::string());
192
193 // Join the loaders
194 loader_ = QuantLib::ext::make_shared<CompositeLoader>(loader, bondSpreads);
195
196 // Check that the loader has quotes
197 QL_REQUIRE(loader_->hasQuotes(configurations().asofDate),
198 "There are no quotes available for date " << configurations().asofDate);
199 // Build the market
200 market_ = QuantLib::ext::make_shared<TodaysMarket>(
202 inputs()->continueOnError(), true, inputs()->lazyMarketBuilding(), inputs()->refDataManager(), false,
203 *inputs()->iborFallbackConfig());
204 } catch (const std::exception& e) {
205 if (marketRequired)
206 QL_FAIL("Failed to build market: " << e.what());
207 else
208 WLOG("Failed to build market: " << e.what());
209 }
210 } else {
211 ALOG("Skip building the market due to missing today's market parameters in configurations");
212 }
213 mtimer.stop();
214 LOG("Market Build time " << setprecision(2) << mtimer.format(default_places, "%w") << " sec");
215}
216
217void Analytic::marketCalibration(const QuantLib::ext::shared_ptr<MarketCalibrationReportBase>& mcr) {
218 if (mcr)
219 mcr->populateReport(market_, configurations().todaysMarketParams);
220}
221
223 QuantLib::ext::shared_ptr<Portfolio> tmp = portfolio_ ? portfolio_ : inputs()->portfolio();
224
225 // create a new empty portfolio
226 portfolio_ = QuantLib::ext::make_shared<Portfolio>(inputs()->buildFailedTrades());
227
228 tmp->reset();
229 // populate with trades
230 for (const auto& [tradeId, trade] : tmp->trades())
231 // If portfolio was already provided to the analytic, make sure to only process those given trades.
232 portfolio()->add(trade);
233
234 if (market_) {
236
237 LOG("Build the portfolio");
238 QuantLib::ext::shared_ptr<EngineFactory> factory = impl()->engineFactory();
239 portfolio()->build(factory, "analytic/" + label());
240
241 // remove dates that will have matured
242 Date maturityDate = inputs()->asof();
243 if (inputs()->portfolioFilterDate() != Null<Date>())
244 maturityDate = inputs()->portfolioFilterDate();
245
246 LOG("Filter trades that expire before " << maturityDate);
247 portfolio()->removeMatured(maturityDate);
248 } else {
249 ALOG("Skip building the portfolio, because market not set");
250 }
251}
252
253/*******************************************************************
254 * MARKET Analytic
255 *******************************************************************/
256
258 analytic()->configurations().todaysMarketParams = inputs_->todaysMarketParams();
259}
260
262 const QuantLib::ext::shared_ptr<ore::data::InMemoryLoader>& loader,
263 const std::set<std::string>& runTypes) {
264
265 Settings::instance().evaluationDate() = inputs_->asof();
266 ObservationMode::instance().setMode(inputs_->observationModel());
267
268 CONSOLEW("Build Market");
269 analytic()->buildMarket(loader);
270 CONSOLE("OK");
271}
272
273QuantLib::ext::shared_ptr<Loader> implyBondSpreads(const Date& asof,
274 const QuantLib::ext::shared_ptr<ore::analytics::InputParameters>& params,
275 const QuantLib::ext::shared_ptr<TodaysMarketParameters>& todaysMarketParams,
276 const QuantLib::ext::shared_ptr<Loader>& loader,
277 const QuantLib::ext::shared_ptr<CurveConfigurations>& curveConfigs,
278 const std::string& excludeRegex) {
279
281 true, excludeRegex);
282
283 if (!securities.empty()) {
284 // always continue on error and always use lazy market building
285 QuantLib::ext::shared_ptr<Market> market =
286 QuantLib::ext::make_shared<TodaysMarket>(asof, todaysMarketParams, loader, curveConfigs, true, true, true,
287 params->refDataManager(), false, *params->iborFallbackConfig());
288 return BondSpreadImply::implyBondSpreads(securities, params->refDataManager(), market, params->pricingEngine(),
289 Market::defaultConfiguration, *params->iborFallbackConfig());
290 } else {
291 // no bonds that require a spread imply => return null ptr
292 return QuantLib::ext::shared_ptr<Loader>();
293 }
294}
295
296} // namespace analytics
297} // namespace ore
ORE Analytics Manager.
a wrapper to buffer sensi stream records
std::map< std::string, QuantLib::ext::shared_ptr< Analytic > > dependentAnalytics_
Definition: analytic.hpp:221
QuantLib::ext::shared_ptr< T > dependentAnalytic(const std::string &key) const
Definition: analytic.hpp:251
std::vector< QuantLib::ext::shared_ptr< Analytic > > allDependentAnalytics() const
Definition: analytic.cpp:97
virtual QuantLib::ext::shared_ptr< ore::data::EngineFactory > engineFactory()
build an engine factory
Definition: analytic.cpp:161
std::set< QuantLib::Date > marketDates() const
Definition: analytic.cpp:135
Configurations & configurations()
Definition: analytic.hpp:128
virtual void marketCalibration(const QuantLib::ext::shared_ptr< MarketCalibrationReportBase > &mcr=nullptr)
Definition: analytic.cpp:217
virtual void buildMarket(const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &loader, const bool marketRequired=true)
Definition: analytic.cpp:178
virtual void runAnalytic(const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &loader, const std::set< std::string > &runTypes={})
Run only those analytic types that are inclcuded in the runTypes vector, run all if the runType vecto...
Definition: analytic.cpp:83
const std::unique_ptr< Impl > & impl()
Definition: analytic.hpp:142
const std::string label() const
Inspectors.
Definition: analytic.cpp:113
const QuantLib::ext::shared_ptr< InputParameters > & inputs() const
Definition: analytic.hpp:116
std::unique_ptr< Impl > impl_
Definition: analytic.hpp:151
std::set< std::string > types_
list of analytic types run by this analytic
Definition: analytic.hpp:154
QuantLib::ext::shared_ptr< ore::data::Portfolio > portfolio_
Definition: analytic.hpp:161
const QuantLib::ext::shared_ptr< ore::data::Portfolio > & portfolio() const
Definition: analytic.hpp:122
Analytic()
Constructors.
Definition: analytic.hpp:79
virtual void setUpConfigurations()
Definition: analytic.cpp:92
QuantLib::ext::shared_ptr< ore::data::Market > market_
Definition: analytic.hpp:159
const QuantLib::ext::shared_ptr< ore::data::Loader > & loader() const
Definition: analytic.hpp:127
virtual void replaceTrades()
Definition: analytic.hpp:111
const QuantLib::ext::shared_ptr< ore::data::Market > & market() const
Definition: analytic.hpp:117
std::vector< QuantLib::ext::shared_ptr< Analytic > > allDependentAnalytics() const
Definition: analytic.cpp:131
Configurations configurations_
Definition: analytic.hpp:158
std::vector< QuantLib::ext::shared_ptr< ore::data::TodaysMarketParameters > > todaysMarketParams()
Definition: analytic.cpp:147
QuantLib::ext::shared_ptr< ore::data::Loader > loader_
Definition: analytic.hpp:160
QuantLib::ext::shared_ptr< InputParameters > inputs_
contains all the input parameters for the run
Definition: analytic.hpp:156
bool match(const std::set< std::string > &runTypes)
Check whether any of the requested run types is covered by this analytic.
Definition: analytic.cpp:118
virtual void buildPortfolio()
Definition: analytic.cpp:222
virtual void buildConfigurations(const bool=false)
Definition: analytic.hpp:103
void runAnalytic(const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &loader, const std::set< std::string > &runTypes={}) override
Definition: analytic.cpp:261
static QuantLib::ext::shared_ptr< Loader > implyBondSpreads(const std::map< std::string, QuantLib::ext::shared_ptr< Security > > &securities, const QuantLib::ext::shared_ptr< ReferenceDataManager > &referenceDataManager, const QuantLib::ext::shared_ptr< Market > &market, const QuantLib::ext::shared_ptr< EngineData > &engineData, const std::string &configuration, const IborFallbackConfig &iborFallbackConfig)
static std::map< std::string, QuantLib::ext::shared_ptr< Security > > requiredSecurities(const Date &asof, const QuantLib::ext::shared_ptr< TodaysMarketParameters > &params, const QuantLib::ext::shared_ptr< CurveConfigurations > &curveConfigs, const Loader &loader, const bool continueOnError=false, const std::string &excludeRegex=std::string())
static const string defaultConfiguration
A Class to write a cube out to file.
Dynamic Initial Margin calculator by regression.
Class that wraps a sensitivity stream and filters out negligible records.
#define LOG(text)
#define ALOG(text)
#define MEM_LOG_USING_LEVEL(LEVEL)
#define CONSOLEW(text)
#define WLOG(text)
#define CONSOLE(text)
#define ORE_WARNING
QuantLib::ext::shared_ptr< Loader > implyBondSpreads(const Date &asof, const QuantLib::ext::shared_ptr< ore::analytics::InputParameters > &params, const QuantLib::ext::shared_ptr< TodaysMarketParameters > &todaysMarketParams, const QuantLib::ext::shared_ptr< Loader > &loader, const QuantLib::ext::shared_ptr< CurveConfigurations > &curveConfigs, const std::string &excludeRegex)
Definition: analytic.cpp:273
std::string to_string(const LocationInfo &l)
Singleton class to hold global Observation Mode.
A Class to write ORE outputs to reports.
ScenarioWriter class.
factory classes for simple scenarios
QuantLib::ext::shared_ptr< ore::data::EngineData > engineData
Definition: analytic.hpp:74
QuantLib::ext::shared_ptr< CurveConfigurations > curveConfig
Definition: analytic.hpp:73
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
Class for structured analytics warnings.
vector< string > curveConfigs
Date asof(14, Jun, 2018)
The cube valuation core.
Class for converting zero sensitivities to par sensitivities.