40using namespace boost::filesystem;
50 LOG(
"XvaAnalytic::setUpConfigurations() called");
59 std::map<std::string, std::string> nettingSetMap = portfolio->nettingSetMap();
60 std::vector<std::string> nettingSetKeys;
61 for(std::map<std::string, std::string>::iterator it = nettingSetMap.begin(); it != nettingSetMap.end(); ++it)
62 nettingSetKeys.push_back(it->second);
64 sort(nettingSetKeys.begin(), nettingSetKeys.end());
65 nettingSetKeys.erase(unique( nettingSetKeys.begin(), nettingSetKeys.end() ), nettingSetKeys.end());
67 for(
auto const& key : nettingSetKeys){
68 LOG(
"For netting-set "<<key<<
"CSA flag is "<<
inputs_->nettingSetManager()->get(key)->activeCsaFlag());
69 if (
inputs_->nettingSetManager()->get(key)->activeCsaFlag()){
70 string calculationType =
inputs_->collateralCalculationType();
71 if (
analytic()->configurations().scenarioGeneratorData->withCloseOutLag()){
72 QL_REQUIRE(calculationType ==
"NoLag",
"For nettingSetID "<<key<<
", CSA is active and a close-out grid is configured in the simulation.xml. Therefore, calculation type "<<calculationType<<
" is not admissable. It must be set to NoLag!");
73 LOG(
"For netting-set "<<key<<
", calculation type is "<<calculationType);
76 QL_REQUIRE(calculationType !=
"NoLag",
"For nettingSetID "<<key<<
", CSA is active and a close-out grid is not configured in the simulation.xml. Therefore, calculation type " <<calculationType<<
" is not admissable. It must be set to either Symmetric or AsymmerticCVA or AsymmetricDVA!" );
77 LOG(
"For netting-set "<<key<<
", calculation type is "<<calculationType);
79 if (
analytic()->configurations().scenarioGeneratorData->withCloseOutLag() &&
analytic()->configurations().scenarioGeneratorData->closeOutLag() != 0*Days){
81 Period mpor_netting =
inputs_->nettingSetManager()->get(key)->csaDetails()->marginPeriodOfRisk();
82 if (mpor_simulation != mpor_netting)
84 "XvaAnalytic",
"Inconsistent MPoR period",
85 "For netting set " + key +
", close-out lag is not consistent with the netting-set's mpor ")
93 LOG(
"XvaAnalytic::engineFactory() called");
94 QuantLib::ext::shared_ptr<EngineData> edCopy = QuantLib::ext::make_shared<EngineData>(*
inputs_->simulationPricingEngine());
95 edCopy->globalParameters()[
"GenerateAdditionalResults"] =
inputs_->outputAdditionalResults() ?
"true" :
"false";
96 edCopy->globalParameters()[
"RunType"] =
"Exposure";
97 map<MarketContext, string> configurations;
98 configurations[MarketContext::irCalibration] =
inputs_->marketConfig(
"lgmcalibration");
99 configurations[MarketContext::fxCalibration] =
inputs_->marketConfig(
"fxcalibration");
100 configurations[MarketContext::pricing] =
inputs_->marketConfig(
"pricing");
102 std::vector<QuantLib::ext::shared_ptr<EngineBuilder>> extraEngineBuilders;
103 std::vector<QuantLib::ext::shared_ptr<LegBuilder>> extraLegBuilders;
107 QL_REQUIRE(
simMarket_,
"Simulaton market not set");
113 *
inputs_->iborFallbackConfig());
121 std::string configuration =
inputs_->marketConfig(
"simulation");
122 simMarket_ = QuantLib::ext::make_shared<ScenarioSimMarket>(
124 analytic()->configurations().simMarketParams,
125 QuantLib::ext::make_shared<FixingManager>(
inputs_->asof()),
127 *
inputs_->curveConfigs().get(),
128 *
analytic()->configurations().todaysMarketParams,
131 *
inputs_->iborFallbackConfig(),
141 QuantLib::ext::make_shared<FixingManager>(
inputs_->asof()), configuration, *
inputs_->curveConfigs().get(),
142 *
analytic()->configurations().todaysMarketParams,
inputs_->continueOnError(),
true,
true,
false,
148 configuration, *
inputs_->curveConfigs().get(), *
analytic()->configurations().todaysMarketParams,
151 TLOG(
"XvaAnalytic: Offset Scenario used in building SimMarket");
153 TLOG(
"RfKey,OffsetScenarioValue");
159 TLOG(
"XvaAnalytic:Finished building Scenario SimMarket");
160 TLOG(
"RfKey,BaseScenarioValue,BaseScenarioAbsValue");
161 for (
const auto& key :
simMarket_->baseScenario()->keys()) {
164 TLOG(
"XvaAnalytic: Finished building Scenario SimMarket for model calibration (useSpreadedTermStructure)");
165 TLOG(
"RfKey,BaseScenarioValue,BaseScenarioAbsValue");
176 QuantLib::ext::shared_ptr<ScenarioFactory> sf = QuantLib::ext::make_shared<SimpleScenarioFactory>(
true);
177 string config =
inputs_->marketConfig(
"simulation");
182 LOG(
"simulation grid size " <<
grid_->size());
183 LOG(
"simulation grid valuation dates " <<
grid_->valuationDates().size());
184 LOG(
"simulation grid close-out dates " <<
grid_->closeOutDates().size());
185 LOG(
"simulation grid front date " << io::iso_date(
grid_->dates().front()));
186 LOG(
"simulation grid back date " << io::iso_date(
grid_->dates().back()));
188 if (
inputs_->writeScenarios()) {
189 auto report = QuantLib::ext::make_shared<InMemoryReport>();
196 LOG(
"XVA: Build Simulation Model (continueOnCalibrationError = "
197 << std::boolalpha << continueOnCalibrationError <<
")");
199 QL_REQUIRE(market !=
nullptr,
"Internal error, buildCrossAssetModel needs to be called after the market is built.");
201 market,
analytic()->configurations().crossAssetModelData,
inputs_->marketConfig(
"lgmcalibration"),
202 inputs_->marketConfig(
"fxcalibration"),
inputs_->marketConfig(
"eqcalibration"),
203 inputs_->marketConfig(
"infcalibration"),
inputs_->marketConfig(
"crcalibration"),
204 inputs_->marketConfig(
"simulation"),
false, continueOnCalibrationError,
"",
205 inputs_->salvageCorrelationMatrix() ? SalvagingAlgorithm::Spectral : SalvagingAlgorithm::None,
212 LOG(
"XVA: Set cube depth");
220 LOG(
"Init cube with depth " << cubeDepth);
222 for (Size i = 0; i <
grid_->valuationDates().
size(); ++i)
223 DLOG(
"initCube: grid[" << i <<
"]=" << io::iso_date(
grid_->valuationDates()[i]));
226 cube = QuantLib::ext::make_shared<SinglePrecisionInMemoryCube>(
inputs_->asof(),
229 cube = QuantLib::ext::make_shared<SinglePrecisionInMemoryCubeN>(
inputs_->asof(),
236 LOG(
"XVA: initClassicRun");
242 LOG(
"XVA: Create asd " <<
grid_->valuationDates().size() <<
" x " <<
samples_);
244 QuantLib::ext::make_shared<InMemoryAggregationScenarioData>(
grid_->valuationDates().size(),
samples_));
250 if (
inputs_->nThreads() == 1) {
251 if (portfolio->size() > 0)
256 if (
inputs_->storeSurvivalProbabilities()) {
258 auto counterparties =
inputs_->portfolio()->counterparties();
259 counterparties.insert(
inputs_->dvaName());
266 LOG(
"XVA: initClassicRun completed");
271 LOG(
"XVA: classicRun");
274 Size n = portfolio->size();
277 LOG(
"XVA: Build classic portfolio of size " << n <<
" linked to the simulation market");
278 const string msg =
"XVA: Build Portfolio";
283 for (
const auto& [tradeId, trade] : portfolio->trades())
285 QL_REQUIRE(
analytic()->market(),
"today's market not set");
286 QuantLib::ext::shared_ptr<EngineFactory> factory =
engineFactory();
288 Date maturityDate =
inputs_->asof();
289 if (
inputs_->portfolioFilterDate() != Null<Date>())
290 maturityDate =
inputs_->portfolioFilterDate();
291 LOG(
"Filter trades that expire before " << maturityDate);
302 LOG(
"XVA: classicRun completed");
310 LOG(
"XVA::buildCube");
313 auto calculators = [
this]() {
314 vector<QuantLib::ext::shared_ptr<ValuationCalculator>> calculators;
316 QuantLib::ext::shared_ptr<NPVCalculator> npvCalc =
317 QuantLib::ext::make_shared<NPVCalculator>(
inputs_->exposureBaseCurrency());
318 calculators.push_back(QuantLib::ext::make_shared<MPORCalculator>(npvCalc,
cubeInterpreter_->defaultDateNpvIndex(),
321 calculators.push_back(QuantLib::ext::make_shared<NPVCalculator>(
inputs_->exposureBaseCurrency()));
323 calculators.push_back(QuantLib::ext::make_shared<CashflowCalculator>(
325 if(
inputs_->storeCreditStateNPVs() > 0) {
326 calculators.push_back(QuantLib::ext::make_shared<MultiStateNPVCalculator>(
inputs_->exposureBaseCurrency(),
328 inputs_->storeCreditStateNPVs()));
335 auto cptyCalculators = [
this]() {
336 vector<QuantLib::ext::shared_ptr<CounterpartyCalculator>> cptyCalculators;
337 if (
inputs_->storeSurvivalProbabilities()) {
338 string configuration =
inputs_->marketConfig(
"simulation");
339 cptyCalculators.push_back(QuantLib::ext::make_shared<SurvivalProbabilityCalculator>(configuration));
341 return cptyCalculators;
347 o <<
"XVA: Build Cube " << portfolio->size() <<
" x " <<
grid_->valuationDates().size() <<
" x " <<
samples_;
353 auto progressBar = QuantLib::ext::make_shared<SimpleProgressBar>(o.str(), ConsoleLog::instance().width(), ConsoleLog::instance().progressBarWidth());
354 auto progressLog = QuantLib::ext::make_shared<ProgressLog>(
"XVA: Building cube", 100, oreSeverity::notice);
363 engine.
buildCube(portfolio,
cube_, calculators(),
analytic()->configurations().scenarioGeneratorData->withMporStickyDate(),
371 auto cubeFactory = [
this](
const QuantLib::Date&
asof,
const std::set<std::string>& ids,
372 const std::vector<QuantLib::Date>& dates,
373 const Size samples) -> QuantLib::ext::shared_ptr<NPVCube> {
375 return QuantLib::ext::make_shared<SinglePrecisionInMemoryCube>(
asof, ids, dates, samples, 0.0f);
377 return QuantLib::ext::make_shared<SinglePrecisionInMemoryCubeN>(
asof, ids, dates, samples,
381 std::function<QuantLib::ext::shared_ptr<NPVCube>(
const QuantLib::Date&,
const std::set<std::string>&,
382 const std::vector<QuantLib::Date>&,
383 const QuantLib::Size)>
385 if (
inputs_->storeSurvivalProbabilities()) {
386 cptyCubeFactory = [](
const QuantLib::Date&
asof,
const std::set<std::string>& ids,
387 const std::vector<QuantLib::Date>& dates,
388 const Size samples) -> QuantLib::ext::shared_ptr<NPVCube> {
389 return QuantLib::ext::make_shared<SinglePrecisionInMemoryCube>(
asof, ids, dates, samples, 0.0f);
392 cptyCubeFactory = [](
const QuantLib::Date&
asof,
const std::set<std::string>& ids,
393 const std::vector<QuantLib::Date>& dates,
394 const Size samples) -> QuantLib::ext::shared_ptr<NPVCube> {
return nullptr; };
399 inputs_->simulationPricingEngine(),
inputs_->curveConfigs().get(),
400 analytic()->configurations().todaysMarketParams,
inputs_->marketConfig(
"simulation"),
401 analytic()->configurations().simMarketParams,
false,
false, QuantLib::ext::make_shared<ScenarioFilter>(),
402 inputs_->refDataManager(), *
inputs_->iborFallbackConfig(),
true,
false,
false, cubeFactory, {},
409 engine.
buildCube(portfolio, calculators, cptyCalculators,
410 analytic()->configurations().scenarioGeneratorData->withMporStickyDate());
412 cube_ = QuantLib::ext::make_shared<JointNPVCube>(engine.
outputCubes(), portfolio->ids());
414 if (
inputs_->storeSurvivalProbabilities())
415 cptyCube_ = QuantLib::ext::make_shared<JointNPVCube>(
417 [](Real a, Real x) { return std::max(a, x); }, 0.0);
422 LOG(
"XVA::buildCube done");
424 Settings::instance().evaluationDate() =
inputs_->asof();
427QuantLib::ext::shared_ptr<EngineFactory>
429 const std::vector<Date>& grid) {
430 LOG(
"XvaAnalytic::engineFactory() called");
431 QuantLib::ext::shared_ptr<EngineData> edCopy = QuantLib::ext::make_shared<EngineData>(*
inputs_->amcPricingEngine());
432 edCopy->globalParameters()[
"GenerateAdditionalResults"] =
"false";
433 edCopy->globalParameters()[
"RunType"] =
"NPV";
434 map<MarketContext, string> configurations;
435 configurations[MarketContext::irCalibration] =
inputs_->marketConfig(
"lgmcalibration");
436 configurations[MarketContext::fxCalibration] =
inputs_->marketConfig(
"fxcalibration");
437 configurations[MarketContext::pricing] =
inputs_->marketConfig(
"pricing");
438 ext::shared_ptr<ore::data::Market> market =
440 auto factory = QuantLib::ext::make_shared<EngineFactory>(
441 edCopy, market, configurations,
inputs_->refDataManager(), *
inputs_->iborFallbackConfig(),
442 EngineBuilderFactory::instance().generateAmcEngineBuilders(cam, grid),
true);
447 LOG(
"XVA: buildAmcPortfolio");
448 const string msg =
"XVA: Build AMC portfolio";
452 LOG(
"buildAmcPortfolio: Check sim dates");
453 std::vector<Date> simDates =
457 LOG(
"buildAmcPortfolio: Register additional engine builders");
460 LOG(
"buildAmcPortfolio: Load Portfolio");
461 QuantLib::ext::shared_ptr<Portfolio> portfolio =
inputs_->portfolio();
463 LOG(
"Build Portfolio with AMC Engine factory and select amc-enabled trades")
465 for (
auto const& [tradeId, trade] : portfolio->trades()) {
466 if (
inputs_->amcTradeTypes().find(trade->tradeType()) !=
inputs_->amcTradeTypes().end()) {
469 trade->build(factory);
471 DLOG(
"trade " << tradeId <<
" is added to amc portfolio");
472 }
catch (
const std::exception& e) {
482 LOG(
"XVA: buildAmcPortfolio completed");
490 LOG(
"XVA: Create asd " <<
grid_->valuationDates().size() <<
" x " <<
samples_);
492 QuantLib::ext::make_shared<InMemoryAggregationScenarioData>(
grid_->valuationDates().size(),
samples_));
498 std::string message =
"XVA: Build AMC Cube " + std::to_string(
amcPortfolio_->size()) +
" x " +
499 std::to_string(
grid_->valuationDates().size()) +
" x " + std::to_string(
samples_) +
"... ";
500 auto progressBar = QuantLib::ext::make_shared<SimpleProgressBar>(message, ConsoleLog::instance().width(), ConsoleLog::instance().progressBarWidth());
501 auto progressLog = QuantLib::ext::make_shared<ProgressLog>(
"XVA: Building AMC Cube...", 100, oreSeverity::notice);
503 if (
inputs_->nThreads() == 1) {
508 inputs_->exposureSimMarketParams()->additionalScenarioDataIndices(),
509 inputs_->exposureSimMarketParams()->additionalScenarioDataCcys(),
510 inputs_->exposureSimMarketParams()->additionalScenarioDataNumberOfCreditStates());
517 auto cubeFactory = [
this](
const QuantLib::Date&
asof,
const std::set<std::string>& ids,
518 const std::vector<QuantLib::Date>& dates,
519 const Size samples) -> QuantLib::ext::shared_ptr<NPVCube> {
521 return QuantLib::ext::make_shared<SinglePrecisionInMemoryCube>(
asof, ids, dates, samples, 0.0f);
523 return QuantLib::ext::make_shared<SinglePrecisionInMemoryCubeN>(
asof, ids, dates, samples,
527 auto simMarketParams =
532 inputs_->exposureSimMarketParams()->additionalScenarioDataIndices(),
533 inputs_->exposureSimMarketParams()->additionalScenarioDataCcys(),
534 inputs_->exposureSimMarketParams()->additionalScenarioDataNumberOfCreditStates(),
536 analytic()->configurations().todaysMarketParams,
inputs_->marketConfig(
"lgmcalibration"),
537 inputs_->marketConfig(
"fxcalibration"),
inputs_->marketConfig(
"eqcalibration"),
538 inputs_->marketConfig(
"infcalibration"),
inputs_->marketConfig(
"crcalibration"),
539 inputs_->marketConfig(
"simulation"),
inputs_->refDataManager(), *
inputs_->iborFallbackConfig(),
true,
552 LOG(
"XVA: amcRun completed");
556 QuantLib::ext::shared_ptr<NettingSetManager> netting =
inputs_->nettingSetManager();
557 QuantLib::ext::shared_ptr<CollateralBalances> balances =
inputs_->collateralBalances();
558 map<string, bool> analytics;
559 analytics[
"exerciseNextBreak"] =
inputs_->exerciseNextBreak();
560 analytics[
"cva"] =
inputs_->cvaAnalytic();
561 analytics[
"dva"] =
inputs_->dvaAnalytic();
562 analytics[
"fva"] =
inputs_->fvaAnalytic();
563 analytics[
"colva"] =
inputs_->colvaAnalytic();
564 analytics[
"collateralFloor"] =
inputs_->collateralFloorAnalytic();
565 analytics[
"mva"] =
inputs_->mvaAnalytic();
566 analytics[
"kva"] =
inputs_->kvaAnalytic();
567 analytics[
"dim"] =
inputs_->dimAnalytic();
568 analytics[
"dynamicCredit"] =
inputs_->dynamicCredit();
569 analytics[
"cvaSensi"] =
inputs_->cvaSensi();
570 analytics[
"flipViewXVA"] =
inputs_->flipViewXVA();
571 analytics[
"creditMigration"] =
inputs_->creditMigrationAnalytic();
573 string baseCurrency =
inputs_->xvaBaseCurrency();
574 string calculationType =
inputs_->collateralCalculationType();
575 string allocationMethod =
inputs_->exposureAllocationMethod();
576 Real marginalAllocationLimit =
inputs_->marginalAllocationLimit();
577 Real quantile =
inputs_->pfeQuantile();
578 string dvaName =
inputs_->dvaName();
579 string fvaLendingCurve =
inputs_->fvaLendingCurve();
580 string fvaBorrowingCurve =
inputs_->fvaBorrowingCurve();
582 Real dimQuantile =
inputs_->dimQuantile();
583 Size dimHorizonCalendarDays =
inputs_->dimHorizonCalendarDays();
584 Size dimRegressionOrder =
inputs_->dimRegressionOrder();
585 vector<string> dimRegressors =
inputs_->dimRegressors();
586 Size dimLocalRegressionEvaluations =
inputs_->dimLocalRegressionEvaluations();
587 Real dimLocalRegressionBandwidth =
inputs_->dimLocalRegressionBandwidth();
589 Real kvaCapitalDiscountRate =
inputs_->kvaCapitalDiscountRate();
590 Real kvaAlpha =
inputs_->kvaAlpha();
591 Real kvaRegAdjustment =
inputs_->kvaRegAdjustment();
592 Real kvaCapitalHurdle =
inputs_->kvaCapitalHurdle();
593 Real kvaOurPdFloor =
inputs_->kvaOurPdFloor();
594 Real kvaTheirPdFloor =
inputs_->kvaTheirPdFloor();
595 Real kvaOurCvaRiskWeight =
inputs_->kvaOurCvaRiskWeight();
596 Real kvaTheirCvaRiskWeight =
inputs_->kvaTheirCvaRiskWeight();
598 string marketConfiguration =
inputs_->marketConfig(
"simulation");
600 bool fullInitialCollateralisation =
inputs_->fullInitialCollateralisation();
605 if (
inputs_->dimModel() ==
"Regression") {
606 LOG(
"dim calculator not set, create RegressionDynamicInitialMarginCalculator");
607 std::map<std::string, Real> currentIM;
608 if (
inputs_->collateralBalances()) {
609 for (
auto const& [n, b] :
inputs_->collateralBalances()->collateralBalances()) {
610 currentIM[n.nettingSetId()] =
611 b->initialMargin() * (b->currency() == baseCurrency
615 ->fxRate(b->currency() + baseCurrency, marketConfiguration)
619 dimCalculator_ = QuantLib::ext::make_shared<RegressionDynamicInitialMarginCalculator>(
621 dimHorizonCalendarDays, dimRegressionOrder, dimRegressors, dimLocalRegressionEvaluations,
622 dimLocalRegressionBandwidth, currentIM);
624 LOG(
"dim calculator not set, create FlatDynamicInitialMarginCalculator");
625 dimCalculator_ = QuantLib::ext::make_shared<FlatDynamicInitialMarginCalculator>(
630 std::vector<Period> cvaSensiGrid =
inputs_->cvaSensiGrid();
631 Real cvaSensiShiftSize =
inputs_->cvaSensiShiftSize();
633 string flipViewBorrowingCurvePostfix =
inputs_->flipViewBorrowingCurvePostfix();
634 string flipViewLendingCurvePostfix =
inputs_->flipViewLendingCurvePostfix();
636 LOG(
"baseCurrency " << baseCurrency);
642 baseCurrency, allocationMethod, marginalAllocationLimit, quantile, calculationType, dvaName, fvaBorrowingCurve,
644 cvaSensiShiftSize, kvaCapitalDiscountRate, kvaAlpha, kvaRegAdjustment, kvaCapitalHurdle, kvaOurPdFloor,
645 kvaTheirPdFloor, kvaOurCvaRiskWeight, kvaTheirCvaRiskWeight,
cptyCube_, flipViewBorrowingCurvePostfix,
646 flipViewLendingCurvePostfix,
inputs_->creditSimulationParameters(),
inputs_->creditMigrationDistributionGrid(),
648 analytic()->configurations().scenarioGeneratorData->withMporStickyDate(),
inputs_->mporCashFlowMode());
653 const std::set<std::string>& runTypes) {
656 LOG(
"XVA analytic is running with amc cg engine (experimental).");
659 analytic()->configurations().todaysMarketParams,
660 analytic()->configurations().simMarketParams,
inputs_->amcPricingEngine(),
662 inputs_->marketConfig(
"simulation"),
inputs_->marketConfig(
"simulation"),
671 LOG(
"XVA analytic called with asof " << io::iso_date(
inputs_->asof()));
674 if (runTypes.find(
"EXPOSURE") != runTypes.end() || runTypes.empty())
677 if (runTypes.find(
"XVA") != runTypes.end() || runTypes.empty())
680 Settings::instance().evaluationDate() =
inputs_->asof();
681 ObservationMode::instance().setMode(
inputs_->exposureObservationModel());
683 const string msg =
"XVA: Build Today's Market";
697 LOG(
"XVA: Build simulation market");
700 LOG(
"XVA: Build Scenario Generator");
701 auto globalParams =
inputs_->simulationPricingEngine()->globalParameters();
702 auto continueOnCalErr = globalParams.find(
"ContinueOnCalibrationError");
703 bool continueOnErr = (continueOnCalErr != globalParams.end()) &&
parseBool(continueOnCalErr->second);
706 LOG(
"XVA: Attach Scenario Generator to ScenarioSimMarket");
710 bool doClassicRun =
true;
711 bool doAmcRun =
false;
714 auto residualPortfolio = QuantLib::ext::make_shared<Portfolio>(
inputs_->buildFailedTrades());
721 for (
auto const& [tradeId, trade] :
inputs_->portfolio()->trades()) {
722 if (
inputs_->amcTradeTypes().find(trade->tradeType()) ==
inputs_->amcTradeTypes().end())
723 residualPortfolio->add(trade);
727 LOG(
"Residual portfolio size " << residualPortfolio->size());
730 doClassicRun = !residualPortfolio->trades().empty();
732 for (
const auto& [tradeId, trade] :
inputs_->portfolio()->trades())
733 residualPortfolio->add(trade);
755 if (doClassicRun && doAmcRun) {
756 LOG(
"Joining classical and AMC cube");
758 }
else if (!doClassicRun && doAmcRun) {
759 LOG(
"We have generated an AMC cube only");
762 WLOG(
"We have generated a classic cube only");
765 LOG(
"NPV cube generation completed");
773 auto newPortfolio = QuantLib::ext::make_shared<Portfolio>();
775 newPortfolio->add(trade);
777 newPortfolio->add(trade);
778 LOG(
"Total portfolio size " << newPortfolio->size());
779 if (newPortfolio->size() <
inputs_->portfolio()->size()) {
780 ALOG(
"input portfolio size is " <<
inputs_->portfolio()->size() <<
781 ", but we have built only " << newPortfolio->size() <<
" trades");
791 LOG(
"Skip cube generation, load input cubes for XVA");
792 const string msg =
"XVA: Load Cubes";
795 QL_REQUIRE(
inputs_->cube(),
"XVA without EXPOSURE requires an NPV cube as input");
797 QL_REQUIRE(
inputs_->mktCube(),
"XVA without EXPOSURE requires a market cube as input");
822 if (
inputs_->rawCubeOutput()) {
824 auto report = QuantLib::ext::make_shared<InMemoryReport>();
835 string msg =
"XVA: Aggregation";
846 msg =
"XVA: Reports";
849 LOG(
"Generating XVA reports and cube outputs");
851 if (
inputs_->exposureProfilesByTrade()) {
852 for (
const auto& [tradeId, tradeIdCubePos] :
postProcess_->tradeIds()) {
853 auto report = QuantLib::ext::make_shared<InMemoryReport>();
857 }
catch (
const std::exception& e) {
859 {{
"tradeId", tradeId}})
865 if (
inputs_->exposureProfiles()) {
866 for (
auto [nettingSet, nettingSetPosInCube] :
postProcess_->nettingSetIds()) {
867 auto exposureReport = QuantLib::ext::make_shared<InMemoryReport>();
871 analytic()->
reports()[
"XVA"][
"exposure_nettingset_" + nettingSet] = exposureReport;
872 }
catch (
const std::exception& e) {
874 e.what(), {{
"nettingSetId", nettingSet}})
878 auto colvaReport = QuantLib::ext::make_shared<InMemoryReport>();
882 analytic()->
reports()[
"XVA"][
"colva_nettingset_" + nettingSet] = colvaReport;
883 }
catch (
const std::exception& e) {
885 e.what(), {{
"nettingSetId", nettingSet}})
889 auto cvaSensiReport = QuantLib::ext::make_shared<InMemoryReport>();
893 analytic()->
reports()[
"XVA"][
"cva_sensitivity_nettingset_" + nettingSet] = cvaSensiReport;
894 }
catch (
const std::exception& e) {
896 {{
"nettingSetId", nettingSet}})
902 auto xvaReport = QuantLib::ext::make_shared<InMemoryReport>();
903 ReportWriter(inputs_->reportNaString())
904 .writeXVA(*xvaReport, inputs_->exposureAllocationMethod(), analytic()->portfolio(), postProcess_);
905 analytic()->reports()[
"XVA"][
"xva"] = xvaReport;
907 if (inputs_->netCubeOutput()) {
908 auto report = QuantLib::ext::make_shared<InMemoryReport>();
909 ReportWriter(inputs_->reportNaString()).writeCube(*report, postProcess_->netCube());
910 analytic()->reports()[
"XVA"][
"netcube"] = report;
913 if (inputs_->dimAnalytic() || inputs_->mvaAnalytic()) {
915 auto dimEvolutionReport = QuantLib::ext::make_shared<InMemoryReport>();
916 postProcess_->exportDimEvolution(*dimEvolutionReport);
917 analytic()->reports()[
"XVA"][
"dim_evolution"] = dimEvolutionReport;
920 vector<QuantLib::ext::shared_ptr<ore::data::Report>> dimRegReports;
921 for (Size i = 0; i < inputs_->dimOutputGridPoints().
size(); ++i) {
922 auto rep = QuantLib::ext::make_shared<InMemoryReport>();
923 dimRegReports.push_back(rep);
924 analytic()->reports()[
"XVA"][
"dim_regression_" + std::to_string(i)] = rep;
926 postProcess_->exportDimRegression(inputs_->dimOutputNettingSet(), inputs_->dimOutputGridPoints(),
930 if (inputs_->creditMigrationAnalytic()) {
932 postProcess_->creditMigrationPdf().size() == inputs_->creditMigrationTimeSteps().size(),
933 "XvaAnalyticImpl::runAnalytic(): inconsistent post process results for credit migration pdf / cdf ("
934 << postProcess_->creditMigrationPdf().size() <<
") and input credit migration time steps ("
935 << inputs_->creditMigrationTimeSteps().size() <<
")");
936 for (Size i = 0; i < postProcess_->creditMigrationPdf().
size(); ++i) {
937 auto rep = QuantLib::ext::make_shared<InMemoryReport>();
939 ->reports()[
"XVA"][
"credit_migration_" + std::to_string(inputs_->creditMigrationTimeSteps()[i])] =
942 .addColumn(
"upperBucketBound",
double(), 6)
943 .addColumn(
"pdf",
double(), 8)
944 .addColumn(
"cdf",
double(), 8);
945 for (Size j = 0; j < postProcess_->creditMigrationPdf()[i].
size(); ++j) {
948 .add(postProcess_->creditMigrationUpperBucketBounds()[j])
949 .add(postProcess_->creditMigrationPdf()[i][j])
950 .add(postProcess_->creditMigrationCdf()[i][j]);
961 ObservationMode::instance().setMode(inputs_->observationModel());
965Matrix XvaAnalyticImpl::creditStateCorrelationMatrix()
const {
968 for (
auto const& [pair,
value] : analytic()->configurations().crossAssetModelData->correlations()) {
973 processInfo[CrossAssetModel::AssetType::CrState] = {
974 {
"CrState", analytic()->configurations().simMarketParams->numberOfCreditStates()}};
std::vector< QuantLib::ext::shared_ptr< ore::analytics::NPVCube > > outputCubes() const
void buildCube(const QuantLib::ext::shared_ptr< ore::data::Portfolio > &portfolio, QuantLib::ext::shared_ptr< ore::analytics::NPVCube > &outputCube)
build cube in single threaded run
QuantLib::ext::shared_ptr< ore::analytics::AggregationScenarioData > & aggregationScenarioData()
Set aggregation data.
Analytic * analytic() const
const std::string & label() const
QuantLib::ext::shared_ptr< InputParameters > inputs_
analytic_reports & reports()
Result reports.
analytic_npvcubes & npvCubes()
Configurations & configurations()
void setPortfolio(const QuantLib::ext::shared_ptr< ore::data::Portfolio > &portfolio)
virtual void buildMarket(const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &loader, const bool marketRequired=true)
const QuantLib::ext::shared_ptr< ore::data::Portfolio > & portfolio() const
const QuantLib::ext::shared_ptr< ore::data::Market > & market() const
analytic_mktcubes & mktCubes()
virtual void buildPortfolio()
std::vector< QuantLib::ext::shared_ptr< ore::analytics::NPVCube > > outputCubes() const
void setAggregationScenarioData(const QuantLib::ext::shared_ptr< AggregationScenarioData > &aggregationScenarioData)
std::vector< QuantLib::ext::shared_ptr< ore::analytics::NPVCube > > outputCptyCubes() const
void buildCube(const QuantLib::ext::shared_ptr< ore::data::Portfolio > &portfolio, const std::function< std::vector< QuantLib::ext::shared_ptr< ore::analytics::ValuationCalculator > >()> &calculators, const std::function< std::vector< QuantLib::ext::shared_ptr< ore::analytics::CounterpartyCalculator > >()> &cptyCalculators={}, bool mporStickyDate=true, bool dryRun=false)
Write ORE outputs to reports.
virtual void writeCube(ore::data::Report &report, const QuantLib::ext::shared_ptr< NPVCube > &cube, const std::map< std::string, std::string > &nettingSetMap=std::map< std::string, std::string >())
virtual void writeNettingSetCvaSensitivities(ore::data::Report &report, QuantLib::ext::shared_ptr< PostProcess > postProcess, const std::string &nettingSetId)
virtual void writeNettingSetExposures(ore::data::Report &report, QuantLib::ext::shared_ptr< PostProcess > postProcess, const std::string &nettingSetId)
virtual void writeTradeExposures(ore::data::Report &report, QuantLib::ext::shared_ptr< PostProcess > postProcess, const std::string &tradeId)
virtual void writeNettingSetColva(ore::data::Report &report, QuantLib::ext::shared_ptr< PostProcess > postProcess, const std::string &nettingSetId)
Build a ScenarioGenerator.
QuantLib::ext::shared_ptr< ScenarioGenerator > build(QuantLib::ext::shared_ptr< QuantExt::CrossAssetModel > model, QuantLib::ext::shared_ptr< ScenarioFactory > sf, QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > marketConfig, Date asof, QuantLib::ext::shared_ptr< ore::data::Market > initMarket, const std::string &configuration=ore::data::Market::defaultConfiguration, const QuantLib::ext::shared_ptr< PathGeneratorFactory > &pf=QuantLib::ext::make_shared< MultiPathGeneratorFactory >())
Build function.
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 setUpConfigurations() override
void buildClassicCube(const QuantLib::ext::shared_ptr< Portfolio > &portfolio)
QuantLib::ext::shared_ptr< ScenarioSimMarket > simMarketCalibration_
QuantLib::ext::shared_ptr< NPVCube > amcCube_
QuantLib::ext::shared_ptr< CubeInterpretation > cubeInterpreter_
virtual void runAnalytic(const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &loader, const std::set< std::string > &runTypes={}) override
void amcRun(bool doClassicRun)
QuantLib::ext::shared_ptr< ScenarioSimMarket > simMarket_
QuantLib::ext::shared_ptr< ScenarioGenerator > scenarioGenerator_
QuantLib::RelinkableHandle< AggregationScenarioData > scenarioData_
void buildScenarioSimMarket()
QuantLib::ext::shared_ptr< EngineFactory > engineFactory_
QuantLib::ext::shared_ptr< DateGrid > grid_
QuantLib::ext::shared_ptr< CrossAssetModel > model_
QuantLib::ext::shared_ptr< Portfolio > amcPortfolio_
QuantLib::ext::shared_ptr< EngineFactory > amcEngineFactory(const QuantLib::ext::shared_ptr< QuantExt::CrossAssetModel > &cam, const std::vector< Date > &grid)
void checkConfigurations(const QuantLib::ext::shared_ptr< Portfolio > &portfolio)
QuantLib::ext::shared_ptr< DynamicInitialMarginCalculator > dimCalculator_
void initClassicRun(const QuantLib::ext::shared_ptr< Portfolio > &portfolio)
QuantLib::ext::shared_ptr< Scenario > offsetScenario_
QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > offsetSimMarketParams_
void buildScenarioGenerator(bool continueOnError)
void buildCrossAssetModel(bool continueOnError)
QuantLib::ext::shared_ptr< NPVCube > cptyCube_
QuantLib::ext::shared_ptr< ore::data::EngineFactory > engineFactory() override
build an engine factory
void initCube(QuantLib::ext::shared_ptr< NPVCube > &cube, const std::set< std::string > &ids, Size cubeDepth)
QuantLib::ext::shared_ptr< Portfolio > classicRun(const QuantLib::ext::shared_ptr< Portfolio > &portfolio)
QuantLib::ext::shared_ptr< PostProcess > postProcess_
QuantLib::ext::shared_ptr< Portfolio > classicPortfolio_
Matrix creditStateCorrelationMatrix() const
QuantLib::ext::shared_ptr< NPVCube > cube_
QuantLib::ext::shared_ptr< ScenarioSimMarket > offsetSimMarket_
QuantLib::ext::shared_ptr< NPVCube > nettingSetCube_
QuantLib::ext::shared_ptr< InMemoryReport > sensiReport()
QuantLib::ext::shared_ptr< InMemoryReport > exposureReport()
QuantLib::Matrix correlationMatrix(const std::vector< std::string > &ccys)
void addCorrelation(const std::string &factor1, const std::string &factor2, QuantLib::Real correlation)
std::map< QuantExt::CrossAssetModel::AssetType, std::vector< std::pair< std::string, QuantLib::Size > > > ProcessInfo
Handle< QuantExt::CrossAssetModel > model() const
void registerProgressIndicator(const QuantLib::ext::shared_ptr< ProgressIndicator > &indicator)
SafeStack< ValueType > value
The counterparty cube calculator interface.
Dynamic Initial Margin calculator by regression.
bool parseBool(const string &s)
join n cubes in terms of stored ids
The cube valuation calculator interface.
a calculator that computes npvs for a vector of credit states
multi-threaded valuation engine
RandomVariable log(RandomVariable x)
Size size(const ValueType &v)
Singleton class to hold global Observation Mode.
A Class to write ORE outputs to reports.
factory classes for simple scenarios
QuantLib::ext::shared_ptr< ore::analytics::CrossAssetModelData > crossAssetModelData
QuantLib::ext::shared_ptr< ore::data::TodaysMarketParameters > todaysMarketParams
QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarketParameters > simMarketParams
QuantLib::ext::shared_ptr< ore::analytics::ScenarioGeneratorData > scenarioGeneratorData
Structured analytics error.
Class for structured analytics warnings.
xva engine using cg infrastructure