Skip to content

Commit ac75858

Browse files
damienbarkerjenkins
authored andcommitted
Resolve QPR-12281 make bt runs more robust
1 parent 1912b43 commit ac75858

3 files changed

Lines changed: 122 additions & 24 deletions

File tree

OREAnalytics/orea/engine/historicalsensipnlcalculator.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
1717
*/
1818

19-
#include <orea/engine/historicalsensipnlcalculator.hpp>
19+
#include <orea/app/structuredanalyticserror.hpp>
2020
#include <orea/cube/inmemorycube.hpp>
21+
#include <orea/engine/historicalsensipnlcalculator.hpp>
2122
#include <ored/utilities/to_string.hpp>
2223

2324
#include <boost/accumulators/statistics/tail_quantile.hpp>
@@ -173,8 +174,16 @@ void HistoricalSensiPnlCalculator::populateSensiShifts(boost::shared_ptr<NPVCube
173174

174175
Size j = 0;
175176
for (const auto& [_, key] : keyNameMapping) {
176-
Real shift = shiftCalculator->shift(key, *baseScenario, *scenario);
177-
cube->set(shift, j, 0, i);
177+
try {
178+
Real shift = shiftCalculator->shift(key, *baseScenario, *scenario);
179+
cube->set(shift, j, 0, i);
180+
} catch (const std::exception& e) {
181+
StructuredAnalyticsErrorMessage(
182+
"HistocialSensiPnlCalculator",
183+
"Shift calcuation failed. Check consistency of simulation and sensi config.",
184+
"Error retrieving sensi key '" + ore::data::to_string(key) + "' from ssm scenario: '" + e.what())
185+
.log();
186+
}
178187
j++;
179188
}
180189
}

OREAnalytics/orea/scenario/scenariosimmarketparameters.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,19 @@ namespace {
4242
template <typename T> const vector<T>& lookup(const map<string, vector<T>>& m, const string& k) {
4343
if (m.count(k) > 0) {
4444
return m.at(k);
45-
} else if (m.count("") > 0) {
46-
return m.at("");
45+
} else if (m.count(std::string()) > 0) {
46+
return m.at(std::string());
4747
} else
48-
QL_FAIL("no vector for key \"" << k << "\" found.");
48+
QL_FAIL("ScenarioSimMarketParameters: no vector for key \"" << k << "\" found.");
4949
}
5050

5151
template <typename T> const T& lookup(const map<string, T>& m, const string& k) {
5252
if (m.count(k) > 0) {
5353
return m.at(k);
54-
} else if (m.count("") > 0) {
55-
return m.at("");
54+
} else if (m.count(std::string()) > 0) {
55+
return m.at(std::string());
5656
} else
57-
QL_FAIL("no result for key \"" << k << "\" found.");
57+
QL_FAIL("ScenarioSimMarketParameters: no result for key \"" << k << "\" found.");
5858
}
5959

6060
} // namespace

OREAnalytics/orea/scenario/sensitivityscenariogenerator.cpp

Lines changed: 104 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,13 @@ void SensitivityScenarioGenerator::generateDiscountCurveScenarios(bool up) {
425425

426426
for (auto c : sensitivityData_->discountCurveShiftData()) {
427427
string ccy = c.first;
428-
Size n_ten = simMarketData_->yieldCurveTenors(ccy).size();
428+
Size n_ten;
429+
try {
430+
n_ten = simMarketData_->yieldCurveTenors(ccy).size();
431+
} catch (const std::exception& e) {
432+
ALOG("skip scenario generation for discount curve " << ccy << ": " << e.what());
433+
continue;
434+
}
429435
// original curves' buffer
430436
std::vector<Real> zeros(n_ten);
431437
std::vector<Real> times(n_ten);
@@ -525,7 +531,13 @@ void SensitivityScenarioGenerator::generateIndexCurveScenarios(bool up) {
525531

526532
for (auto idx : sensitivityData_->indexCurveShiftData()) {
527533
string indexName = idx.first;
528-
Size n_ten = simMarketData_->yieldCurveTenors(indexName).size();
534+
Size n_ten;
535+
try {
536+
n_ten = simMarketData_->yieldCurveTenors(indexName).size();
537+
} catch (const std::exception& e) {
538+
ALOG("skip scenario generation for index curve " << indexName << ": " << e.what());
539+
continue;
540+
}
529541
// original curves' buffer
530542
std::vector<Real> zeros(n_ten);
531543
std::vector<Real> times(n_ten);
@@ -624,7 +636,13 @@ void SensitivityScenarioGenerator::generateYieldCurveScenarios(bool up) {
624636

625637
for (auto y : sensitivityData_->yieldCurveShiftData()) {
626638
string name = y.first;
627-
Size n_ten = simMarketData_->yieldCurveTenors(name).size();
639+
Size n_ten;
640+
try {
641+
n_ten = simMarketData_->yieldCurveTenors(name).size();
642+
} catch (const std::exception& e) {
643+
ALOG("skip scenario generation for yield curve " << name << ": " << e.what());
644+
continue;
645+
}
628646
// original curves' buffer
629647
std::vector<Real> zeros(n_ten);
630648
std::vector<Real> times(n_ten);
@@ -720,7 +738,13 @@ void SensitivityScenarioGenerator::generateDividendYieldScenarios(bool up) {
720738

721739
for (auto d : sensitivityData_->dividendYieldShiftData()) {
722740
string name = d.first;
723-
Size n_ten = simMarketData_->equityDividendTenors(name).size();
741+
Size n_ten;
742+
try {
743+
n_ten = simMarketData_->equityDividendTenors(name).size();
744+
} catch (const std::exception& e) {
745+
ALOG("skip scenario generation for div yield " << name << ": " << e.what());
746+
continue;
747+
}
724748
// original curves' buffer
725749
std::vector<Real> zeros(n_ten);
726750
std::vector<Real> times(n_ten);
@@ -818,7 +842,13 @@ void SensitivityScenarioGenerator::generateFxVolScenarios(bool up) {
818842
string ccyPair = f.first;
819843
QL_REQUIRE(ccyPair.length() == 6, "invalid ccy pair length");
820844

821-
Size n_fxvol_exp = simMarketData_->fxVolExpiries(ccyPair).size();
845+
Size n_fxvol_exp;
846+
try {
847+
n_fxvol_exp = simMarketData_->fxVolExpiries(ccyPair).size();
848+
} catch (const std::exception& e) {
849+
ALOG("skip scenario generation for fx vol " << ccyPair << ": " << e.what());
850+
continue;
851+
}
822852
std::vector<Real> times(n_fxvol_exp);
823853
Size n_fxvol_strikes;
824854
vector<Real> vol_strikes;
@@ -933,7 +963,13 @@ void SensitivityScenarioGenerator::generateEquityVolScenarios(bool up) {
933963
if (!isScenarioRelevant(up, data))
934964
continue;
935965

936-
Size n_eqvol_exp = simMarketData_->equityVolExpiries(equity).size();
966+
Size n_eqvol_exp;
967+
try {
968+
n_eqvol_exp = simMarketData_->equityVolExpiries(equity).size();
969+
} catch (const std::exception& e) {
970+
ALOG("skip scenario generation for eq vol " << equity << ": " << e.what());
971+
continue;
972+
}
937973
Size n_eqvol_strikes;
938974
vector<Real> vol_strikes;
939975
if (!simMarketData_->equityVolIsSurface(equity)) {
@@ -1109,7 +1145,13 @@ void SensitivityScenarioGenerator::generateGenericYieldVolScenarios(bool up, Ris
11091145
for (auto s : shiftData) {
11101146
std::string qualifier = s.first;
11111147

1112-
Size n_term = get_n_term(qualifier);
1148+
Size n_term;
1149+
try {
1150+
n_term = get_n_term(qualifier);
1151+
} catch (const std::exception& e) {
1152+
ALOG("skip scenario generation for general yield vol " << qualifier << ": " << e.what());
1153+
continue;
1154+
}
11131155
Size n_expiry = get_n_expiry(qualifier);
11141156

11151157
vector<Real> volExpiryTimes(n_expiry, 0.0);
@@ -1268,7 +1310,13 @@ void SensitivityScenarioGenerator::generateCapFloorVolScenarios(bool up) {
12681310
for (auto c : sensitivityData_->capFloorVolShiftData()) {
12691311
std::string key = c.first;
12701312

1271-
vector<Real> volStrikes = simMarketData_->capFloorVolStrikes(key);
1313+
vector<Real> volStrikes;
1314+
try {
1315+
volStrikes = simMarketData_->capFloorVolStrikes(key);
1316+
} catch (const std::exception& e) {
1317+
ALOG("skip scenario generation for cf vol " << key << ": " << e.what());
1318+
continue;
1319+
}
12721320
// Strikes may be empty which indicates that the optionlet structure in the simulation market is an ATM curve
12731321
if (volStrikes.empty()) {
12741322
volStrikes = {0.0};
@@ -1394,7 +1442,12 @@ void SensitivityScenarioGenerator::generateSurvivalProbabilityScenarios(bool up)
13941442

13951443
for (auto c : sensitivityData_->creditCurveShiftData()) {
13961444
string name = c.first;
1397-
n_ten = simMarketData_->defaultTenors(name).size();
1445+
try {
1446+
n_ten = simMarketData_->defaultTenors(name).size();
1447+
} catch (const std::exception& e) {
1448+
ALOG("skip scenario generation for survival curve " << name << ": " << e.what());
1449+
continue;
1450+
}
13981451
std::vector<Real> hazardRates(n_ten); // integrated hazard rates
13991452
times.clear();
14001453
times.resize(n_ten);
@@ -1587,7 +1640,13 @@ void SensitivityScenarioGenerator::generateZeroInflationScenarios(bool up) {
15871640

15881641
for (auto z : sensitivityData_->zeroInflationCurveShiftData()) {
15891642
string indexName = z.first;
1590-
Size n_ten = simMarketData_->zeroInflationTenors(indexName).size();
1643+
Size n_ten;
1644+
try {
1645+
n_ten = simMarketData_->zeroInflationTenors(indexName).size();
1646+
} catch (const std::exception& e) {
1647+
ALOG("skip scenario generation for zero inflation curve " << indexName << ": " << e.what());
1648+
continue;
1649+
}
15911650
// original curves' buffer
15921651
std::vector<Real> zeros(n_ten);
15931652
std::vector<Real> times(n_ten);
@@ -1682,7 +1741,13 @@ void SensitivityScenarioGenerator::generateYoYInflationScenarios(bool up) {
16821741

16831742
for (auto y : sensitivityData_->yoyInflationCurveShiftData()) {
16841743
string indexName = y.first;
1685-
Size n_ten = simMarketData_->yoyInflationTenors(indexName).size();
1744+
Size n_ten;
1745+
try {
1746+
n_ten = simMarketData_->yoyInflationTenors(indexName).size();
1747+
} catch (const std::exception& e) {
1748+
ALOG("skip scenario generation for yoy inflation curve " << indexName << ": " << e.what());
1749+
continue;
1750+
}
16861751
// original curves' buffer
16871752
std::vector<Real> yoys(n_ten);
16881753
std::vector<Real> times(n_ten);
@@ -1777,7 +1842,13 @@ void SensitivityScenarioGenerator::generateYoYInflationCapFloorVolScenarios(bool
17771842

17781843
for (auto c : sensitivityData_->yoyInflationCapFloorVolShiftData()) {
17791844
std::string name = c.first;
1780-
Size n_yoyvol_strikes = simMarketData_->yoyInflationCapFloorVolStrikes(name).size();
1845+
Size n_yoyvol_strikes;
1846+
try {
1847+
n_yoyvol_strikes = simMarketData_->yoyInflationCapFloorVolStrikes(name).size();
1848+
} catch (const std::exception& e) {
1849+
ALOG("skip scenario generation for yoy inflation cf vol " << name << ": " << e.what());
1850+
continue;
1851+
}
17811852
vector<Real> volStrikes = simMarketData_->yoyInflationCapFloorVolStrikes(name);
17821853
Size n_yoyvol_exp = simMarketData_->yoyInflationCapFloorVolExpiries(name).size();
17831854
SensitivityScenarioData::VolShiftData data = *c.second;
@@ -1884,7 +1955,13 @@ void SensitivityScenarioGenerator::generateZeroInflationCapFloorVolScenarios(boo
18841955

18851956
for (auto c : sensitivityData_->zeroInflationCapFloorVolShiftData()) {
18861957
std::string name = c.first;
1887-
Size n_strikes = simMarketData_->zeroInflationCapFloorVolStrikes(name).size();
1958+
Size n_strikes;
1959+
try {
1960+
n_strikes = simMarketData_->zeroInflationCapFloorVolStrikes(name).size();
1961+
} catch (const std::exception& e) {
1962+
ALOG("skip scenario generation for zero inflation cf vol " << name << ": " << e.what());
1963+
continue;
1964+
}
18881965
Size n_exp = simMarketData_->zeroInflationCapFloorVolExpiries(name).size();
18891966
vector<Real> volStrikes = simMarketData_->zeroInflationCapFloorVolStrikes(name);
18901967
SensitivityScenarioData::VolShiftData data = *c.second;
@@ -2113,7 +2190,13 @@ void SensitivityScenarioGenerator::generateCommodityCurveScenarios(bool up) {
21132190
for (auto c : sensitivityData_->commodityCurveShiftData()) {
21142191
string name = c.first;
21152192
// Tenors for this name in simulation market
2116-
vector<Period> simMarketTenors = simMarketData_->commodityCurveTenors(name);
2193+
vector<Period> simMarketTenors;
2194+
try {
2195+
simMarketTenors = simMarketData_->commodityCurveTenors(name);
2196+
} catch (const std::exception& e) {
2197+
ALOG("skip scenario generation for comm curve " << name << ": " << e.what());
2198+
continue;
2199+
}
21172200
DayCounter dc = Actual365Fixed();
21182201
try {
21192202
if (auto s = simMarket_.lock()) {
@@ -2208,7 +2291,13 @@ void SensitivityScenarioGenerator::generateCommodityVolScenarios(bool up) {
22082291
for (auto c : sensitivityData_->commodityVolShiftData()) {
22092292
string name = c.first;
22102293
// Simulation market data for the current name
2211-
const vector<Period>& expiries = simMarketData_->commodityVolExpiries(name);
2294+
vector<Period> expiries;
2295+
try {
2296+
expiries = simMarketData_->commodityVolExpiries(name);
2297+
} catch (const std::exception& e) {
2298+
ALOG("skip scenario generation for comm vol " << name << ": " << e.what());
2299+
continue;
2300+
}
22122301
const vector<Real>& moneyness = simMarketData_->commodityVolMoneyness(name);
22132302
QL_REQUIRE(!expiries.empty(), "Sim market commodity volatility expiries have not been specified for " << name);
22142303
QL_REQUIRE(!moneyness.empty(), "Sim market commodity volatility moneyness has not been specified for " << name);

0 commit comments

Comments
 (0)