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

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

+ Inheritance diagram for XvaAnalyticImpl:
+ Collaboration diagram for XvaAnalyticImpl:

Public Member Functions

 XvaAnalyticImpl (const QuantLib::ext::shared_ptr< InputParameters > &inputs, const QuantLib::ext::shared_ptr< Scenario > &offsetScenario=nullptr, const QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > &offsetSimMarketParams=nullptr)
 
virtual void runAnalytic (const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &loader, const std::set< std::string > &runTypes={}) override
 
void setUpConfigurations () override
 
void checkConfigurations (const QuantLib::ext::shared_ptr< Portfolio > &portfolio)
 
- 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 = "XVA"
 

Protected Member Functions

QuantLib::ext::shared_ptr< ore::data::EngineFactoryengineFactory () override
 build an engine factory More...
 
void buildScenarioSimMarket ()
 
void buildCrossAssetModel (bool continueOnError)
 
void buildScenarioGenerator (bool continueOnError)
 
void initCubeDepth ()
 
void initCube (QuantLib::ext::shared_ptr< NPVCube > &cube, const std::set< std::string > &ids, Size cubeDepth)
 
void initClassicRun (const QuantLib::ext::shared_ptr< Portfolio > &portfolio)
 
void buildClassicCube (const QuantLib::ext::shared_ptr< Portfolio > &portfolio)
 
QuantLib::ext::shared_ptr< PortfolioclassicRun (const QuantLib::ext::shared_ptr< Portfolio > &portfolio)
 
QuantLib::ext::shared_ptr< EngineFactoryamcEngineFactory (const QuantLib::ext::shared_ptr< QuantExt::CrossAssetModel > &cam, const std::vector< Date > &grid)
 
void buildAmcPortfolio ()
 
void amcRun (bool doClassicRun)
 
void runPostProcessor ()
 
Matrix creditStateCorrelationMatrix () const
 

Protected Attributes

QuantLib::ext::shared_ptr< ScenarioSimMarketsimMarket_
 
QuantLib::ext::shared_ptr< ScenarioSimMarketsimMarketCalibration_
 
QuantLib::ext::shared_ptr< ScenarioSimMarketoffsetSimMarket_
 
QuantLib::ext::shared_ptr< EngineFactoryengineFactory_
 
QuantLib::ext::shared_ptr< CrossAssetModelmodel_
 
QuantLib::ext::shared_ptr< ScenarioGeneratorscenarioGenerator_
 
QuantLib::ext::shared_ptr< PortfolioamcPortfolio_
 
QuantLib::ext::shared_ptr< PortfolioclassicPortfolio_
 
QuantLib::ext::shared_ptr< NPVCubecube_
 
QuantLib::ext::shared_ptr< NPVCubenettingSetCube_
 
QuantLib::ext::shared_ptr< NPVCubecptyCube_
 
QuantLib::ext::shared_ptr< NPVCubeamcCube_
 
QuantLib::RelinkableHandle< AggregationScenarioDatascenarioData_
 
QuantLib::ext::shared_ptr< CubeInterpretationcubeInterpreter_
 
QuantLib::ext::shared_ptr< DynamicInitialMarginCalculatordimCalculator_
 
QuantLib::ext::shared_ptr< PostProcesspostProcess_
 
QuantLib::ext::shared_ptr< ScenariooffsetScenario_
 
QuantLib::ext::shared_ptr< ScenarioSimMarketParametersoffsetSimMarketParams_
 
Size cubeDepth_ = 0
 
QuantLib::ext::shared_ptr< DateGridgrid_
 
Size samples_ = 0
 
bool runSimulation_ = false
 
bool runXva_ = false
 
- 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 30 of file xvaanalytic.hpp.

Constructor & Destructor Documentation

◆ XvaAnalyticImpl()

XvaAnalyticImpl ( const QuantLib::ext::shared_ptr< InputParameters > &  inputs,
const QuantLib::ext::shared_ptr< Scenario > &  offsetScenario = nullptr,
const QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > &  offsetSimMarketParams = nullptr 
)
explicit

Definition at line 34 of file xvaanalytic.hpp.

38 : Analytic::Impl(inputs), offsetScenario_(offsetScenario), offsetSimMarketParams_(offsetSimMarketParams) {
39 QL_REQUIRE(!((offsetScenario_ == nullptr) ^ (offsetSimMarketParams_ == nullptr)),
40 "Need offsetScenario and corresponding simMarketParameter");
42 }
void setLabel(const string &label)
Definition: analytic.hpp:189
QuantLib::ext::shared_ptr< Scenario > offsetScenario_
Definition: xvaanalytic.hpp:83
QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > offsetSimMarketParams_
Definition: xvaanalytic.hpp:84
static constexpr const char * LABEL
Definition: xvaanalytic.hpp:32
+ 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 652 of file xvaanalytic.cpp.

653 {
654
655 if(inputs_->amcCg()) {
656 LOG("XVA analytic is running with amc cg engine (experimental).");
657 // note: market configs both set to simulation, see note in xvaenginecg, we'd need inccy config in sim market there...
658 XvaEngineCG engine(inputs_->nThreads(), inputs_->asof(), loader, inputs_->curveConfigs().get(),
659 analytic()->configurations().todaysMarketParams,
660 analytic()->configurations().simMarketParams, inputs_->amcPricingEngine(),
661 inputs_->crossAssetModelData(), inputs_->scenarioGeneratorData(), inputs_->portfolio(),
662 inputs_->marketConfig("simulation"), inputs_->marketConfig("simulation"),
663 inputs_->xvaCgSensiScenarioData(), inputs_->refDataManager(), *inputs_->iborFallbackConfig(),
664 inputs_->xvaCgBumpSensis());
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()));
672 ProgressMessage("Running XVA Analytic", 0, 1).log();
673
674 if (runTypes.find("EXPOSURE") != runTypes.end() || runTypes.empty())
675 runSimulation_ = true;
676
677 if (runTypes.find("XVA") != runTypes.end() || runTypes.empty())
678 runXva_ = true;
679
680 Settings::instance().evaluationDate() = inputs_->asof();
681 ObservationMode::instance().setMode(inputs_->exposureObservationModel());
682
683 const string msg = "XVA: Build Today's Market";
684 LOG(msg);
685 CONSOLEW(msg);
686 ProgressMessage(msg, 0, 1).log();
687 analytic()->buildMarket(loader);
688 CONSOLE("OK");
689 ProgressMessage(msg, 1, 1).log();
690
692 cubeInterpreter_ = QuantLib::ext::make_shared<CubeInterpretation>(
693 inputs_->storeFlows(), analytic()->configurations().scenarioGeneratorData->withCloseOutLag(), scenarioData_,
694 grid_, inputs_->storeCreditStateNPVs(), inputs_->flipViewXVA());
695
696 if (runSimulation_) {
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);
704 buildScenarioGenerator(continueOnErr);
705
706 LOG("XVA: Attach Scenario Generator to ScenarioSimMarket");
707 simMarket_->scenarioGenerator() = scenarioGenerator_;
708
709 // We may have to build two cubes below for complementary sub-portfolios, a classical cube and an AMC cube
710 bool doClassicRun = true;
711 bool doAmcRun = false;
712
713 // Initialize the residual "classical" portfolio that we do not process using AMC
714 auto residualPortfolio = QuantLib::ext::make_shared<Portfolio>(inputs_->buildFailedTrades());
715
716 if (inputs_->amc()) {
717 // Build a separate sub-portfolio for the AMC cube generation and perform its training
719
720 // Build the residual portfolio for the classic cube generation, i.e. strip out the AMC part
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
726 LOG("AMC portfolio size " << amcPortfolio_->size());
727 LOG("Residual portfolio size " << residualPortfolio->size());
728
729 doAmcRun = !amcPortfolio_->trades().empty();
730 doClassicRun = !residualPortfolio->trades().empty();
731 } else {
732 for (const auto& [tradeId, trade] : inputs_->portfolio()->trades())
733 residualPortfolio->add(trade);
734 }
735
736 /********************************************************************************
737 * This is where we build cubes and the "classic" valuation work is done
738 * The bulk of the AMC work is done before in the AMC portfolio building/training
739 ********************************************************************************/
740
741 if (doAmcRun)
742 amcRun(doClassicRun);
743 else
744 amcPortfolio_ = QuantLib::ext::make_shared<Portfolio>(inputs_->buildFailedTrades());
745
746 if (doClassicRun)
747 classicPortfolio_ = classicRun(residualPortfolio);
748 else
749 classicPortfolio_ = QuantLib::ext::make_shared<Portfolio>(inputs_->buildFailedTrades());
750
751 /***************************************************
752 * We may have two cubes now that need to be merged
753 ***************************************************/
754
755 if (doClassicRun && doAmcRun) {
756 LOG("Joining classical and AMC cube");
757 cube_ = QuantLib::ext::make_shared<JointNPVCube>(cube_, amcCube_);
758 } else if (!doClassicRun && doAmcRun) {
759 LOG("We have generated an AMC cube only");
760 cube_ = amcCube_;
761 } else {
762 WLOG("We have generated a classic cube only");
763 }
764
765 LOG("NPV cube generation completed");
766
767 /***********************************************************************
768 * We may have two non-empty portfolios to be merged for post processing
769 ***********************************************************************/
770
771 LOG("Classic portfolio size " << classicPortfolio_->size());
772 LOG("AMC portfolio size " << amcPortfolio_->size());
773 auto newPortfolio = QuantLib::ext::make_shared<Portfolio>();
774 for (const auto& [tradeId, trade] : classicPortfolio_->trades())
775 newPortfolio->add(trade);
776 for (const auto& [tradeId, trade] : amcPortfolio_->trades())
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 }
783 analytic()->setPortfolio(newPortfolio);
784 } else { // runSimulation_
785
786 // build the portfolio linked to today's market
788
789 // ... and load a pre-built cube for post-processing
790
791 LOG("Skip cube generation, load input cubes for XVA");
792 const string msg = "XVA: Load Cubes";
793 CONSOLEW(msg);
794 ProgressMessage(msg, 0, 1).log();
795 QL_REQUIRE(inputs_->cube(), "XVA without EXPOSURE requires an NPV cube as input");
796 cube_= inputs_->cube();
797 QL_REQUIRE(inputs_->mktCube(), "XVA without EXPOSURE requires a market cube as input");
798 scenarioData_.linkTo(inputs_->mktCube());
799 if (inputs_->nettingSetCube())
800 nettingSetCube_= inputs_->nettingSetCube();
801 if (inputs_->cptyCube())
802 cptyCube_ = inputs_->cptyCube();
803 CONSOLE("OK");
804 ProgressMessage(msg, 1, 1).log();
805 }
806
807 MEM_LOG;
808
809 // Return the cubes to serialalize
810 if (inputs_->writeCube()) {
811 analytic()->npvCubes()["XVA"]["cube"] = cube_;
812 analytic()->mktCubes()["XVA"]["scenariodata"] = *scenarioData_;
813 if (nettingSetCube_) {
814 analytic()->npvCubes()["XVA"]["nettingsetcube"] = nettingSetCube_;
815 }
816 if (cptyCube_) {
817 analytic()->npvCubes()["XVA"]["cptycube"] = cptyCube_;
818 }
819 }
820
821 // Generate cube reports to inspect
822 if (inputs_->rawCubeOutput()) {
823 map<string, string> nettingSetMap = analytic()->portfolio()->nettingSetMap();
824 auto report = QuantLib::ext::make_shared<InMemoryReport>();
825 ReportWriter(inputs_->reportNaString()).writeCube(*report, cube_, nettingSetMap);
826 analytic()->reports()["XVA"]["rawcube"] = report;
827 }
828
829 if (runXva_) {
830
831 /*********************************************************************
832 * This is where the aggregation work is done: call the post-processor
833 *********************************************************************/
834
835 string msg = "XVA: Aggregation";
836 CONSOLEW(msg);
837 ProgressMessage(msg, 0, 1).log();
839 CONSOLE("OK");
840 ProgressMessage(msg, 1, 1).log();
841
842 /******************************************************
843 * Finally generate various (in-memory) reports/outputs
844 ******************************************************/
845
846 msg = "XVA: Reports";
847 CONSOLEW(msg);
848 ProgressMessage(msg, 0, 1).log();
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);
856 analytic()->reports()["XVA"]["exposure_trade_" + tradeId] = report;
857 } catch (const std::exception& e) {
858 StructuredAnalyticsErrorMessage("Trade Exposure Report", "Error processing trade.", e.what(),
859 {{"tradeId", tradeId}})
860 .log();
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}})
875 .log();
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}})
886 .log();
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}})
897 .log();
898 }
899 }
900 }
901
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;
906
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;
911 }
912
913 if (inputs_->dimAnalytic() || inputs_->mvaAnalytic()) {
914 // Generate DIM evolution report
915 auto dimEvolutionReport = QuantLib::ext::make_shared<InMemoryReport>();
916 postProcess_->exportDimEvolution(*dimEvolutionReport);
917 analytic()->reports()["XVA"]["dim_evolution"] = dimEvolutionReport;
918
919 // Generate DIM regression reports
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 }
926 postProcess_->exportDimRegression(inputs_->dimOutputNettingSet(), inputs_->dimOutputGridPoints(),
927 dimRegReports);
928 }
929
930 if (inputs_->creditMigrationAnalytic()) {
931 QL_REQUIRE(
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>();
938 analytic()
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);
945 for (Size j = 0; j < postProcess_->creditMigrationPdf()[i].size(); ++j) {
946 (*rep)
947 .next()
948 .add(postProcess_->creditMigrationUpperBucketBounds()[j])
949 .add(postProcess_->creditMigrationPdf()[i][j])
950 .add(postProcess_->creditMigrationCdf()[i][j]);
951 }
952 rep->end();
953 }
954 }
955
956 CONSOLE("OK");
957 ProgressMessage(msg, 1, 1).log();
958 }
959
960 // reset that mode
961 ObservationMode::instance().setMode(inputs_->observationModel());
962 ProgressMessage("Running XVA Analytic", 1, 1).log();
963}
Analytic * analytic() const
Definition: analytic.hpp:193
QuantLib::ext::shared_ptr< InputParameters > inputs_
Definition: analytic.hpp:216
analytic_reports & reports()
Result reports.
Definition: analytic.hpp:131
analytic_npvcubes & npvCubes()
Definition: analytic.hpp:132
Configurations & configurations()
Definition: analytic.hpp:128
void setPortfolio(const QuantLib::ext::shared_ptr< ore::data::Portfolio > &portfolio)
Definition: analytic.hpp:125
virtual void buildMarket(const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &loader, const bool marketRequired=true)
Definition: analytic.cpp:178
const QuantLib::ext::shared_ptr< ore::data::Portfolio > & portfolio() const
Definition: analytic.hpp:122
analytic_mktcubes & mktCubes()
Definition: analytic.hpp:133
virtual void buildPortfolio()
Definition: analytic.cpp:222
QuantLib::ext::shared_ptr< NPVCube > amcCube_
Definition: xvaanalytic.hpp:78
QuantLib::ext::shared_ptr< CubeInterpretation > cubeInterpreter_
Definition: xvaanalytic.hpp:80
void amcRun(bool doClassicRun)
QuantLib::ext::shared_ptr< ScenarioSimMarket > simMarket_
Definition: xvaanalytic.hpp:71
QuantLib::ext::shared_ptr< ScenarioGenerator > scenarioGenerator_
Definition: xvaanalytic.hpp:76
QuantLib::RelinkableHandle< AggregationScenarioData > scenarioData_
Definition: xvaanalytic.hpp:79
QuantLib::ext::shared_ptr< DateGrid > grid_
Definition: xvaanalytic.hpp:86
QuantLib::ext::shared_ptr< Portfolio > amcPortfolio_
Definition: xvaanalytic.hpp:77
void buildScenarioGenerator(bool continueOnError)
QuantLib::ext::shared_ptr< NPVCube > cptyCube_
Definition: xvaanalytic.hpp:78
QuantLib::ext::shared_ptr< Portfolio > classicRun(const QuantLib::ext::shared_ptr< Portfolio > &portfolio)
QuantLib::ext::shared_ptr< PostProcess > postProcess_
Definition: xvaanalytic.hpp:82
QuantLib::ext::shared_ptr< Portfolio > classicPortfolio_
Definition: xvaanalytic.hpp:77
QuantLib::ext::shared_ptr< NPVCube > cube_
Definition: xvaanalytic.hpp:78
QuantLib::ext::shared_ptr< NPVCube > nettingSetCube_
Definition: xvaanalytic.hpp:78
bool parseBool(const string &s)
#define MEM_LOG
#define LOG(text)
#define ALOG(text)
#define CONSOLEW(text)
#define WLOG(text)
#define CONSOLE(text)
RandomVariable log(RandomVariable x)
Size size(const ValueType &v)
QuantLib::ext::shared_ptr< ore::analytics::ScenarioGeneratorData > scenarioGeneratorData
Definition: analytic.hpp:71
+ Here is the call graph for this function:

◆ setUpConfigurations()

void setUpConfigurations ( )
overridevirtual

Reimplemented from Analytic::Impl.

Definition at line 49 of file xvaanalytic.cpp.

49 {
50 LOG("XvaAnalytic::setUpConfigurations() called");
51 analytic()->configurations().todaysMarketParams = inputs_->todaysMarketParams();
52 analytic()->configurations().simMarketParams = inputs_->exposureSimMarketParams();
53 analytic()->configurations().scenarioGeneratorData = inputs_->scenarioGeneratorData();
54 analytic()->configurations().crossAssetModelData = inputs_->crossAssetModelData();
55}
QuantLib::ext::shared_ptr< ore::analytics::CrossAssetModelData > crossAssetModelData
Definition: analytic.hpp:72
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:

◆ checkConfigurations()

void checkConfigurations ( const QuantLib::ext::shared_ptr< Portfolio > &  portfolio)

Definition at line 57 of file xvaanalytic.cpp.

57 {
58 //find the unique nettingset keys in portfolio
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);
63 //unique nettingset keys
64 sort(nettingSetKeys.begin(), nettingSetKeys.end());
65 nettingSetKeys.erase(unique( nettingSetKeys.begin(), nettingSetKeys.end() ), nettingSetKeys.end());
66 //controls on calcType and grid type, if netting-set has an active CSA in place
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);
74 }
75 else{
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);
78 }
79 if (analytic()->configurations().scenarioGeneratorData->withCloseOutLag() && analytic()->configurations().scenarioGeneratorData->closeOutLag() != 0*Days){
80 Period mpor_simulation = analytic()->configurations().scenarioGeneratorData->closeOutLag();
81 Period mpor_netting = inputs_->nettingSetManager()->get(key)->csaDetails()->marginPeriodOfRisk();
82 if (mpor_simulation != mpor_netting)
83 StructuredAnalyticsWarningMessage(
84 "XvaAnalytic", "Inconsistent MPoR period",
85 "For netting set " + key + ", close-out lag is not consistent with the netting-set's mpor ")
86 .log();
87 }
88 }
89 }
90}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ engineFactory()

QuantLib::ext::shared_ptr< EngineFactory > engineFactory ( )
overrideprotectedvirtual

build an engine factory

Reimplemented from Analytic::Impl.

Definition at line 92 of file xvaanalytic.cpp.

92 {
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");
101 //configurations[MarketContext::simulation] = inputs_->marketConfig("simulation");
102 std::vector<QuantLib::ext::shared_ptr<EngineBuilder>> extraEngineBuilders;
103 std::vector<QuantLib::ext::shared_ptr<LegBuilder>> extraLegBuilders;
104
105 if (runSimulation_) {
106 // link to the sim market here
107 QL_REQUIRE(simMarket_, "Simulaton market not set");
108 engineFactory_ = QuantLib::ext::make_shared<EngineFactory>(edCopy, simMarket_, configurations,
109 inputs_->refDataManager(), *inputs_->iborFallbackConfig());
110 } else {
111 // we just link to today's market if simulation is not required
112 engineFactory_ = QuantLib::ext::make_shared<EngineFactory>(edCopy, analytic()->market(), configurations, inputs_->refDataManager(),
113 *inputs_->iborFallbackConfig());
114 }
115 return engineFactory_;
116}
QuantLib::ext::shared_ptr< EngineFactory > engineFactory_
Definition: xvaanalytic.hpp:74
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildScenarioSimMarket()

void buildScenarioSimMarket ( )
protected

Definition at line 119 of file xvaanalytic.cpp.

119 {
120
121 std::string configuration = inputs_->marketConfig("simulation");
122 simMarket_ = QuantLib::ext::make_shared<ScenarioSimMarket>(
123 analytic()->market(),
124 analytic()->configurations().simMarketParams,
125 QuantLib::ext::make_shared<FixingManager>(inputs_->asof()),
126 configuration,
127 *inputs_->curveConfigs().get(),
128 *analytic()->configurations().todaysMarketParams,
129 inputs_->continueOnError(),
130 false, true, false,
131 *inputs_->iborFallbackConfig(),
132 false, offsetScenario_);
133
134 if(offsetScenario_ == nullptr){
137 } else{
138 // set useSpreadedTermstructure to true, yield better results in calibration of the CAM
139 simMarketCalibration_ = QuantLib::ext::make_shared<ScenarioSimMarket>(
140 analytic()->market(), analytic()->configurations().simMarketParams,
141 QuantLib::ext::make_shared<FixingManager>(inputs_->asof()), configuration, *inputs_->curveConfigs().get(),
142 *analytic()->configurations().todaysMarketParams, inputs_->continueOnError(), true, true, false,
143 *inputs_->iborFallbackConfig(), false, offsetScenario_);
144
145 // Create a third market used for AMC and Postprocessor, holds a larger simmarket, e.g. default curves
146 offsetSimMarket_ = QuantLib::ext::make_shared<ScenarioSimMarket>(
147 analytic()->market(), offsetSimMarketParams_, QuantLib::ext::make_shared<FixingManager>(inputs_->asof()),
148 configuration, *inputs_->curveConfigs().get(), *analytic()->configurations().todaysMarketParams,
149 inputs_->continueOnError(), true, true, false, *inputs_->iborFallbackConfig(), false, offsetScenario_);
150
151 TLOG("XvaAnalytic: Offset Scenario used in building SimMarket");
152 TLOG("XvaAnalytic: Offset scenario is absolute = " << offsetScenario_->isAbsolute());
153 TLOG("RfKey,OffsetScenarioValue");
154 for (const auto& key : offsetScenario_->keys()) {
155 TLOG(key << " : " << offsetScenario_->get(key));
156 }
157 }
158
159 TLOG("XvaAnalytic:Finished building Scenario SimMarket");
160 TLOG("RfKey,BaseScenarioValue,BaseScenarioAbsValue");
161 for (const auto& key : simMarket_->baseScenario()->keys()) {
162 TLOG(key << "," << simMarket_->baseScenario()->get(key) << "," << simMarket_->baseScenarioAbsolute()->get(key));
163 }
164 TLOG("XvaAnalytic: Finished building Scenario SimMarket for model calibration (useSpreadedTermStructure)");
165 TLOG("RfKey,BaseScenarioValue,BaseScenarioAbsValue");
166 for (const auto& key : simMarketCalibration_->baseScenario()->keys()) {
167 TLOG(key << "," << simMarketCalibration_->baseScenario()->get(key) << ","
168 << simMarketCalibration_->baseScenarioAbsolute()->get(key));
169 }
170}
QuantLib::ext::shared_ptr< ScenarioSimMarket > simMarketCalibration_
Definition: xvaanalytic.hpp:72
QuantLib::ext::shared_ptr< ScenarioSimMarket > offsetSimMarket_
Definition: xvaanalytic.hpp:73
#define TLOG(text)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildCrossAssetModel()

void buildCrossAssetModel ( bool  continueOnError)
protected

Definition at line 195 of file xvaanalytic.cpp.

195 {
196 LOG("XVA: Build Simulation Model (continueOnCalibrationError = "
197 << std::boolalpha << continueOnCalibrationError << ")");
198 ext::shared_ptr<Market> market = offsetScenario_ != nullptr ? simMarketCalibration_ : analytic()->market();
199 QL_REQUIRE(market != nullptr, "Internal error, buildCrossAssetModel needs to be called after the market is built.");
200 CrossAssetModelBuilder modelBuilder(
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,
206 "xva cam building");
207 model_ = *modelBuilder.model();
208}
const QuantLib::ext::shared_ptr< ore::data::Market > & market() const
Definition: analytic.hpp:117
QuantLib::ext::shared_ptr< CrossAssetModel > model_
Definition: xvaanalytic.hpp:75
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildScenarioGenerator()

void buildScenarioGenerator ( bool  continueOnError)
protected

Definition at line 172 of file xvaanalytic.cpp.

172 {
173 if (!model_)
174 buildCrossAssetModel(continueOnCalibrationError);
175 ScenarioGeneratorBuilder sgb(analytic()->configurations().scenarioGeneratorData);
176 QuantLib::ext::shared_ptr<ScenarioFactory> sf = QuantLib::ext::make_shared<SimpleScenarioFactory>(true);
177 string config = inputs_->marketConfig("simulation");
178 auto market = offsetScenario_ == nullptr ? analytic()->market() : simMarketCalibration_;
179 scenarioGenerator_ = sgb.build(model_, sf, analytic()->configurations().simMarketParams, inputs_->asof(), market, config);
180 QL_REQUIRE(scenarioGenerator_, "failed to build the scenario generator");
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()));
187
188 if (inputs_->writeScenarios()) {
189 auto report = QuantLib::ext::make_shared<InMemoryReport>();
190 analytic()->reports()["XVA"]["scenario"] = report;
191 scenarioGenerator_ = QuantLib::ext::make_shared<ScenarioWriter>(scenarioGenerator_, report);
192 }
193}
void buildCrossAssetModel(bool continueOnError)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ initCubeDepth()

void initCubeDepth ( )
protected

Definition at line 210 of file xvaanalytic.cpp.

210 {
211 if (cubeDepth_ == 0) {
212 LOG("XVA: Set cube depth");
213 cubeDepth_ = cubeInterpreter_->requiredNpvCubeDepth();
214 LOG("XVA: Cube depth set to: " << cubeDepth_);
215 }
216}
+ Here is the caller graph for this function:

◆ initCube()

void initCube ( QuantLib::ext::shared_ptr< NPVCube > &  cube,
const std::set< std::string > &  ids,
Size  cubeDepth 
)
protected

Definition at line 218 of file xvaanalytic.cpp.

218 {
219
220 LOG("Init cube with depth " << cubeDepth);
221
222 for (Size i = 0; i < grid_->valuationDates().size(); ++i)
223 DLOG("initCube: grid[" << i << "]=" << io::iso_date(grid_->valuationDates()[i]));
224
225 if (cubeDepth == 1)
226 cube = QuantLib::ext::make_shared<SinglePrecisionInMemoryCube>(inputs_->asof(),
227 ids, grid_->valuationDates(), samples_, 0.0f);
228 else
229 cube = QuantLib::ext::make_shared<SinglePrecisionInMemoryCubeN>(inputs_->asof(),
230 ids, grid_->valuationDates(), samples_, cubeDepth, 0.0f);
231}
#define DLOG(text)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ initClassicRun()

void initClassicRun ( const QuantLib::ext::shared_ptr< Portfolio > &  portfolio)
protected

Definition at line 234 of file xvaanalytic.cpp.

234 {
235
236 LOG("XVA: initClassicRun");
237
239
240 // May have been set already
241 if (scenarioData_.empty()) {
242 LOG("XVA: Create asd " << grid_->valuationDates().size() << " x " << samples_);
243 scenarioData_.linkTo(
244 QuantLib::ext::make_shared<InMemoryAggregationScenarioData>(grid_->valuationDates().size(), samples_));
245 simMarket_->aggregationScenarioData() = *scenarioData_;
246
247 }
248
249 // We can skip the cube initialization if the mt val engine is used, since it builds its own cubes
250 if (inputs_->nThreads() == 1) {
251 if (portfolio->size() > 0)
252 initCube(cube_, portfolio->ids(), cubeDepth_);
253 // not required by any calculators in ore at the moment
254 nettingSetCube_ = nullptr;
255 // Init counterparty cube for the storage of survival probabilities
256 if (inputs_->storeSurvivalProbabilities()) {
257 // Use full list of counterparties, not just those in the sub-portflio
258 auto counterparties = inputs_->portfolio()->counterparties();
259 counterparties.insert(inputs_->dvaName());
260 initCube(cptyCube_, counterparties, 1);
261 } else {
262 cptyCube_ = nullptr;
263 }
264 }
265
266 LOG("XVA: initClassicRun completed");
267}
void initCube(QuantLib::ext::shared_ptr< NPVCube > &cube, const std::set< std::string > &ids, Size cubeDepth)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildClassicCube()

void buildClassicCube ( const QuantLib::ext::shared_ptr< Portfolio > &  portfolio)
protected

Definition at line 308 of file xvaanalytic.cpp.

308 {
309
310 LOG("XVA::buildCube");
311
312 // set up valuation calculator factory
313 auto calculators = [this]() {
314 vector<QuantLib::ext::shared_ptr<ValuationCalculator>> calculators;
315 if (analytic()->configurations().scenarioGeneratorData->withCloseOutLag()) {
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(),
319 cubeInterpreter_->closeOutDateNpvIndex()));
320 } else
321 calculators.push_back(QuantLib::ext::make_shared<NPVCalculator>(inputs_->exposureBaseCurrency()));
322 if (inputs_->storeFlows())
323 calculators.push_back(QuantLib::ext::make_shared<CashflowCalculator>(
324 inputs_->exposureBaseCurrency(), inputs_->asof(), grid_, cubeInterpreter_->mporFlowsIndex()));
325 if(inputs_->storeCreditStateNPVs() > 0) {
326 calculators.push_back(QuantLib::ext::make_shared<MultiStateNPVCalculator>(inputs_->exposureBaseCurrency(),
327 cubeInterpreter_->creditStateNPVsIndex(),
328 inputs_->storeCreditStateNPVs()));
329 }
330 return calculators;
331 };
332
333 // set up cpty calculator factory
334
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));
340 }
341 return cptyCalculators;
342 };
343
344 // log message
345
346 ostringstream o;
347 o << "XVA: Build Cube " << portfolio->size() << " x " << grid_->valuationDates().size() << " x " << samples_;
348 CONSOLEW(o.str());
349 LOG(o.str());
350
351 // set up progress indicators
352
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);
355
356 if(inputs_->nThreads() == 1) {
357
358 // single-threaded engine run
359
360 ValuationEngine engine(inputs_->asof(), grid_, simMarket_);
361 engine.registerProgressIndicator(progressBar);
362 engine.registerProgressIndicator(progressLog);
363 engine.buildCube(portfolio, cube_, calculators(), analytic()->configurations().scenarioGeneratorData->withMporStickyDate(),
364 nettingSetCube_, cptyCube_, cptyCalculators());
365 } else {
366
367 // multi-threaded engine run
368
369 /* TODO we assume no netting output cube is needed. Currently there are no valuation calculators in ore that require this cube. */
370
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> {
374 if (cubeDepth_ == 1)
375 return QuantLib::ext::make_shared<SinglePrecisionInMemoryCube>(asof, ids, dates, samples, 0.0f);
376 else
377 return QuantLib::ext::make_shared<SinglePrecisionInMemoryCubeN>(asof, ids, dates, samples,
378 cubeDepth_, 0.0f);
379 };
380
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)>
384 cptyCubeFactory;
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);
390 };
391 } else {
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; };
395 }
396
397 MultiThreadedValuationEngine engine(
398 inputs_->nThreads(), inputs_->asof(), grid_, samples_, analytic()->loader(), scenarioGenerator_,
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, {},
403 cptyCubeFactory, "xva-simulation", offsetScenario_);
404
405 engine.setAggregationScenarioData(*scenarioData_);
406 engine.registerProgressIndicator(progressBar);
407 engine.registerProgressIndicator(progressLog);
408
409 engine.buildCube(portfolio, calculators, cptyCalculators,
410 analytic()->configurations().scenarioGeneratorData->withMporStickyDate());
411
412 cube_ = QuantLib::ext::make_shared<JointNPVCube>(engine.outputCubes(), portfolio->ids());
413
414 if (inputs_->storeSurvivalProbabilities())
415 cptyCube_ = QuantLib::ext::make_shared<JointNPVCube>(
416 engine.outputCptyCubes(), portfolio->counterparties(), false,
417 [](Real a, Real x) { return std::max(a, x); }, 0.0);
418 }
419
420 CONSOLE("OK");
421
422 LOG("XVA::buildCube done");
423
424 Settings::instance().evaluationDate() = inputs_->asof();
425}
Date asof(14, Jun, 2018)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ classicRun()

QuantLib::ext::shared_ptr< Portfolio > classicRun ( const QuantLib::ext::shared_ptr< Portfolio > &  portfolio)
protected

Definition at line 270 of file xvaanalytic.cpp.

270 {
271 LOG("XVA: classicRun");
272
273
274 Size n = portfolio->size();
275 // Create a new empty portfolio, fill it and link it to the simulation market
276 // We don't use Analytic::buildPortfolio() here because we are possibly dealing with a sub-portfolio only.
277 LOG("XVA: Build classic portfolio of size " << n << " linked to the simulation market");
278 const string msg = "XVA: Build Portfolio";
279 CONSOLEW(msg);
280 ProgressMessage(msg, 0, 1).log();
281 classicPortfolio_ = QuantLib::ext::make_shared<Portfolio>(inputs_->buildFailedTrades());
282 portfolio->reset();
283 for (const auto& [tradeId, trade] : portfolio->trades())
284 classicPortfolio_->add(trade);
285 QL_REQUIRE(analytic()->market(), "today's market not set");
286 QuantLib::ext::shared_ptr<EngineFactory> factory = engineFactory();
287 classicPortfolio_->build(factory, "analytic/" + label());
288 Date maturityDate = inputs_->asof();
289 if (inputs_->portfolioFilterDate() != Null<Date>())
290 maturityDate = inputs_->portfolioFilterDate();
291 LOG("Filter trades that expire before " << maturityDate);
292 classicPortfolio_->removeMatured(maturityDate);
293 CONSOLE("OK");
294 ProgressMessage(msg, 1, 1).log();
295
296 // Allocate cubes for the sub-portfolio we are processing here
298
299 // This is where the valuation work is done
301
302 LOG("XVA: classicRun completed");
303
304 return classicPortfolio_;
305}
const std::string & label() const
Definition: analytic.hpp:190
void buildClassicCube(const QuantLib::ext::shared_ptr< Portfolio > &portfolio)
void initClassicRun(const QuantLib::ext::shared_ptr< Portfolio > &portfolio)
QuantLib::ext::shared_ptr< ore::data::EngineFactory > engineFactory() override
build an engine factory
Definition: xvaanalytic.cpp:92
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ amcEngineFactory()

QuantLib::ext::shared_ptr< EngineFactory > amcEngineFactory ( const QuantLib::ext::shared_ptr< QuantExt::CrossAssetModel > &  cam,
const std::vector< Date > &  grid 
)
protected

Definition at line 428 of file xvaanalytic.cpp.

429 {
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);
443 return factory;
444}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildAmcPortfolio()

void buildAmcPortfolio ( )
protected

Definition at line 446 of file xvaanalytic.cpp.

446 {
447 LOG("XVA: buildAmcPortfolio");
448 const string msg = "XVA: Build AMC portfolio";
449 CONSOLEW(msg);
450 ProgressMessage(msg, 0, 1).log();
451
452 LOG("buildAmcPortfolio: Check sim dates");
453 std::vector<Date> simDates =
454 analytic()->configurations().scenarioGeneratorData->withCloseOutLag() && !analytic()->configurations().scenarioGeneratorData->withMporStickyDate() ?
455 analytic()->configurations().scenarioGeneratorData->getGrid()->dates() : analytic()->configurations().scenarioGeneratorData->getGrid()->valuationDates();
456
457 LOG("buildAmcPortfolio: Register additional engine builders");
458 auto factory = amcEngineFactory(model_, simDates);
459
460 LOG("buildAmcPortfolio: Load Portfolio");
461 QuantLib::ext::shared_ptr<Portfolio> portfolio = inputs_->portfolio();
462
463 LOG("Build Portfolio with AMC Engine factory and select amc-enabled trades")
464 amcPortfolio_ = QuantLib::ext::make_shared<Portfolio>();
465 for (auto const& [tradeId, trade] : portfolio->trades()) {
466 if (inputs_->amcTradeTypes().find(trade->tradeType()) != inputs_->amcTradeTypes().end()) {
467 try {
468 trade->reset();
469 trade->build(factory);
470 amcPortfolio_->add(trade);
471 DLOG("trade " << tradeId << " is added to amc portfolio");
472 } catch (const std::exception& e) {
473 StructuredTradeErrorMessage(trade, "Error building trade for AMC simulation", e.what()).log();
474 }
475 }
476 }
477 LOG("AMC portfolio built, size is " << amcPortfolio_->size());
478
479 CONSOLE("OK");
480 ProgressMessage(msg, 1, 1).log();
481
482 LOG("XVA: buildAmcPortfolio completed");
483}
QuantLib::ext::shared_ptr< EngineFactory > amcEngineFactory(const QuantLib::ext::shared_ptr< QuantExt::CrossAssetModel > &cam, const std::vector< Date > &grid)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ amcRun()

void amcRun ( bool  doClassicRun)
protected

Definition at line 485 of file xvaanalytic.cpp.

485 {
486
487 LOG("XVA: amcRun");
488
489 if (scenarioData_.empty()) {
490 LOG("XVA: Create asd " << grid_->valuationDates().size() << " x " << samples_);
491 scenarioData_.linkTo(
492 QuantLib::ext::make_shared<InMemoryAggregationScenarioData>(grid_->valuationDates().size(), samples_));
493 simMarket_->aggregationScenarioData() = *scenarioData_;
494 }
495
497
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);
502
503 if (inputs_->nThreads() == 1) {
505 ext::shared_ptr<ore::data::Market> market = offsetScenario_ == nullptr ? analytic()->market() : offsetSimMarket_;
506
507 AMCValuationEngine amcEngine(model_, inputs_->scenarioGeneratorData(), market,
508 inputs_->exposureSimMarketParams()->additionalScenarioDataIndices(),
509 inputs_->exposureSimMarketParams()->additionalScenarioDataCcys(),
510 inputs_->exposureSimMarketParams()->additionalScenarioDataNumberOfCreditStates());
511 amcEngine.registerProgressIndicator(progressBar);
512 amcEngine.registerProgressIndicator(progressLog);
513 if (!scenarioData_.empty())
514 amcEngine.aggregationScenarioData() = *scenarioData_;
515 amcEngine.buildCube(amcPortfolio_, amcCube_);
516 } else {
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> {
520 if (cubeDepth_ == 1)
521 return QuantLib::ext::make_shared<SinglePrecisionInMemoryCube>(asof, ids, dates, samples, 0.0f);
522 else
523 return QuantLib::ext::make_shared<SinglePrecisionInMemoryCubeN>(asof, ids, dates, samples,
524 cubeDepth_, 0.0f);
525 };
526
527 auto simMarketParams =
529
530 AMCValuationEngine amcEngine(
531 inputs_->nThreads(), inputs_->asof(), samples_, analytic()->loader(), inputs_->scenarioGeneratorData(),
532 inputs_->exposureSimMarketParams()->additionalScenarioDataIndices(),
533 inputs_->exposureSimMarketParams()->additionalScenarioDataCcys(),
534 inputs_->exposureSimMarketParams()->additionalScenarioDataNumberOfCreditStates(),
535 inputs_->crossAssetModelData(), inputs_->amcPricingEngine(), inputs_->curveConfigs().get(),
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,
540 cubeFactory, offsetScenario_, simMarketParams);
541
542 amcEngine.registerProgressIndicator(progressBar);
543 amcEngine.registerProgressIndicator(progressLog);
544 if (!scenarioData_.empty())
545 amcEngine.aggregationScenarioData() = *scenarioData_;
546 amcEngine.buildCube(amcPortfolio_);
547 amcCube_ = QuantLib::ext::make_shared<JointNPVCube>(amcEngine.outputCubes());
548 }
549
550 CONSOLE("OK");
551
552 LOG("XVA: amcRun completed");
553}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ runPostProcessor()

void runPostProcessor ( )
protected

Definition at line 555 of file xvaanalytic.cpp.

555 {
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();
572
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();
581
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();
588
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();
597
598 string marketConfiguration = inputs_->marketConfig("simulation");
599
600 bool fullInitialCollateralisation = inputs_->fullInitialCollateralisation();
601
602 checkConfigurations(analytic()->portfolio());
603
604 if (!dimCalculator_ && (analytics["mva"] || analytics["dim"])) {
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
612 ? 1.0
613 : analytic()
614 ->market()
615 ->fxRate(b->currency() + baseCurrency, marketConfiguration)
616 ->value());
617 }
618 }
619 dimCalculator_ = QuantLib::ext::make_shared<RegressionDynamicInitialMarginCalculator>(
620 inputs_, analytic()->portfolio(), cube_, cubeInterpreter_, *scenarioData_, dimQuantile,
621 dimHorizonCalendarDays, dimRegressionOrder, dimRegressors, dimLocalRegressionEvaluations,
622 dimLocalRegressionBandwidth, currentIM);
623 } else {
624 LOG("dim calculator not set, create FlatDynamicInitialMarginCalculator");
625 dimCalculator_ = QuantLib::ext::make_shared<FlatDynamicInitialMarginCalculator>(
627 }
628 }
629
630 std::vector<Period> cvaSensiGrid = inputs_->cvaSensiGrid();
631 Real cvaSensiShiftSize = inputs_->cvaSensiShiftSize();
632
633 string flipViewBorrowingCurvePostfix = inputs_->flipViewBorrowingCurvePostfix();
634 string flipViewLendingCurvePostfix = inputs_->flipViewLendingCurvePostfix();
635
636 LOG("baseCurrency " << baseCurrency);
637
638 auto market = offsetScenario_ == nullptr ? analytic()->market() : offsetSimMarket_;
639
640 postProcess_ = QuantLib::ext::make_shared<PostProcess>(
641 analytic()->portfolio(), netting, balances, market, marketConfiguration, cube_, *scenarioData_, analytics,
642 baseCurrency, allocationMethod, marginalAllocationLimit, quantile, calculationType, dvaName, fvaBorrowingCurve,
643 fvaLendingCurve, dimCalculator_, cubeInterpreter_, fullInitialCollateralisation, cvaSensiGrid,
644 cvaSensiShiftSize, kvaCapitalDiscountRate, kvaAlpha, kvaRegAdjustment, kvaCapitalHurdle, kvaOurPdFloor,
645 kvaTheirPdFloor, kvaOurCvaRiskWeight, kvaTheirCvaRiskWeight, cptyCube_, flipViewBorrowingCurvePostfix,
646 flipViewLendingCurvePostfix, inputs_->creditSimulationParameters(), inputs_->creditMigrationDistributionGrid(),
647 inputs_->creditMigrationTimeSteps(), creditStateCorrelationMatrix(),
648 analytic()->configurations().scenarioGeneratorData->withMporStickyDate(), inputs_->mporCashFlowMode());
649 LOG("post done");
650}
void checkConfigurations(const QuantLib::ext::shared_ptr< Portfolio > &portfolio)
Definition: xvaanalytic.cpp:57
QuantLib::ext::shared_ptr< DynamicInitialMarginCalculator > dimCalculator_
Definition: xvaanalytic.hpp:81
Matrix creditStateCorrelationMatrix() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ creditStateCorrelationMatrix()

Matrix creditStateCorrelationMatrix ( ) const
protected

Definition at line 965 of file xvaanalytic.cpp.

965 {
966
968 for (auto const& [pair, value] : analytic()->configurations().crossAssetModelData->correlations()) {
969 cmb.addCorrelation(pair.first, pair.second, value);
970 }
971
973 processInfo[CrossAssetModel::AssetType::CrState] = {
974 {"CrState", analytic()->configurations().simMarketParams->numberOfCreditStates()}};
975
976 return cmb.correlationMatrix(processInfo);
977}
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ LABEL

constexpr const char* LABEL = "XVA"
staticconstexpr

Definition at line 32 of file xvaanalytic.hpp.

◆ simMarket_

QuantLib::ext::shared_ptr<ScenarioSimMarket> simMarket_
protected

Definition at line 71 of file xvaanalytic.hpp.

◆ simMarketCalibration_

QuantLib::ext::shared_ptr<ScenarioSimMarket> simMarketCalibration_
protected

Definition at line 72 of file xvaanalytic.hpp.

◆ offsetSimMarket_

QuantLib::ext::shared_ptr<ScenarioSimMarket> offsetSimMarket_
protected

Definition at line 73 of file xvaanalytic.hpp.

◆ engineFactory_

QuantLib::ext::shared_ptr<EngineFactory> engineFactory_
protected

Definition at line 74 of file xvaanalytic.hpp.

◆ model_

QuantLib::ext::shared_ptr<CrossAssetModel> model_
protected

Definition at line 75 of file xvaanalytic.hpp.

◆ scenarioGenerator_

QuantLib::ext::shared_ptr<ScenarioGenerator> scenarioGenerator_
protected

Definition at line 76 of file xvaanalytic.hpp.

◆ amcPortfolio_

QuantLib::ext::shared_ptr<Portfolio> amcPortfolio_
protected

Definition at line 77 of file xvaanalytic.hpp.

◆ classicPortfolio_

QuantLib::ext::shared_ptr<Portfolio> classicPortfolio_
protected

Definition at line 77 of file xvaanalytic.hpp.

◆ cube_

QuantLib::ext::shared_ptr<NPVCube> cube_
protected

Definition at line 78 of file xvaanalytic.hpp.

◆ nettingSetCube_

QuantLib::ext::shared_ptr<NPVCube> nettingSetCube_
protected

Definition at line 78 of file xvaanalytic.hpp.

◆ cptyCube_

QuantLib::ext::shared_ptr<NPVCube> cptyCube_
protected

Definition at line 78 of file xvaanalytic.hpp.

◆ amcCube_

QuantLib::ext::shared_ptr<NPVCube> amcCube_
protected

Definition at line 78 of file xvaanalytic.hpp.

◆ scenarioData_

QuantLib::RelinkableHandle<AggregationScenarioData> scenarioData_
protected

Definition at line 79 of file xvaanalytic.hpp.

◆ cubeInterpreter_

QuantLib::ext::shared_ptr<CubeInterpretation> cubeInterpreter_
protected

Definition at line 80 of file xvaanalytic.hpp.

◆ dimCalculator_

QuantLib::ext::shared_ptr<DynamicInitialMarginCalculator> dimCalculator_
protected

Definition at line 81 of file xvaanalytic.hpp.

◆ postProcess_

QuantLib::ext::shared_ptr<PostProcess> postProcess_
protected

Definition at line 82 of file xvaanalytic.hpp.

◆ offsetScenario_

QuantLib::ext::shared_ptr<Scenario> offsetScenario_
protected

Definition at line 83 of file xvaanalytic.hpp.

◆ offsetSimMarketParams_

QuantLib::ext::shared_ptr<ScenarioSimMarketParameters> offsetSimMarketParams_
protected

Definition at line 84 of file xvaanalytic.hpp.

◆ cubeDepth_

Size cubeDepth_ = 0
protected

Definition at line 85 of file xvaanalytic.hpp.

◆ grid_

QuantLib::ext::shared_ptr<DateGrid> grid_
protected

Definition at line 86 of file xvaanalytic.hpp.

◆ samples_

Size samples_ = 0
protected

Definition at line 87 of file xvaanalytic.hpp.

◆ runSimulation_

bool runSimulation_ = false
protected

Definition at line 89 of file xvaanalytic.hpp.

◆ runXva_

bool runXva_ = false
protected

Definition at line 90 of file xvaanalytic.hpp.