653 {
654
656 LOG(
"XVA analytic is running with amc cg engine (experimental).");
657
659 analytic()->configurations().todaysMarketParams,
660 analytic()->configurations().simMarketParams,
inputs_->amcPricingEngine(),
662 inputs_->marketConfig(
"simulation"),
inputs_->marketConfig(
"simulation"),
665
666 analytic()->
reports()[
"XVA"][
"xvacg-exposure"] = engine.exposureReport();
667 analytic()->
reports()[
"XVA"][
"xvacg-cva-sensi-scenario"] = engine.sensiReport();
668 return;
669 }
670
671 LOG(
"XVA analytic called with asof " << io::iso_date(
inputs_->asof()));
673
674 if (runTypes.find("EXPOSURE") != runTypes.end() || runTypes.empty())
676
677 if (runTypes.find("XVA") != runTypes.end() || runTypes.empty())
679
680 Settings::instance().evaluationDate() =
inputs_->asof();
681 ObservationMode::instance().setMode(
inputs_->exposureObservationModel());
682
683 const string msg = "XVA: Build Today's Market";
690
695
697 LOG(
"XVA: Build simulation market");
699
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);
705
706 LOG(
"XVA: Attach Scenario Generator to ScenarioSimMarket");
708
709
710 bool doClassicRun = true;
711 bool doAmcRun = false;
712
713
714 auto residualPortfolio = QuantLib::ext::make_shared<Portfolio>(
inputs_->buildFailedTrades());
715
717
719
720
721 for (
auto const& [tradeId, trade] :
inputs_->portfolio()->trades()) {
722 if (
inputs_->amcTradeTypes().find(trade->tradeType()) ==
inputs_->amcTradeTypes().end())
723 residualPortfolio->add(trade);
724 }
725
727 LOG(
"Residual portfolio size " << residualPortfolio->size());
728
730 doClassicRun = !residualPortfolio->trades().empty();
731 } else {
732 for (
const auto& [tradeId, trade] :
inputs_->portfolio()->trades())
733 residualPortfolio->add(trade);
734 }
735
736
737
738
739
740
741 if (doAmcRun)
743 else
745
746 if (doClassicRun)
748 else
750
751
752
753
754
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");
761 } else {
762 WLOG(
"We have generated a classic cube only");
763 }
764
765 LOG(
"NPV cube generation completed");
766
767
768
769
770
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");
782 }
784 } else {
785
786
788
789
790
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");
805 }
806
808
809
815 }
818 }
819 }
820
821
822 if (
inputs_->rawCubeOutput()) {
824 auto report = QuantLib::ext::make_shared<InMemoryReport>();
825 ReportWriter(
inputs_->reportNaString()).writeCube(*report,
cube_, nettingSetMap);
827 }
828
830
831
832
833
834
835 string msg = "XVA: Aggregation";
841
842
843
844
845
846 msg = "XVA: Reports";
849 LOG(
"Generating XVA reports and cube outputs");
850
851 if (
inputs_->exposureProfilesByTrade()) {
852 for (
const auto& [tradeId, tradeIdCubePos] :
postProcess_->tradeIds()) {
853 auto report = QuantLib::ext::make_shared<InMemoryReport>();
854 try {
855 ReportWriter(
inputs_->reportNaString()).writeTradeExposures(*report,
postProcess_, tradeId);
857 } catch (const std::exception& e) {
858 StructuredAnalyticsErrorMessage("Trade Exposure Report", "Error processing trade.", e.what(),
859 {{"tradeId", tradeId}})
861 }
862 }
863 }
864
865 if (
inputs_->exposureProfiles()) {
866 for (
auto [nettingSet, nettingSetPosInCube] :
postProcess_->nettingSetIds()) {
867 auto exposureReport = QuantLib::ext::make_shared<InMemoryReport>();
868 try {
869 ReportWriter(
inputs_->reportNaString())
870 .writeNettingSetExposures(*exposureReport,
postProcess_, nettingSet);
871 analytic()->
reports()[
"XVA"][
"exposure_nettingset_" + nettingSet] = exposureReport;
872 } catch (const std::exception& e) {
873 StructuredAnalyticsErrorMessage("Netting Set Exposure Report", "Error processing netting set.",
874 e.what(), {{"nettingSetId", nettingSet}})
876 }
877
878 auto colvaReport = QuantLib::ext::make_shared<InMemoryReport>();
879 try {
880 ReportWriter(
inputs_->reportNaString())
881 .writeNettingSetColva(*colvaReport,
postProcess_, nettingSet);
882 analytic()->
reports()[
"XVA"][
"colva_nettingset_" + nettingSet] = colvaReport;
883 } catch (const std::exception& e) {
884 StructuredAnalyticsErrorMessage("Netting Set Colva Report", "Error processing netting set.",
885 e.what(), {{"nettingSetId", nettingSet}})
887 }
888
889 auto cvaSensiReport = QuantLib::ext::make_shared<InMemoryReport>();
890 try {
891 ReportWriter(
inputs_->reportNaString())
892 .writeNettingSetCvaSensitivities(*cvaSensiReport,
postProcess_, nettingSet);
893 analytic()->
reports()[
"XVA"][
"cva_sensitivity_nettingset_" + nettingSet] = cvaSensiReport;
894 } catch (const std::exception& e) {
895 StructuredAnalyticsErrorMessage("Cva Sensi Report", "Error processing netting set.", e.what(),
896 {{"nettingSetId", nettingSet}})
898 }
899 }
900 }
901
902 auto xvaReport = QuantLib::ext::make_shared<InMemoryReport>();
903 ReportWriter(
inputs_->reportNaString())
906
907 if (
inputs_->netCubeOutput()) {
908 auto report = QuantLib::ext::make_shared<InMemoryReport>();
911 }
912
914
915 auto dimEvolutionReport = QuantLib::ext::make_shared<InMemoryReport>();
918
919
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;
925 }
927 dimRegReports);
928 }
929
930 if (
inputs_->creditMigrationAnalytic()) {
931 QL_REQUIRE(
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() <<
")");
937 auto rep = QuantLib::ext::make_shared<InMemoryReport>();
939 ->
reports()[
"XVA"][
"credit_migration_" + std::to_string(
inputs_->creditMigrationTimeSteps()[i])] =
940 rep;
941 (*rep)
942 .addColumn("upperBucketBound", double(), 6)
943 .addColumn("pdf", double(), 8)
944 .addColumn("cdf", double(), 8);
946 (*rep)
947 .next()
948 .add(
postProcess_->creditMigrationUpperBucketBounds()[j])
951 }
952 rep->end();
953 }
954 }
955
958 }
959
960
961 ObservationMode::instance().setMode(
inputs_->observationModel());
963}
Analytic * analytic() 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
analytic_mktcubes & mktCubes()
virtual void buildPortfolio()
QuantLib::ext::shared_ptr< NPVCube > amcCube_
QuantLib::ext::shared_ptr< CubeInterpretation > cubeInterpreter_
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< DateGrid > grid_
QuantLib::ext::shared_ptr< Portfolio > amcPortfolio_
void buildScenarioGenerator(bool continueOnError)
QuantLib::ext::shared_ptr< NPVCube > cptyCube_
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_
QuantLib::ext::shared_ptr< NPVCube > cube_
QuantLib::ext::shared_ptr< NPVCube > nettingSetCube_
bool parseBool(const string &s)
RandomVariable log(RandomVariable x)
Size size(const ValueType &v)
QuantLib::ext::shared_ptr< ore::analytics::ScenarioGeneratorData > scenarioGeneratorData