32std::vector<RiskFactorKey>
35 std::map<RiskFactorKey, std::set<RiskFactorKey>> parToZeroEdges;
36 std::map<RiskFactorKey, std::set<RiskFactorKey>> zeroToParEdges;
37 std::vector<RiskFactorKey> orderedKeys;
38 std::map<RiskFactorKey, size_t> order;
39 std::map<RiskFactorKey, std::set<RiskFactorKey>> dependencies;
40 for (
const auto& [key, value] : parWithRespectToZero) {
41 const auto& [parKey, zeroKey] = key;
42 if (order.count(parKey) == 0) {
45 if (!QuantLib::close_enough(value, 0.0)) {
46 parToZeroEdges[parKey].insert(zeroKey);
47 if (zeroKey != parKey) {
48 order[parKey] = order[parKey] + 1;
49 dependencies[zeroKey].insert(parKey);
54 std::queue<RiskFactorKey> zeroOrderParKeys;
55 for (
const auto& [key, n] : order) {
57 zeroOrderParKeys.push(key);
61 while (!zeroOrderParKeys.empty()) {
62 auto key = zeroOrderParKeys.front();
63 zeroOrderParKeys.pop();
64 orderedKeys.push_back(key);
65 for (
const auto& dependentKey : dependencies[key]) {
66 order[dependentKey] -= 1;
67 if (order[dependentKey] == 0) {
68 zeroOrderParKeys.push(dependentKey);
78 const QuantLib::Date&
asof, QuantLib::ext::shared_ptr<ore::data::TodaysMarketParameters>& todaysMarketParams,
79 const QuantLib::ext::shared_ptr<ore::analytics::ScenarioSimMarketParameters>& simMarketParams,
80 const QuantLib::ext::shared_ptr<ore::analytics::SensitivityScenarioData>& sensiScenarioData,
81 const QuantLib::ext::shared_ptr<ore::data::CurveConfigurations>& curveConfigs,
82 const QuantLib::ext::shared_ptr<ore::data::Market>& todaysMarket,
83 const QuantLib::ext::shared_ptr<ore::data::IborFallbackConfig>& iborFallbackConfig)
84 : asof_(
asof), todaysMarketParams_(todaysMarketParams), simMarketParams_(simMarketParams),
85 sensiScenarioData_(sensiScenarioData), curveConfigs_(
curveConfigs), todaysMarket_(todaysMarket),
86 iborFallbackConfig_(iborFallbackConfig) {}
89 const QuantLib::ext::shared_ptr<ore::analytics::StressTestScenarioData>& stressTestData)
const {
91 if (!stressTestData->hasScenarioWithParShifts()) {
92 LOG(
"ParStressConverter: No scenario with par shifts found, use it as is");
93 return stressTestData;
95 QuantLib::ext::shared_ptr<StressTestScenarioData> results = QuantLib::ext::make_shared<StressTestScenarioData>();
96 results->useSpreadedTermStructures() = stressTestData->useSpreadedTermStructures();
99 std::set<RiskFactorKey::KeyType> disabledRiskFactors{
103 auto disabled =
disabledParRates(stressTestData->withIrCurveParShifts(), stressTestData->withIrCapFloorParShifts(),
104 stressTestData->withCreditCurveParShifts());
105 disabledRiskFactors.insert(disabled.begin(), disabled.end());
107 DLOG(
"ParStressConverter: The following risk factors will be not converted:")
108 for (
const auto& keyType : disabledRiskFactors) {
111 LOG(
"ParStressConverter: Compute Par Sensitivities")
114 LOG(
"ParStressConverter: Build dependency graph of par instruments")
115 auto dependencyGraph = sortParRiskFactorByDependency(parAnalysis->parSensitivities());
117 parAnalysis->parInstruments(), stressTestData->useSpreadedTermStructures());
119 for (
const auto& scenario : stressTestData->data()) {
120 DLOG(
"ParStressConverter: Scenario" << scenario.label);
121 if (scenario.containsParShifts()) {
123 LOG(
"ParStressConverter: Scenario " << scenario.label <<
" Convert par shifts to zero shifts");
125 results->data().push_back(std::move(convertedScenario));
126 }
catch (
const std::exception& e) {
128 "Skip Scenario " + scenario.label +
", got :" + e.what())
132 LOG(
"ParStressConverter: Skip scenario " << scenario.label <<
", it contains only zero shifts");
133 results->data().push_back(scenario);
141std::pair<QuantLib::ext::shared_ptr<ScenarioSimMarket>, QuantLib::ext::shared_ptr<ParSensitivityAnalysis>>
143 QL_REQUIRE(
simMarketParams_ !=
nullptr,
"computeParSensitivity: simMarketData required to compute par sensitivity before "
144 "converting par to zero stress test shifts");
146 "computeParSensitivity: sensiScenarioData required to compute par sensitivity before "
147 "converting par to zero stress test shifts");
150 QL_REQUIRE(parAnalysis !=
nullptr,
"ParStressConverter: failed to generate parAnalysis");
151 LOG(
"ParStressConverter: Allign Pillars for par sensitivity analysis");
152 parAnalysis->alignPillars();
155 LOG(
"ParStressConverter: Allign CapFloor strikes and adjust optionletPillars");
161 LOG(
"ParStressConverter: Build SimMarket");
162 auto simMarket = QuantLib::ext::make_shared<ScenarioSimMarket>(
167 LOG(
"ParStressConverter: Build ScenarioGenerator");
168 auto scnearioFactory = QuantLib::ext::make_shared<ore::analytics::DeltaScenarioFactory>(simMarket->baseScenario());
169 auto scenarioGenerator = QuantLib::ext::make_shared<SensitivityScenarioGenerator>(
171 simMarket->baseScenarioAbsolute());
172 simMarket->scenarioGenerator() = scenarioGenerator;
173 LOG(
"ParStressConverter: Compute ParInstrumentSensitivities");
174 parAnalysis->computeParInstrumentSensitivities(simMarket);
175 return {simMarket, parAnalysis};
std::map< std::pair< ore::analytics::RiskFactorKey, ore::analytics::RiskFactorKey >, Real > ParContainer
Convert all par shifts in a single stress test scenario to zero shifts.
ore::analytics::StressTestScenarioData::StressTestData convertScenario(const StressTestScenarioData::StressTestData &scenario) const
Convert par shifts in a stress scenario to zero shifts.
QuantLib::ext::shared_ptr< ore::data::CurveConfigurations > curveConfigs_
QuantLib::ext::shared_ptr< ore::data::TodaysMarketParameters > todaysMarketParams_
QuantLib::ext::shared_ptr< ore::data::Market > todaysMarket_
QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarketParameters > simMarketParams_
std::pair< QuantLib::ext::shared_ptr< ScenarioSimMarket >, QuantLib::ext::shared_ptr< ParSensitivityAnalysis > > computeParSensitivity(const std::set< RiskFactorKey::KeyType > &typesDisabled) const
ParStressTestConverter(const QuantLib::Date &asof, QuantLib::ext::shared_ptr< ore::data::TodaysMarketParameters > &todaysMarketParams, const QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarketParameters > &simMarketParams, const QuantLib::ext::shared_ptr< ore::analytics::SensitivityScenarioData > &sensiScenarioData, const QuantLib::ext::shared_ptr< ore::data::CurveConfigurations > &curveConfigs, const QuantLib::ext::shared_ptr< ore::data::Market > &todaysMarket, const QuantLib::ext::shared_ptr< ore::data::IborFallbackConfig > &iborFallbackConfig)
QuantLib::ext::shared_ptr< ore::data::IborFallbackConfig > iborFallbackConfig_
QuantLib::ext::shared_ptr< ore::analytics::SensitivityScenarioData > sensiScenarioData_
QuantLib::ext::shared_ptr< ore::analytics::StressTestScenarioData > convertStressScenarioData(const QuantLib::ext::shared_ptr< ore::analytics::StressTestScenarioData > &scenarioData) const
Convert all par shifts to zero shifts for all scenarios defined in the stresstest.
@ YoYInflationCapFloorVolatility
@ ZeroInflationCapFloorVolatility
static const string defaultConfiguration
factory class for cloning a cached scenario
std::set< RiskFactorKey::KeyType > disabledParRates(bool irCurveParRates, bool irCapFloorParRates, bool creditParRates)
Perfrom sensitivity analysis for a given portfolio.
Convert all par shifts in a stress test to a zero shifts.
Convert all par shifts in a single stress test scenario to a zero shifts.
Class for structured analytics warnings.
vector< string > curveConfigs