Convert par shifts in a stress scenario to zero shifts.
324 {
325
326 if (!parStressScenario.containsParShifts()) {
327 return parStressScenario;
328 }
329
331 WLOG(
"Can not convert scenario " << parStressScenario.label <<
" Skip it and apply all shifts as zero shifts.");
332 return parStressScenario;
333 }
334
336
337 LOG(
"ParStressConverter: Scenario " << parStressScenario.label <<
" has IR Curve Par Shifts = "
339
340 LOG(
"ParStressConverter: Scenario " << parStressScenario.label <<
" has CapFloor Par Shifts = "
342
343 LOG(
"ParStressConverter: Scenario " << parStressScenario.label <<
" has Credit Par Shifts = "
345
346 std::set<RiskFactorKey::KeyType> excludedParRates =
347 disabledParRates(parStressScenario.irCurveParShifts, parStressScenario.irCapFloorParShifts,
348 parStressScenario.creditCurveParShifts);
349
350 LOG(
"ParStressConverter: Copy scenario and remove parShifts from scenario");
351 auto zeroStressScenario = removeParShiftsCopy(parStressScenario);
352 DLOG(
"ParStressConverter: Clone base scenario");
353 auto zeroSimMarketScenario =
simMarket_->baseScenario()->clone();
354
355
356 std::vector<RiskFactorKey> relevantParKeys;
357 std::map<RiskFactorKey, double> fairRates;
358 std::map<RiskFactorKey, double> baseScenarioValues;
359 std::map<RiskFactorKey, double> targets;
360 LOG(
"ParStressConverter: Compute fair rate and target rate for all ParInstruments");
362 if (excludedParRates.count(rfKey.keytype) == 0 &&
363 (supportedCurveShiftTypes.count(rfKey.keytype) == 1 ||
365 relevantParKeys.push_back(rfKey);
367
368 const double target =
370 const double baseScenarioValue =
simMarket_->baseScenario()->get(rfKey);
371 const double baseScenarioAbsoluteValue =
simMarket_->baseScenarioAbsolute()->get(rfKey);
372 DLOG(
"ParStressConverter: ParInstrument "
373 << rfKey << ", fair rate = " << fairRate << ", target rate = " << target << ", baseScenarioValue = "
374 << baseScenarioValue << ", baseScenarioAbsoluteValue = " << baseScenarioAbsoluteValue);
375 fairRates[rfKey] = fairRate;
376 targets[rfKey] = target;
377 baseScenarioValues[rfKey] = baseScenarioValue;
378 } else {
379 DLOG(
"Skip parInsturment " << rfKey <<
" the shifts for this risk factor type are in zero domain.");
380 }
381 }
382
383 LOG(
"ParStressConverter: Imply zero shifts");
384 std::map<RiskFactorKey, double> shifts;
385 for (const auto& rfKey : relevantParKeys) {
386 DLOG(
"Imply zero shifts for parInstrument " << rfKey);
387 const double target = targets[rfKey];
388 auto targetFunction = [this, &target, &rfKey, &zeroSimMarketScenario](double x) {
389 zeroSimMarketScenario->add(rfKey, x);
390 simMarket_->applyScenario(zeroSimMarketScenario);
392 };
393 double targetValue;
394 Brent brent;
395 try {
396 DLOG(
"ParStressConverter: Try to imply zero rate" << rfKey <<
" with bounds << " <<
lowerBound(rfKey) <<
","
398 targetValue =
400 } catch (const std::exception& e) {
401 ALOG(
"ParStressConverter: Couldn't find a solution to imply a zero rate for parRate " << rfKey <<
", got "
402 << e.what());
403 targetValue =
simMarket_->baseScenario()->get(rfKey);
404 }
405 zeroSimMarketScenario->add(rfKey, targetValue);
408 }
409 simMarket_->applyScenario(zeroSimMarketScenario);
410 DLOG(
"ParStressConverter: Implied Scenario");
411 DLOG(
"parInstrument;fairRate;targetFairRate;zeroBaseValue;shift");
412 for (const auto& rfKey : relevantParKeys) {
413 DLOG(rfKey <<
";" <<
impliedParRate(rfKey) <<
";" << targets[rfKey] <<
";" << baseScenarioValues[rfKey] <<
";"
414 << shifts[rfKey]);
415 }
417 return zeroStressScenario;
418}
bool scenarioCanBeConverted(const StressTestScenarioData::StressTestData &parStressScenario) const
check if the scenario can be converted
double shiftsSizeForScenario(const RiskFactorKey rfKey, double targetValue, double baseValue) const
convert the scenario value to the corresponding zero shift size for the stress test data
double getStressShift(const RiskFactorKey &key, const StressTestScenarioData::StressTestData &stressScenario) const
get the par stress shift size from stress test data
double impliedParRate(const RiskFactorKey &key) const
Compute the implied fair rate of the par instrument.
double upperBound(const RiskFactorKey key) const
void updateTargetStressTestScenarioData(StressTestScenarioData::StressTestData &stressScenario, const RiskFactorKey &key, const double zeroShift) const
add zero shifts in the stress test data
double lowerBound(const RiskFactorKey key) const
std::set< RiskFactorKey::KeyType > disabledParRates(bool irCurveParRates, bool irCapFloorParRates, bool creditParRates)
std::string to_string(const LocationInfo &l)