Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
xvaenginecg.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2023 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
20#include <orea/cube/npvcube.hpp>
27
31
35#include <qle/ad/ssaform.hpp>
37
38#include <boost/accumulators/accumulators.hpp>
39#include <boost/accumulators/statistics/stats.hpp>
40#include <boost/accumulators/statistics/weighted_sum.hpp>
41#include <boost/timer/timer.hpp>
42
43namespace ore {
44namespace analytics {
45
46namespace {
47std::size_t numberOfStochasticRvs(const std::vector<RandomVariable>& v) {
48 return std::count_if(v.begin(), v.end(),
49 [](const RandomVariable& r) { return r.initialised() && !r.deterministic(); });
50}
51} // namespace
52
53XvaEngineCG::XvaEngineCG(const Size nThreads, const Date& asof, const QuantLib::ext::shared_ptr<ore::data::Loader>& loader,
54 const QuantLib::ext::shared_ptr<ore::data::CurveConfigurations>& curveConfigs,
55 const QuantLib::ext::shared_ptr<ore::data::TodaysMarketParameters>& todaysMarketParams,
56 const QuantLib::ext::shared_ptr<ore::analytics::ScenarioSimMarketParameters>& simMarketData,
57 const QuantLib::ext::shared_ptr<ore::data::EngineData>& engineData,
58 const QuantLib::ext::shared_ptr<ore::analytics::CrossAssetModelData>& crossAssetModelData,
59 const QuantLib::ext::shared_ptr<ore::analytics::ScenarioGeneratorData>& scenarioGeneratorData,
60 const QuantLib::ext::shared_ptr<ore::data::Portfolio>& portfolio, const string& marketConfiguration,
61 const string& marketConfigurationInCcy,
62 const QuantLib::ext::shared_ptr<ore::analytics::SensitivityScenarioData>& sensitivityData,
63 const QuantLib::ext::shared_ptr<ReferenceDataManager>& referenceData,
64 const IborFallbackConfig& iborFallbackConfig,
65 const bool bumpCvaSensis, const bool continueOnCalibrationError,
66 const bool continueOnError, const std::string& context)
67 : asof_(asof), loader_(loader), curveConfigs_(curveConfigs),
68 todaysMarketParams_(todaysMarketParams), simMarketData_(simMarketData), engineData_(engineData),
69 crossAssetModelData_(crossAssetModelData), scenarioGeneratorData_(scenarioGeneratorData), portfolio_(portfolio),
70 marketConfiguration_(marketConfiguration), marketConfigurationInCcy_(marketConfigurationInCcy),
71 sensitivityData_(sensitivityData), referenceData_(referenceData), iborFallbackConfig_(iborFallbackConfig),
72 bumpCvaSensis_(bumpCvaSensis), continueOnCalibrationError_(continueOnCalibrationError), continueOnError_(continueOnError), context_(context) {
73
74 // Just for performance testing, duplicate the trades in input portfolio as specified by env var N
75
76 // portfolio_ = QuantLib::ext::make_shared<Portfolio>();
77 // std::string pfxml = portfolio->toXMLString();
78 // for (Size i = 0; i < atoi(getenv("N")); ++i) {
79 // auto p = QuantLib::ext::make_shared<Portfolio>();
80 // p->fromXMLString(pfxml);
81 // for (auto const& [id, t] : p->trades()) {
82 // t->id() += "_" + std::to_string(i + 1);
83 // portfolio_->add(t);
84 // }
85 // }
86
87 // Start Engine
88
89 LOG("XvaEngineCG: started");
90 boost::timer::cpu_timer timer;
91
92 // Build T0 market
93
94 LOG("XvaEngineCG: build init market");
95
96 initMarket_ = QuantLib::ext::make_shared<ore::data::TodaysMarket>(asof_, todaysMarketParams_, loader_, curveConfigs_,
97 continueOnError_, true, true, referenceData_, false,
98 iborFallbackConfig_, false, true);
99
100 boost::timer::nanosecond_type timing1 = timer.elapsed().wall;
101
102 // Build sim market
103
104 LOG("XvaEngineCG: build sim market");
105
106 // note: take "use spreaded term structures" from sensitivity config instead of hardcoding to true here?
107 simMarket_ = QuantLib::ext::make_shared<ore::analytics::ScenarioSimMarket>(
109 false, false, iborFallbackConfig_, true);
110
111 boost::timer::nanosecond_type timing2 = timer.elapsed().wall;
112
113 // Set up cam builder against sim market
114
115 LOG("XvaEngineCG: build cam model builder");
116
117 // note: sim market has one config only, no in-ccy config to calibrate IR components
118 camBuilder_ = QuantLib::ext::make_shared<CrossAssetModelBuilder>(
121 std::string(), SalvagingAlgorithm::Spectral, "xva engine cg - cam builder");
122
123 // Set up gaussian cam cg model
124
125 LOG("XvaEngineCG: build cam cg model");
126
127 QL_REQUIRE(
128 crossAssetModelData_->discretization() == CrossAssetModel::Discretization::Euler,
129 "XvaEngineCG: cam is required to use discretization 'Euler', please update simulation parameters accordingly.");
130
131 std::vector<std::string> currencies; // from cam
132 std::vector<Handle<YieldTermStructure>> curves; // from cam
133 std::vector<Handle<Quote>> fxSpots; // from cam
134 std::vector<std::pair<std::string, QuantLib::ext::shared_ptr<InterestRateIndex>>> irIndices; // from trade building
135 std::vector<std::pair<std::string, QuantLib::ext::shared_ptr<ZeroInflationIndex>>> infIndices; // from trade building
136 std::vector<std::string> indices; // from trade building
137 std::vector<std::string> indexCurrencies; // from trade building
138
139 // note: for the PoC we populate the containers with hardcoded values ... temp hack ...
140 currencies.push_back("EUR");
141 curves.push_back(camBuilder_->model()->irModel(0)->termStructure());
142 irIndices.push_back(std::make_pair("EUR-EURIBOR-6M", *simMarket_->iborIndex("EUR-EURIBOR-6M")));
143
144 // note: these must be fine enough for Euler, e.g. weekly over the whole simulation period
145 std::set<Date> simulationDates(scenarioGeneratorData_->getGrid()->dates().begin(),
146 scenarioGeneratorData_->getGrid()->dates().end());
147 // note: this should be added to CrossAssetModelData
148 Size timeStepsPerYear = 1;
149
150 // note: projectedStateProcessIndices can be removed from GaussianCamCG constructor most probably?
151 model_ = QuantLib::ext::make_shared<GaussianCamCG>(camBuilder_->model(), scenarioGeneratorData_->samples(), currencies,
152 curves, fxSpots, irIndices, infIndices, indices, indexCurrencies,
153 simulationDates, timeStepsPerYear, iborFallbackConfig,
154 std::vector<Size>(), std::vector<std::string>(), true);
155 model_->calculate();
156 boost::timer::nanosecond_type timing3 = timer.elapsed().wall;
157
158 // Build trades against global cg cam model
159
160 LOG("XvaEngineCG: build trades against global cam cg model");
161
162 auto edCopy = QuantLib::ext::make_shared<EngineData>(*engineData_);
163 edCopy->globalParameters()["GenerateAdditionalResults"] = "false";
164 edCopy->globalParameters()["RunType"] = "NPV";
165 map<MarketContext, string> configurations;
166 configurations[MarketContext::irCalibration] = marketConfigurationInCcy_;
167 configurations[MarketContext::fxCalibration] = marketConfiguration_;
168 configurations[MarketContext::pricing] = marketConfiguration_;
169 auto factory =
170 QuantLib::ext::make_shared<EngineFactory>(edCopy, simMarket_, configurations, referenceData_, iborFallbackConfig_,
171 EngineBuilderFactory::instance().generateAmcCgEngineBuilders(
172 model_, scenarioGeneratorData_->getGrid()->dates()),
173 true);
174
175 portfolio_->build(factory, "xva engine cg", true);
176
177 boost::timer::nanosecond_type timing4 = timer.elapsed().wall;
178
179 // Build computation graph for all trades ("part B") and
180 // - store npv, amc npv nodes
181
182 LOG("XvaEngineCG: build computation graph for all trades");
183
184 std::vector<std::vector<std::size_t>> amcNpvNodes; // includes time zero npv
185
186 auto g = model_->computationGraph();
187
188 for (auto const& [id, trade] : portfolio_->trades()) {
189 auto qlInstr = QuantLib::ext::dynamic_pointer_cast<ScriptedInstrument>(trade->instrument()->qlInstrument());
190 QL_REQUIRE(qlInstr, "XvaEngineCG: expeced trade to provide ScriptedInstrument, trade '" << id << "' does not.");
191 auto engine = QuantLib::ext::dynamic_pointer_cast<ScriptedInstrumentPricingEngineCG>(qlInstr->pricingEngine());
192 QL_REQUIRE(engine, "XvaEngineCG: expected to get ScriptedInstrumentPricingEngineCG, trade '"
193 << id << "' has a different engine.");
194 g->startRedBlock();
195 engine->buildComputationGraph();
196 std::vector<std::size_t> tmp;
197 tmp.push_back(cg_add(*g, cg_const(*g, 0.0), g->variable(engine->npvName() + "_0")));
198 for (std::size_t i = 0; i < simulationDates.size(); ++i) {
199 tmp.push_back(cg_add(*g, cg_const(*g, 0.0), g->variable("_AMC_NPV_" + std::to_string(i))));
200 }
201 amcNpvNodes.push_back(tmp);
202 g->endRedBlock();
203 }
204
205 boost::timer::nanosecond_type timing5 = timer.elapsed().wall;
206
207 // Add nodes that sum the exposure over trades, both pathwise and conditional expectations
208 // This constitutes part C of the computation graph spanning "trade m range end ... lastExposureNode"
209 // - pfPathExposureNodes: path amc sim values, aggregated over trades
210 // - pfExposureNodes: the corresponding conditional expectations
211
212 std::vector<std::size_t> pfPathExposureNodes, pfExposureNodes;
213 for (Size i = 0; i < simulationDates.size() + 1; ++i) {
214 std::size_t sumNode = cg_const(*g, 0.0);
215 for (auto const& v : amcNpvNodes) {
216 sumNode = cg_add(*g, sumNode, v[i]);
217 }
218 pfPathExposureNodes.push_back(sumNode);
219 pfExposureNodes.push_back(
220 model_->npv(sumNode, i == 0 ? model_->referenceDate() : *std::next(simulationDates.begin(), i - 1),
221 cg_const(*g, 1.0), boost::none, ComputationGraph::nan, ComputationGraph::nan));
222 }
223
224 boost::timer::nanosecond_type timing6 = timer.elapsed().wall;
225
226 // Add post processor
227 // This constitues part D of the computation graph from lastExposureNode ... g->size()
228 // The cvaNode is the ultimate result w.r.t. which we want to compute sensitivities
229
230 // note: very simplified calculation, for testing, just multiply the EPE on each date by fixed default prob
231 auto defaultCurve = simMarket_->defaultCurve("BANK")->curve();
232 model_->registerWith(defaultCurve);
233 Size cvaNode = cg_const(*g, 0.0);
234 for (Size i = 0; i < simulationDates.size(); ++i) {
235 Date d = i == 0 ? model_->referenceDate() : *std::next(simulationDates.begin(), i - 1);
236 Date e = *std::next(simulationDates.begin(), i);
237 std::size_t defaultProb =
238 addModelParameter(*g, model_->modelParameterFunctors(), "__defaultprob_" + std::to_string(i),
239 [defaultCurve, d, e]() { return defaultCurve->defaultProbability(d, e); });
240 cvaNode = cg_add(*g, cvaNode, cg_mult(*g, defaultProb, cg_max(*g, pfExposureNodes[i], cg_const(*g, 0.0))));
241 }
242
243 boost::timer::nanosecond_type timing7 = timer.elapsed().wall;
244
245 LOG("XvaEngineCG: graph building complete, size is " << g->size());
246 LOG("XvaEngineCG: got " << g->redBlockDependencies().size() << " red block dependencies.");
247 std::size_t sumRedNodes = 0;
248 for (auto const& r : g->redBlockRanges()) {
249 DLOG("XvaEngineCG: red block range " << r.first << " ... " << r.second);
250 sumRedNodes += r.second - r.first;
251 }
252
253 // Create values and derivatives containers
254
255 std::vector<RandomVariable> values(g->size(), RandomVariable(model_->size(), 0.0));
256 std::vector<RandomVariable> derivatives(g->size(), RandomVariable(model_->size(), 0.0));
257
258 // Populate random variates
259
261 boost::timer::nanosecond_type timing8 = timer.elapsed().wall;
262
263 // Populate constants and model parameters
264
265 baseModelParams_ = model_->modelParameters();
266 populateConstants(values);
268 boost::timer::nanosecond_type timing9 = timer.elapsed().wall;
269
270 std::size_t rvMemMax = numberOfStochasticRvs(values) + numberOfStochasticRvs(derivatives);
271
272 // Do a forward evaluation, keep the following values nodes
273 // - constants
274 // - model parameters
275 // - values needed for derivatives (except in red blocks, by their definition)
276 // - red block dependencies
277 // - the random variates for bump sensis
278 // - the pfExposureNodes to dump out the epe profile
279
280 LOG("XvaEngineCG: do forward evaluation");
281
282 Real eps = 0.0; // smoothing parameter for indicator functions
283 ops_ = getRandomVariableOps(model_->size(), 4, QuantLib::LsmBasisSystem::Monomial, bumpCvaSensis_ ? eps : 0.0,
284 Null<Real>()); // todo set regression variance cutoff
285 grads_ = getRandomVariableGradients(model_->size(), 4, QuantLib::LsmBasisSystem::Monomial, eps);
287
288 std::vector<bool> keepNodes(g->size(), false);
289
290 for (auto const& c : g->constants()) {
291 keepNodes[c.second] = true;
292 }
293
294 for (auto const& [n, v] : baseModelParams_) {
295 keepNodes[n] = true;
296 }
297
298 for (auto const n : g->redBlockDependencies()) {
299 keepNodes[n] = true;
300 }
301
302 if (bumpCvaSensis_) {
303 for (auto const& rv : model_->randomVariates())
304 for (auto const& v : rv)
305 keepNodes[v] = true;
306 }
307
308 for (auto const& n : pfExposureNodes) {
309 keepNodes[n] = true;
310 }
311
313
314 boost::timer::nanosecond_type timing10 = timer.elapsed().wall;
315
316 // Write epe / ene profile out
317
318 {
319 epeReport_ = QuantLib::ext::make_shared<InMemoryReport>();
320 epeReport_->addColumn("Date", Date()).addColumn("EPE", double(), 4).addColumn("ENE", double(), 4);
321
322 for (Size i = 0; i < simulationDates.size() + 1; ++i) {
323 epeReport_->next();
324 epeReport_->add(i == 0 ? model_->referenceDate() : *std::next(simulationDates.begin(), i - 1))
325 .add(expectation(max(values[pfExposureNodes[i]], RandomVariable(model_->size(), 0.0))).at(0))
326 .add(expectation(max(-values[pfExposureNodes[i]], RandomVariable(model_->size(), 0.0))).at(0));
327 }
328 epeReport_->end();
329 epeReport_->toFile("Output/xvacg-exposure.csv");
330 }
331
332 Real cva = expectation(values[cvaNode]).at(0);
333 LOG("XvaEngineCG: Calcuated CVA (node " << cvaNode << ") = " << cva);
334
335 rvMemMax = std::max(rvMemMax, numberOfStochasticRvs(values) + numberOfStochasticRvs(derivatives));
336
337 // Do backward derivatives run
338
339 boost::timer::nanosecond_type timing11 = timer.elapsed().wall;
340
341 std::vector<double> modelParamDerivatives(baseModelParams_.size());
342
343 if (!bumpCvaSensis_) {
344
345 LOG("XvaEngineCG: run backward derivatives");
346
347 derivatives[cvaNode] = RandomVariable(model_->size(), 1.0);
348
349 std::vector<bool> keepNodesDerivatives(g->size(), false);
350
351 for (auto const& [n, _] : baseModelParams_)
352 keepNodesDerivatives[n] = true;
353
354 // backward derivatives run
355
356 backwardDerivatives(*g, values, derivatives, grads_, RandomVariable::deleter, keepNodesDerivatives, ops_,
359
360 // read model param derivatives
361
362 Size i = 0;
363 for (auto const& [n, v] : baseModelParams_) {
364 modelParamDerivatives[i++] = expectation(derivatives[n]).at(0);
365 }
366
367 // get mem consumption
368
369 rvMemMax = std::max(rvMemMax, numberOfStochasticRvs(values) + numberOfStochasticRvs(derivatives));
370
371 LOG("XvaEngineCG: got " << modelParamDerivatives.size()
372 << " model parameter derivatives from run backward derivatives");
373
374 timing11 = timer.elapsed().wall;
375
376 // Delete values and derivatives vectors, they are not needed from this point on
377 // except we are doing a full revaluation!
378
379 values.clear();
380 derivatives.clear();
381 }
382
383 // 13 generate sensitivity scenarios
384
385 LOG("XvaEngineCG: running sensi scenarios");
386
387 sensiScenarioGenerator_ = QuantLib::ext::make_shared<SensitivityScenarioGenerator>(
389 QuantLib::ext::make_shared<DeltaScenarioFactory>(simMarket_->baseScenario()), false, std::string(), continueOnError,
390 simMarket_->baseScenarioAbsolute());
391
392 simMarket_->scenarioGenerator() = sensiScenarioGenerator_;
393
394 auto resultCube = QuantLib::ext::make_shared<DoublePrecisionSensiCube>(std::set<std::string>{"CVA"}, asof_,
395 sensiScenarioGenerator_->samples());
396 resultCube->setT0(cva, 0, 0);
397
398 model_->alwaysForwardNotifications();
399
400 Size activeScenarios = 0;
401 for (Size sample = 0; sample < resultCube->samples(); ++sample) {
402
403 // update sim market to next scenario
404
405 simMarket_->preUpdate();
406 simMarket_->updateScenario(asof_);
407 simMarket_->postUpdate(asof_, false);
408
409 // recalibrate the model
410
411 camBuilder_->recalibrate();
412
413 Real sensi = 0.0;
414
415 // calculate sensi if model was notified of a change
416
417 if (!model_->isCalculated()) {
418
419 model_->calculate();
420 ++activeScenarios;
421
422 if (!bumpCvaSensis_) {
423
424 // calcuate CVA sensi using ad derivatives
425
426 auto modelParameters = model_->modelParameters();
427 Size i = 0;
428 boost::accumulators::accumulator_set<
429 double, boost::accumulators::stats<boost::accumulators::tag::weighted_sum>, double>
430 acc;
431 for (auto const& [n, v0] : baseModelParams_) {
432 Real v1 = modelParameters[i].second;
433 acc(modelParamDerivatives[i], boost::accumulators::weight = (v1 - v0));
434 ++i;
435 }
436 sensi = boost::accumulators::weighted_sum(acc);
437
438 } else {
439
440 // calcuate CVA sensi doing full recalc of CVA
441
442 populateModelParameters(values, model_->modelParameters());
444 sensi = expectation(values[cvaNode]).at(0) - cva;
445
446 }
447 }
448
449 // set result in cube
450
451 resultCube->set(cva + sensi, 0, 0, sample, 0);
452 }
453
454 boost::timer::nanosecond_type timing12 = timer.elapsed().wall;
455
456 LOG("XvaEngineCG: finished running " << resultCube->samples() << " sensi scenarios, thereof " << activeScenarios
457 << " active.");
458
459 // write out sensi report
460
461 {
462 sensiReport_ = QuantLib::ext::make_shared<InMemoryReport>();
463 auto sensiCube = QuantLib::ext::make_shared<SensitivityCube>(
464 resultCube, sensiScenarioGenerator_->scenarioDescriptions(), sensiScenarioGenerator_->shiftSizes(),
465 sensiScenarioGenerator_->shiftSizes(), sensiScenarioGenerator_->shiftSchemes());
466 auto sensiStream = QuantLib::ext::make_shared<SensitivityCubeStream>(sensiCube, simMarketData_->baseCcy());
467 ReportWriter().writeScenarioReport(*sensiReport_, {sensiCube}, 0.0);
468 sensiReport_->toFile("Output/xvacg-cva-sensi-scenario.csv");
469 }
470
471 // Output statistics
472
473 LOG("XvaEngineCG: graph size : " << g->size());
474 LOG("XvaEngineCG: red nodes : " << sumRedNodes);
475 LOG("XvaEngineCG: red node dependendices : " << g->redBlockDependencies().size());
476 LOG("XvaEngineCG: Peak mem usage : " << ore::data::os::getPeakMemoryUsageBytes() / 1024 / 1024 << " MB");
477 LOG("XvaEngineCG: Peak theoretical rv mem : " << static_cast<double>(rvMemMax) / 1024 / 1024 * 8 * model_->size()
478 << " MB");
479 LOG("XvaEngineCG: T0 market build : " << std::fixed << std::setprecision(1) << timing1 / 1E6 << " ms");
480 LOG("XvaEngineCG: Sim market build : " << std::fixed << std::setprecision(1) << (timing2 - timing1) / 1E6
481 << " ms");
482 LOG("XvaEngineCG: Part A CG build : " << std::fixed << std::setprecision(1) << (timing3 - timing2) / 1E6
483 << " ms");
484 LOG("XvaEngineCG: Portfolio build : " << std::fixed << std::setprecision(1) << (timing4 - timing3) / 1E6
485 << " ms");
486 LOG("XvaEngineCG: Part B CG build : " << std::fixed << std::setprecision(1) << (timing5 - timing4) / 1E6
487 << " ms");
488 LOG("XvaEngineCG: Part C CG build : " << std::fixed << std::setprecision(1) << (timing6 - timing5) / 1E6
489 << " ms");
490 LOG("XvaEngineCG: Part D CG build : " << std::fixed << std::setprecision(1) << (timing7 - timing6) / 1E6
491 << " ms");
492 LOG("XvaEngineCG: RV gen : " << std::fixed << std::setprecision(1) << (timing8 - timing7) / 1E6
493 << " ms");
494 LOG("XvaEngineCG: Const and Model params : " << std::fixed << std::setprecision(1) << (timing9 - timing8) / 1E6
495 << " ms");
496 LOG("XvaEngineCG: Forward eval : " << std::fixed << std::setprecision(1) << (timing10 - timing9) / 1E6
497 << " ms");
498 LOG("XvaEngineCG: Backward deriv : " << std::fixed << std::setprecision(1) << (timing11 - timing10) / 1E6
499 << " ms");
500 LOG("XvaEngineCG: Sensi Cube Gen : " << std::fixed << std::setprecision(1) << (timing12 - timing11) / 1E6
501 << " ms");
502 LOG("XvaEngineCG: total : " << std::fixed << std::setprecision(1) << timing12 / 1E6 << " ms");
503}
504
505void XvaEngineCG::populateRandomVariates(std::vector<RandomVariable>& values) const {
506
507 DLOG("XvaEngineCG: populate random variates");
508
509 auto const& rv = model_->randomVariates();
510 if (!rv.empty()) {
511 auto gen = makeMultiPathVariateGenerator(scenarioGeneratorData_->sequenceType(), rv.size(), rv.front().size(),
513 scenarioGeneratorData_->directionIntegers());
514 for (Size path = 0; path < model_->size(); ++path) {
515 auto p = gen->next();
516 for (Size j = 0; j < rv.front().size(); ++j) {
517 for (Size k = 0; k < rv.size(); ++k) {
518 values[rv[k][j]].set(path, p.value[j][k]);
519 }
520 }
521 }
522 DLOG("XvaEngineCG: generated rvs for " << rv.size() << " underlyings and " << rv.front().size()
523 << " time steps.");
524 }
525}
526
527void XvaEngineCG::populateConstants(std::vector<RandomVariable>& values) const {
528
529 DLOG("XvaEngineCG: populate constants");
530
531 auto g = model_->computationGraph();
532 for (auto const& c : g->constants()) {
533 values[c.second] = RandomVariable(model_->size(), c.first);
534 }
535
536 DLOG("XvaEngineCG: set " << g->constants().size() << " constants");
537}
538
539void XvaEngineCG::populateModelParameters(std::vector<RandomVariable>& values,
540 const std::vector<std::pair<std::size_t, double>>& modelParameters) const {
541
542 DLOG("XvaEngineCG: populate model parameters");
543
544 for (auto const& [n, v] : modelParameters) {
545 values[n] = RandomVariable(model_->size(), v);
546 }
547
548 DLOG("XvaEngineCG: set " << modelParameters.size() << " model parameters.");
549}
550
551} // namespace analytics
552} // namespace ore
static std::size_t nan
Write ORE outputs to reports.
virtual void writeScenarioReport(ore::data::Report &report, const std::vector< QuantLib::ext::shared_ptr< SensitivityCube > > &sensitivityCubes, QuantLib::Real outputThreshold=0.0)
QuantLib::ext::shared_ptr< ore::data::CurveConfigurations > curveConfigs_
Definition: xvaenginecg.hpp:79
QuantLib::ext::shared_ptr< ore::data::TodaysMarketParameters > todaysMarketParams_
Definition: xvaenginecg.hpp:80
void populateModelParameters(std::vector< RandomVariable > &values, const std::vector< std::pair< std::size_t, double > > &modelParameters) const
QuantLib::ext::shared_ptr< ore::analytics::SensitivityScenarioData > sensitivityData_
Definition: xvaenginecg.hpp:88
QuantLib::ext::shared_ptr< SensitivityScenarioGenerator > sensiScenarioGenerator_
QuantLib::ext::shared_ptr< InMemoryReport > sensiReport_
QuantLib::ext::shared_ptr< ore::analytics::CrossAssetModelData > crossAssetModelData_
Definition: xvaenginecg.hpp:83
QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarketParameters > simMarketData_
Definition: xvaenginecg.hpp:81
std::vector< std::pair< std::size_t, double > > baseModelParams_
std::vector< RandomVariableOpNodeRequirements > opNodeRequirements_
QuantLib::ext::shared_ptr< CrossAssetModelBuilder > camBuilder_
std::vector< RandomVariableOp > ops_
QuantLib::ext::shared_ptr< ore::data::Portfolio > portfolio_
Definition: xvaenginecg.hpp:85
QuantLib::ext::shared_ptr< InMemoryReport > epeReport_
XvaEngineCG(const Size nThreads, const Date &asof, const QuantLib::ext::shared_ptr< ore::data::Loader > &loader, const QuantLib::ext::shared_ptr< ore::data::CurveConfigurations > &curveConfigs, const QuantLib::ext::shared_ptr< ore::data::TodaysMarketParameters > &todaysMarketParams, const QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarketParameters > &simMarketData, const QuantLib::ext::shared_ptr< ore::data::EngineData > &engineData, const QuantLib::ext::shared_ptr< ore::analytics::CrossAssetModelData > &crossAssetModelData, const QuantLib::ext::shared_ptr< ore::analytics::ScenarioGeneratorData > &scenarioGeneratorData, const QuantLib::ext::shared_ptr< ore::data::Portfolio > &portfolio, const string &marketConfiguration=Market::defaultConfiguration, const string &marketConfigurationInCcy=Market::inCcyConfiguration, const QuantLib::ext::shared_ptr< ore::analytics::SensitivityScenarioData > &sensitivityData=nullptr, const QuantLib::ext::shared_ptr< ReferenceDataManager > &referenceData=nullptr, const IborFallbackConfig &iborFallbackConfig=IborFallbackConfig::defaultConfig(), const bool bumpCvaSensis=false, const bool continueOnCalibrationError=true, const bool continueOnError=true, const std::string &context="xva engine cg")
Definition: xvaenginecg.cpp:53
void populateConstants(std::vector< RandomVariable > &values) const
std::string marketConfigurationInCcy_
Definition: xvaenginecg.hpp:87
IborFallbackConfig iborFallbackConfig_
Definition: xvaenginecg.hpp:90
std::vector< RandomVariableGrad > grads_
QuantLib::ext::shared_ptr< ore::analytics::ScenarioGeneratorData > scenarioGeneratorData_
Definition: xvaenginecg.hpp:84
QuantLib::ext::shared_ptr< ore::data::Market > initMarket_
QuantLib::ext::shared_ptr< ReferenceDataManager > referenceData_
Definition: xvaenginecg.hpp:89
QuantLib::ext::shared_ptr< GaussianCamCG > model_
QuantLib::ext::shared_ptr< ore::data::Loader > loader_
Definition: xvaenginecg.hpp:78
void populateRandomVariates(std::vector< RandomVariable > &values) const
QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarket > simMarket_
QuantLib::ext::shared_ptr< ore::data::EngineData > engineData_
Definition: xvaenginecg.hpp:82
Context & context_
factory class for cloning a cached scenario
unsigned long long getPeakMemoryUsageBytes()
#define LOG(text)
#define DLOG(text)
RandomVariable max(RandomVariable x, const RandomVariable &y)
std::size_t cg_const(ComputationGraph &g, const double value)
void forwardEvaluation(const ComputationGraph &g, std::vector< T > &values, const std::vector< std::function< T(const std::vector< const T * > &)> > &ops, std::function< void(T &)> deleter={}, bool keepValuesForDerivatives=true, const std::vector< std::function< std::pair< std::vector< bool >, bool >(const std::size_t)> > &opRequiresNodesForDerivatives={}, const std::vector< bool > &keepNodes={})
std::size_t cg_max(ComputationGraph &g, const std::size_t a, const std::size_t b, const std::string &label)
std::vector< RandomVariableOpNodeRequirements > getRandomVariableOpNodeRequirements()
boost::shared_ptr< MultiPathVariateGeneratorBase > makeMultiPathVariateGenerator(const SequenceType s, const Size dimension, const Size timeSteps, const BigNatural seed, const SobolBrownianGenerator::Ordering ordering, const SobolRsg::DirectionIntegers directionIntegers)
RandomVariable expectation(const RandomVariable &r)
std::size_t cg_mult(ComputationGraph &g, const std::size_t a, const std::size_t b, const std::string &label)
std::size_t cg_add(ComputationGraph &g, const std::size_t a, const std::size_t b, const std::string &label)
std::vector< RandomVariableOp > getRandomVariableOps(const Size size, const std::map< Size, std::vector< std::function< RandomVariable(const std::vector< const RandomVariable * > &)> > > &basisFn)
std::vector< RandomVariableGrad > getRandomVariableGradients(const Size size, const double eps, const std::vector< std::function< RandomVariable(const std::vector< const RandomVariable * > &)> > &basisFn)
void backwardDerivatives(const ComputationGraph &g, const std::vector< T > &values, std::vector< T > &derivatives, const std::vector< std::function< std::vector< T >(const std::vector< const T * > &, const T *)> > &grad, std::function< void(T &)> deleter={}, const std::vector< bool > &keepNodes={})
Size size(const ValueType &v)
std::size_t addModelParameter(ComputationGraph &g, std::vector< std::pair< std::size_t, std::function< double(void)> > > &m, const std::string &id, std::function< double(void)> f)
The base NPV cube class.
An NPV cube for storing NPVs resulting from risk factor shifts.
A Class to write ORE outputs to reports.
A cube implementation that stores the cube in memory.
holds a grid of NPVs for a list of trades under various scenarios
Class for streaming SensitivityRecords from a SensitivityCube.
static std::function< void(RandomVariable &)> deleter
Real at(const Size i) const
static constexpr std::size_t ConditionalExpectation
vector< string > curveConfigs
Date asof(14, Jun, 2018)
xva engine using cg infrastructure