21#include <boost/test/unit_test.hpp>
22#include <oret/toplevelfixture.hpp>
25#include <boost/timer/timer.hpp>
54#include <ql/math/randomnumbers/mt19937uniformrng.hpp>
55#include <ql/time/calendars/target.hpp>
56#include <ql/time/date.hpp>
57#include <ql/time/daycounters/actualactual.hpp>
63using namespace boost::unit_test_framework;
67using boost::timer::cpu_timer;
68using boost::timer::default_places;
73inline unsigned long randInt(MersenneTwisterUniformRng& rng, Size min, Size max) {
74 return min + (rng.nextInt32() % (
max + 1 -
min));
77inline const string&
randString(MersenneTwisterUniformRng& rng,
const vector<string>& strs) {
78 return strs[
randInt(rng, 0, strs.size() - 1)];
81inline bool randBoolean(MersenneTwisterUniformRng& rng) {
return randInt(rng, 0, 1) == 1; }
83QuantLib::ext::shared_ptr<data::Conventions> conv() {
84 QuantLib::ext::shared_ptr<data::Conventions> conventions(
new data::Conventions());
86 QuantLib::ext::shared_ptr<data::Convention> swapIndexConv(
88 conventions->add(swapIndexConv);
92 conventions->add(QuantLib::ext::make_shared<data::IRSwapConvention>(
"EUR-6M-SWAP-CONVENTIONS",
"TARGET",
"A",
"MF",
93 "30/360",
"EUR-EURIBOR-6M"));
94 conventions->add(QuantLib::ext::make_shared<data::IRSwapConvention>(
"USD-3M-SWAP-CONVENTIONS",
"TARGET",
"Q",
"MF",
95 "30/360",
"USD-LIBOR-3M"));
96 conventions->add(QuantLib::ext::make_shared<data::IRSwapConvention>(
"USD-6M-SWAP-CONVENTIONS",
"TARGET",
"Q",
"MF",
97 "30/360",
"USD-LIBOR-6M"));
98 conventions->add(QuantLib::ext::make_shared<data::IRSwapConvention>(
"GBP-6M-SWAP-CONVENTIONS",
"TARGET",
"A",
"MF",
99 "30/360",
"GBP-LIBOR-6M"));
100 conventions->add(QuantLib::ext::make_shared<data::IRSwapConvention>(
"JPY-6M-SWAP-CONVENTIONS",
"TARGET",
"A",
"MF",
101 "30/360",
"JPY-LIBOR-6M"));
102 conventions->add(QuantLib::ext::make_shared<data::IRSwapConvention>(
"CHF-6M-SWAP-CONVENTIONS",
"TARGET",
"A",
"MF",
103 "30/360",
"CHF-LIBOR-6M"));
105 conventions->add(QuantLib::ext::make_shared<data::DepositConvention>(
"EUR-DEP-CONVENTIONS",
"EUR-EURIBOR"));
106 conventions->add(QuantLib::ext::make_shared<data::DepositConvention>(
"USD-DEP-CONVENTIONS",
"USD-LIBOR"));
107 conventions->add(QuantLib::ext::make_shared<data::DepositConvention>(
"GBP-DEP-CONVENTIONS",
"GBP-LIBOR"));
108 conventions->add(QuantLib::ext::make_shared<data::DepositConvention>(
"JPY-DEP-CONVENTIONS",
"JPY-LIBOR"));
109 conventions->add(QuantLib::ext::make_shared<data::DepositConvention>(
"CHF-DEP-CONVENTIONS",
"CHF-LIBOR"));
111 InstrumentConventions::instance().setConventions(conventions);
117 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> simMarketData(
120 simMarketData->baseCcy() =
"EUR";
121 simMarketData->setDiscountCurveNames({
"EUR",
"GBP",
"USD",
"CHF",
"JPY"});
122 simMarketData->setYieldCurveTenors(
"", {1 * Months, 6 * Months, 1 * Years, 2 * Years, 3 * Years, 4 * Years,
123 5 * Years, 7 * Years, 10 * Years, 15 * Years, 20 * Years, 30 * Years});
124 simMarketData->setIndices(
125 {
"EUR-EURIBOR-6M",
"USD-LIBOR-3M",
"USD-LIBOR-6M",
"GBP-LIBOR-6M",
"CHF-LIBOR-6M",
"JPY-LIBOR-6M"});
126 simMarketData->interpolation() =
"LogLinear";
128 simMarketData->setSwapVolTerms(
"", {1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 20 * Years});
129 simMarketData->setSwapVolExpiries(
130 "", {6 * Months, 1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 20 * Years});
131 simMarketData->setSwapVolKeys({
"EUR",
"GBP",
"USD",
"CHF",
"JPY"});
132 simMarketData->swapVolDecayMode() =
"ForwardVariance";
133 simMarketData->setSimulateSwapVols(
true);
135 simMarketData->setFxVolExpiries(
"",
136 vector<Period>{1 * Months, 3 * Months, 6 * Months, 2 * Years, 3 * Years, 4 * Years, 5 * Years});
137 simMarketData->setFxVolDecayMode(
string(
"ConstantVariance"));
138 simMarketData->setSimulateFXVols(
true);
139 simMarketData->setFxVolCcyPairs({
"EURUSD",
"EURGBP",
"EURCHF",
"EURJPY",
"GBPCHF"});
141 simMarketData->setFxCcyPairs({
"EURUSD",
"EURGBP",
"EURCHF",
"EURJPY"});
143 simMarketData->setSimulateCapFloorVols(
true);
144 simMarketData->capFloorVolDecayMode() =
"ForwardVariance";
145 simMarketData->setCapFloorVolKeys({
"EUR",
"USD"});
146 simMarketData->setCapFloorVolExpiries(
147 "", {6 * Months, 1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 15 * Years, 20 * Years});
148 simMarketData->setCapFloorVolStrikes(
"", {0.00, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06});
150 return simMarketData;
153QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> setupSimMarketData5Big() {
154 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> simMarketData(
157 simMarketData->baseCcy() =
"EUR";
158 simMarketData->setDiscountCurveNames({
"EUR",
"GBP",
"USD",
"CHF",
"JPY"});
159 simMarketData->setYieldCurveTenors(
160 "", {1 * Weeks, 2 * Weeks, 1 * Months, 2 * Months, 3 * Months, 4 * Months, 5 * Months, 6 * Months,
161 9 * Months, 10 * Months, 11 * Months, 1 * Years, 13 * Months, 14 * Months, 15 * Months, 16 * Months,
162 17 * Months, 18 * Months, 19 * Months, 20 * Months, 21 * Months, 22 * Months, 23 * Months, 2 * Years,
163 25 * Months, 26 * Months, 27 * Months, 28 * Months, 29 * Months, 30 * Months, 31 * Months, 32 * Months,
164 3 * Years, 40 * Months, 41 * Months, 42 * Months, 43 * Months, 44 * Months, 4 * Years, 52 * Months,
165 53 * Months, 54 * Months, 55 * Months, 56 * Months, 5 * Years, 64 * Months, 65 * Months, 66 * Months,
166 67 * Months, 68 * Months, 6 * Years, 76 * Months, 77 * Months, 78 * Months, 79 * Months, 80 * Months,
167 7 * Years, 88 * Months, 89 * Months, 90 * Months, 91 * Months, 92 * Months, 10 * Years, 15 * Years,
168 20 * Years, 25 * Years, 30 * Years, 50 * Years});
169 simMarketData->setIndices(
170 {
"EUR-EURIBOR-6M",
"USD-LIBOR-3M",
"USD-LIBOR-6M",
"GBP-LIBOR-6M",
"CHF-LIBOR-6M",
"JPY-LIBOR-6M"});
171 simMarketData->interpolation() =
"LogLinear";
173 simMarketData->setSwapVolTerms(
174 "", {3 * Months, 4 * Months, 5 * Months, 6 * Months, 9 * Months, 10 * Months, 11 * Months, 1 * Years,
175 13 * Months, 14 * Months, 15 * Months, 16 * Months, 17 * Months, 18 * Months, 19 * Months, 20 * Months,
176 21 * Months, 22 * Months, 23 * Months, 2 * Years, 25 * Months, 26 * Months, 27 * Months, 28 * Months,
177 29 * Months, 30 * Months, 31 * Months, 32 * Months, 3 * Years, 40 * Months, 41 * Months, 42 * Months,
178 43 * Months, 44 * Months, 4 * Years, 52 * Months, 53 * Months, 54 * Months, 55 * Months, 56 * Months,
179 5 * Years, 64 * Months, 65 * Months, 66 * Months, 67 * Months, 68 * Months, 6 * Years, 76 * Months,
180 77 * Months, 78 * Months, 79 * Months, 80 * Months, 7 * Years, 88 * Months, 89 * Months, 90 * Months,
181 91 * Months, 92 * Months, 10 * Years, 15 * Years, 20 * Years, 25 * Years, 30 * Years, 50 * Years});
182 simMarketData->setSwapVolExpiries(
183 "", {1 * Weeks, 2 * Weeks, 1 * Months, 2 * Months, 3 * Months, 4 * Months, 5 * Months, 6 * Months,
184 9 * Months, 10 * Months, 11 * Months, 1 * Years, 13 * Months, 14 * Months, 15 * Months, 16 * Months,
185 17 * Months, 18 * Months, 19 * Months, 20 * Months, 21 * Months, 22 * Months, 23 * Months, 2 * Years,
186 25 * Months, 26 * Months, 27 * Months, 28 * Months, 29 * Months, 30 * Months, 31 * Months, 32 * Months,
187 3 * Years, 40 * Months, 41 * Months, 42 * Months, 43 * Months, 44 * Months, 4 * Years, 52 * Months,
188 53 * Months, 54 * Months, 55 * Months, 56 * Months, 5 * Years, 64 * Months, 65 * Months, 66 * Months,
189 67 * Months, 68 * Months, 6 * Years, 76 * Months, 77 * Months, 78 * Months, 79 * Months, 80 * Months,
190 7 * Years, 88 * Months, 89 * Months, 90 * Months, 91 * Months, 92 * Months, 10 * Years, 15 * Years,
191 20 * Years, 25 * Years, 30 * Years, 50 * Years});
192 simMarketData->setSwapVolKeys({
"EUR",
"GBP",
"USD",
"CHF",
"JPY"});
193 simMarketData->swapVolDecayMode() =
"ForwardVariance";
194 simMarketData->setSimulateSwapVols(
true);
196 vector<Period> tmpFxVolExpiries = {
197 1 * Weeks, 2 * Weeks, 1 * Months, 2 * Months, 3 * Months, 4 * Months, 5 * Months, 6 * Months,
198 9 * Months, 10 * Months, 11 * Months, 1 * Years, 13 * Months, 14 * Months, 15 * Months, 16 * Months,
199 17 * Months, 18 * Months, 19 * Months, 20 * Months, 21 * Months, 22 * Months, 23 * Months, 2 * Years,
200 25 * Months, 26 * Months, 27 * Months, 28 * Months, 29 * Months, 30 * Months, 31 * Months, 32 * Months,
201 3 * Years, 40 * Months, 41 * Months, 42 * Months, 43 * Months, 44 * Months, 4 * Years, 52 * Months,
202 53 * Months, 54 * Months, 55 * Months, 56 * Months, 5 * Years, 64 * Months, 65 * Months, 66 * Months,
203 67 * Months, 68 * Months, 6 * Years, 76 * Months, 77 * Months, 78 * Months, 79 * Months, 80 * Months,
204 7 * Years, 88 * Months, 89 * Months, 90 * Months, 91 * Months, 92 * Months, 10 * Years, 15 * Years,
205 20 * Years, 25 * Years, 30 * Years, 50 * Years};
207 simMarketData->setFxVolExpiries(
"", tmpFxVolExpiries);
208 simMarketData->setFxVolDecayMode(
string(
"ConstantVariance"));
209 simMarketData->setSimulateFXVols(
true);
210 simMarketData->setFxVolCcyPairs({
"EURUSD",
"EURGBP",
"EURCHF",
"EURJPY",
"GBPCHF"});
212 simMarketData->setFxCcyPairs({
"EURUSD",
"EURGBP",
"EURCHF",
"EURJPY"});
214 simMarketData->setSimulateCapFloorVols(
true);
215 simMarketData->capFloorVolDecayMode() =
"ForwardVariance";
216 simMarketData->setCapFloorVolKeys({
"EUR",
"USD"});
217 simMarketData->setCapFloorVolExpiries(
218 "", {3 * Months, 4 * Months, 5 * Months, 6 * Months, 9 * Months, 10 * Months, 11 * Months, 1 * Years,
219 13 * Months, 14 * Months, 15 * Months, 16 * Months, 17 * Months, 18 * Months, 19 * Months, 20 * Months,
220 21 * Months, 22 * Months, 23 * Months, 2 * Years, 25 * Months, 26 * Months, 27 * Months, 28 * Months,
221 29 * Months, 30 * Months, 31 * Months, 32 * Months, 3 * Years, 40 * Months, 41 * Months, 42 * Months,
222 43 * Months, 44 * Months, 4 * Years, 52 * Months, 53 * Months, 54 * Months, 55 * Months, 56 * Months,
223 5 * Years, 64 * Months, 65 * Months, 66 * Months, 67 * Months, 68 * Months, 6 * Years, 76 * Months,
224 77 * Months, 78 * Months, 79 * Months, 80 * Months, 7 * Years, 88 * Months, 89 * Months, 90 * Months,
225 91 * Months, 92 * Months, 10 * Years, 15 * Years, 20 * Years, 25 * Years, 30 * Years, 50 * Years});
226 simMarketData->setCapFloorVolStrikes(
"", {0.00, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06});
228 return simMarketData;
231QuantLib::ext::shared_ptr<SensitivityScenarioData> setupSensitivityScenarioData5Big() {
232 QuantLib::ext::shared_ptr<SensitivityScenarioData> sensiData = QuantLib::ext::make_shared<SensitivityScenarioData>();
236 1 * Weeks, 2 * Weeks, 1 * Months, 2 * Months, 3 * Months, 4 * Months, 5 * Months, 6 * Months,
237 9 * Months, 10 * Months, 11 * Months, 1 * Years, 13 * Months, 14 * Months, 15 * Months, 16 * Months,
238 17 * Months, 18 * Months, 19 * Months, 20 * Months, 21 * Months, 22 * Months, 23 * Months, 2 * Years,
239 25 * Months, 26 * Months, 27 * Months, 28 * Months, 29 * Months, 30 * Months, 31 * Months, 32 * Months,
240 3 * Years, 40 * Months, 41 * Months, 42 * Months, 43 * Months, 44 * Months, 4 * Years, 52 * Months,
241 53 * Months, 54 * Months, 55 * Months, 56 * Months, 5 * Years, 64 * Months, 65 * Months, 66 * Months,
242 67 * Months, 68 * Months, 6 * Years, 76 * Months, 77 * Months, 78 * Months, 79 * Months, 80 * Months,
243 7 * Years, 88 * Months, 89 * Months, 90 * Months, 91 * Months, 92 * Months, 10 * Years, 15 * Years,
244 20 * Years, 25 * Years, 30 * Years, 50 * Years};
253 fxvsData.
shiftType = ShiftType::Relative;
255 fxvsData.
shiftExpiries = {1 * Weeks, 2 * Weeks, 1 * Months, 2 * Months, 3 * Months, 4 * Months, 5 * Months,
256 6 * Months, 9 * Months, 10 * Months, 11 * Months, 1 * Years, 13 * Months, 14 * Months,
257 15 * Months, 16 * Months, 17 * Months, 18 * Months, 19 * Months, 20 * Months, 21 * Months,
258 22 * Months, 23 * Months, 2 * Years, 25 * Months, 26 * Months, 27 * Months, 28 * Months,
259 29 * Months, 30 * Months, 31 * Months, 32 * Months, 3 * Years, 40 * Months, 41 * Months,
260 42 * Months, 43 * Months, 44 * Months, 4 * Years, 52 * Months, 53 * Months, 54 * Months,
261 55 * Months, 56 * Months, 5 * Years, 64 * Months, 65 * Months, 66 * Months, 67 * Months,
262 68 * Months, 6 * Years, 76 * Months, 77 * Months, 78 * Months, 79 * Months, 80 * Months,
263 7 * Years, 88 * Months, 89 * Months, 90 * Months, 91 * Months, 92 * Months, 10 * Years,
264 15 * Years, 20 * Years, 25 * Years, 30 * Years, 50 * Years};
267 cfvsData.
shiftType = ShiftType::Absolute;
270 3 * Months, 4 * Months, 5 * Months, 6 * Months, 9 * Months, 10 * Months, 11 * Months, 1 * Years,
271 13 * Months, 14 * Months, 15 * Months, 16 * Months, 17 * Months, 18 * Months, 19 * Months, 20 * Months,
272 21 * Months, 22 * Months, 23 * Months, 2 * Years, 25 * Months, 26 * Months, 27 * Months, 28 * Months,
273 29 * Months, 30 * Months, 31 * Months, 32 * Months, 3 * Years, 40 * Months, 41 * Months, 42 * Months,
274 43 * Months, 44 * Months, 4 * Years, 52 * Months, 53 * Months, 54 * Months, 55 * Months, 56 * Months,
275 5 * Years, 64 * Months, 65 * Months, 66 * Months, 67 * Months, 68 * Months, 6 * Years, 76 * Months,
276 77 * Months, 78 * Months, 79 * Months, 80 * Months, 7 * Years, 88 * Months, 89 * Months, 90 * Months,
277 91 * Months, 92 * Months, 10 * Years, 15 * Years, 20 * Years, 25 * Years, 30 * Years, 50 * Years};
281 swvsData.
shiftType = ShiftType::Relative;
283 swvsData.
shiftExpiries = {1 * Weeks, 2 * Weeks, 1 * Months, 2 * Months, 3 * Months, 4 * Months, 5 * Months,
284 6 * Months, 9 * Months, 10 * Months, 11 * Months, 1 * Years, 13 * Months, 14 * Months,
285 15 * Months, 16 * Months, 17 * Months, 18 * Months, 19 * Months, 20 * Months, 21 * Months,
286 22 * Months, 23 * Months, 2 * Years, 25 * Months, 26 * Months, 27 * Months, 28 * Months,
287 29 * Months, 30 * Months, 31 * Months, 32 * Months, 3 * Years, 40 * Months, 41 * Months,
288 42 * Months, 43 * Months, 44 * Months, 4 * Years, 52 * Months, 53 * Months, 54 * Months,
289 55 * Months, 56 * Months, 5 * Years, 64 * Months, 65 * Months, 66 * Months, 67 * Months,
290 68 * Months, 6 * Years, 76 * Months, 77 * Months, 78 * Months, 79 * Months, 80 * Months,
291 7 * Years, 88 * Months, 89 * Months, 90 * Months, 91 * Months, 92 * Months, 10 * Years,
292 15 * Years, 20 * Years, 25 * Years, 30 * Years, 50 * Years};
294 3 * Months, 4 * Months, 5 * Months, 6 * Months, 9 * Months, 10 * Months, 11 * Months, 1 * Years,
295 13 * Months, 14 * Months, 15 * Months, 16 * Months, 17 * Months, 18 * Months, 19 * Months, 20 * Months,
296 21 * Months, 22 * Months, 23 * Months, 2 * Years, 25 * Months, 26 * Months, 27 * Months, 28 * Months,
297 29 * Months, 30 * Months, 31 * Months, 32 * Months, 3 * Years, 40 * Months, 41 * Months, 42 * Months,
298 43 * Months, 44 * Months, 4 * Years, 52 * Months, 53 * Months, 54 * Months, 55 * Months, 56 * Months,
299 5 * Years, 64 * Months, 65 * Months, 66 * Months, 67 * Months, 68 * Months, 6 * Years, 76 * Months,
300 77 * Months, 78 * Months, 79 * Months, 80 * Months, 7 * Years, 88 * Months, 89 * Months, 90 * Months,
301 91 * Months, 92 * Months, 10 * Years, 15 * Years, 20 * Years, 25 * Years, 30 * Years, 50 * Years};
303 sensiData->discountCurveShiftData()[
"EUR"] = QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
305 sensiData->discountCurveShiftData()[
"USD"] = QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
307 sensiData->discountCurveShiftData()[
"GBP"] = QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
309 sensiData->discountCurveShiftData()[
"JPY"] = QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
311 sensiData->discountCurveShiftData()[
"CHF"] = QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
313 sensiData->indexCurveShiftData()[
"EUR-EURIBOR-6M"] =
314 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
316 sensiData->indexCurveShiftData()[
"USD-LIBOR-3M"] =
317 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
319 sensiData->indexCurveShiftData()[
"GBP-LIBOR-6M"] =
320 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
322 sensiData->indexCurveShiftData()[
"JPY-LIBOR-6M"] =
323 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
325 sensiData->indexCurveShiftData()[
"CHF-LIBOR-6M"] =
326 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
328 sensiData->fxShiftData()[
"EURUSD"] = fxsData;
329 sensiData->fxShiftData()[
"EURGBP"] = fxsData;
330 sensiData->fxShiftData()[
"EURJPY"] = fxsData;
331 sensiData->fxShiftData()[
"EURCHF"] = fxsData;
333 sensiData->fxVolShiftData()[
"EURUSD"] = fxvsData;
334 sensiData->fxVolShiftData()[
"EURGBP"] = fxvsData;
335 sensiData->fxVolShiftData()[
"EURJPY"] = fxvsData;
336 sensiData->fxVolShiftData()[
"EURCHF"] = fxvsData;
337 sensiData->fxVolShiftData()[
"GBPCHF"] = fxvsData;
339 sensiData->swaptionVolShiftData()[
"EUR"] = swvsData;
340 sensiData->swaptionVolShiftData()[
"GBP"] = swvsData;
341 sensiData->swaptionVolShiftData()[
"USD"] = swvsData;
342 sensiData->swaptionVolShiftData()[
"JPY"] = swvsData;
343 sensiData->swaptionVolShiftData()[
"CHF"] = swvsData;
345 sensiData->capFloorVolShiftData()[
"EUR"] =
346 QuantLib::ext::make_shared<SensitivityScenarioData::CapFloorVolShiftData>(cfvsData);
347 sensiData->capFloorVolShiftData()[
"EUR"]->indexName =
"EUR-EURIBOR-6M";
348 sensiData->capFloorVolShiftData()[
"USD"] =
349 QuantLib::ext::make_shared<SensitivityScenarioData::CapFloorVolShiftData>(cfvsData);
350 sensiData->capFloorVolShiftData()[
"USD"]->indexName =
"USD-LIBOR-3M";
356 QuantLib::ext::shared_ptr<SensitivityScenarioData> sensiData = QuantLib::ext::make_shared<SensitivityScenarioData>();
359 cvsData.
shiftTenors = {6 * Months, 1 * Years, 2 * Years, 3 * Years, 5 * Years,
360 7 * Years, 10 * Years, 15 * Years, 20 * Years};
369 fxvsData.
shiftType = ShiftType::Relative;
374 cfvsData.
shiftType = ShiftType::Absolute;
376 cfvsData.
shiftExpiries = {1 * Years, 2 * Years, 3 * Years, 5 * Years, 10 * Years};
380 swvsData.
shiftType = ShiftType::Relative;
382 swvsData.
shiftExpiries = {6 * Months, 1 * Years, 3 * Years, 5 * Years, 10 * Years};
383 swvsData.
shiftTerms = {1 * Years, 3 * Years, 5 * Years, 10 * Years, 20 * Years};
385 sensiData->discountCurveShiftData()[
"EUR"] = QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
387 sensiData->discountCurveShiftData()[
"USD"] = QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
389 sensiData->discountCurveShiftData()[
"GBP"] = QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
391 sensiData->discountCurveShiftData()[
"JPY"] = QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
393 sensiData->discountCurveShiftData()[
"CHF"] = QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
395 sensiData->indexCurveShiftData()[
"EUR-EURIBOR-6M"] =
396 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
398 sensiData->indexCurveShiftData()[
"USD-LIBOR-3M"] =
399 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
401 sensiData->indexCurveShiftData()[
"GBP-LIBOR-6M"] =
402 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
404 sensiData->indexCurveShiftData()[
"JPY-LIBOR-6M"] =
405 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
407 sensiData->indexCurveShiftData()[
"CHF-LIBOR-6M"] =
408 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftData>(cvsData);
410 sensiData->fxShiftData()[
"EURUSD"] = fxsData;
411 sensiData->fxShiftData()[
"EURGBP"] = fxsData;
412 sensiData->fxShiftData()[
"EURJPY"] = fxsData;
413 sensiData->fxShiftData()[
"EURCHF"] = fxsData;
415 sensiData->fxVolShiftData()[
"EURUSD"] = fxvsData;
416 sensiData->fxVolShiftData()[
"EURGBP"] = fxvsData;
417 sensiData->fxVolShiftData()[
"EURJPY"] = fxvsData;
418 sensiData->fxVolShiftData()[
"EURCHF"] = fxvsData;
419 sensiData->fxVolShiftData()[
"GBPCHF"] = fxvsData;
421 sensiData->swaptionVolShiftData()[
"EUR"] = swvsData;
422 sensiData->swaptionVolShiftData()[
"GBP"] = swvsData;
423 sensiData->swaptionVolShiftData()[
"USD"] = swvsData;
424 sensiData->swaptionVolShiftData()[
"JPY"] = swvsData;
425 sensiData->swaptionVolShiftData()[
"CHF"] = swvsData;
427 sensiData->capFloorVolShiftData()[
"EUR"] =
428 QuantLib::ext::make_shared<SensitivityScenarioData::CapFloorVolShiftData>(cfvsData);
429 sensiData->capFloorVolShiftData()[
"EUR"]->indexName =
"EUR-EURIBOR-6M";
430 sensiData->capFloorVolShiftData()[
"USD"] =
431 QuantLib::ext::make_shared<SensitivityScenarioData::CapFloorVolShiftData>(cfvsData);
432 sensiData->capFloorVolShiftData()[
"USD"]->indexName =
"USD-LIBOR-3M";
437void addCrossGammas(vector<pair<string, string>>& cgFilter) {
438 BOOST_CHECK_EQUAL(cgFilter.size(), 0);
439 cgFilter.push_back(pair<string, string>(
"DiscountCurve/EUR",
"DiscountCurve/EUR"));
440 cgFilter.push_back(pair<string, string>(
"DiscountCurve/USD",
"DiscountCurve/USD"));
441 cgFilter.push_back(pair<string, string>(
"DiscountCurve/GBP",
"DiscountCurve/GBP"));
442 cgFilter.push_back(pair<string, string>(
"DiscountCurve/CHF",
"DiscountCurve/CHF"));
443 cgFilter.push_back(pair<string, string>(
"DiscountCurve/JPY",
"DiscountCurve/JPY"));
444 cgFilter.push_back(pair<string, string>(
"IndexCurve/EUR",
"DiscountCurve/EUR"));
445 cgFilter.push_back(pair<string, string>(
"IndexCurve/USD",
"DiscountCurve/USD"));
446 cgFilter.push_back(pair<string, string>(
"IndexCurve/GBP",
"DiscountCurve/GBP"));
447 cgFilter.push_back(pair<string, string>(
"IndexCurve/CHF",
"DiscountCurve/CHF"));
448 cgFilter.push_back(pair<string, string>(
"IndexCurve/JPY",
"DiscountCurve/JPY"));
449 cgFilter.push_back(pair<string, string>(
"IndexCurve/EUR",
"IndexCurve/EUR"));
450 cgFilter.push_back(pair<string, string>(
"IndexCurve/USD",
"IndexCurve/USD"));
451 cgFilter.push_back(pair<string, string>(
"IndexCurve/GBP",
"IndexCurve/GBP"));
452 cgFilter.push_back(pair<string, string>(
"IndexCurve/CHF",
"IndexCurve/CHF"));
453 cgFilter.push_back(pair<string, string>(
"IndexCurve/JPY",
"IndexCurve/JPY"));
454 cgFilter.push_back(pair<string, string>(
"SwaptionVolatility/EUR",
"SwaptionVolatility/EUR"));
455 cgFilter.push_back(pair<string, string>(
"SwaptionVolatility/USD",
"SwaptionVolatility/USD"));
456 cgFilter.push_back(pair<string, string>(
"SwaptionVolatility/GBP",
"SwaptionVolatility/GBP"));
461QuantLib::ext::shared_ptr<Portfolio>
buildPortfolio(Size portfolioSize, QuantLib::ext::shared_ptr<EngineFactory> factory = {}) {
463 QuantLib::ext::shared_ptr<Portfolio> portfolio(
new Portfolio());
465 vector<string> ccys = {
"EUR",
"USD",
"GBP",
"JPY",
"CHF"};
467 map<string, vector<string>> indices = {{
"EUR", {
"EUR-EURIBOR-6M"}},
468 {
"USD", {
"USD-LIBOR-3M"}},
469 {
"GBP", {
"GBP-LIBOR-6M"}},
470 {
"CHF", {
"CHF-LIBOR-6M"}},
471 {
"JPY", {
"JPY-LIBOR-6M"}}};
473 vector<string> fixedTenors = {
"6M",
"1Y"};
480 Size minFixedBps = 10;
481 Size maxFixedBps = 400;
484 MersenneTwisterUniformRng rng(seed);
486 Calendar cal = TARGET();
487 string fixDC =
"30/360";
488 string floatDC =
"ACT/365";
490 Real notional = 1000000;
493 for (Size i = 0; i < portfolioSize; i++) {
496 string ccy = portfolioSize == 1 ?
"EUR" :
randString(rng, ccys);
497 string index = portfolioSize == 1 ?
"EUR-EURIBOR-6M" :
randString(rng, indices[ccy]);
498 string floatFreq = portfolioSize == 1 ?
"6M" : index.substr(index.find(
'-', 4) + 1);
501 Real fixedRate = portfolioSize == 1 ? 0.02 :
randInt(rng, minFixedBps, maxFixedBps) / 100.0;
502 string fixFreq = portfolioSize == 1 ?
"1Y" :
randString(rng, fixedTenors);
507 std::ostringstream oss;
510 oss <<
"Trade_" << i + 1;
511 string id = oss.str();
514 int start =
randInt(rng, minTerm, maxTerm);
515 Size term = portfolioSize == 1 ? 20 :
randInt(rng, minTerm, maxTerm);
516 string longShort =
randBoolean(rng) ?
"Long" :
"Short";
518 fixedRate, spread, fixFreq, fixDC, floatFreq, floatDC,
521 int start =
randInt(rng, minStart, maxStart);
522 Size end =
randInt(rng, minTerm, maxTerm);
523 portfolio->add(
testsuite::buildSwap(
id, ccy, isPayer, notional, start, end, fixedRate, spread, fixFreq,
524 fixDC, floatFreq, floatDC, index));
528 portfolio->build(factory);
530 BOOST_CHECK_MESSAGE(portfolio->size() == portfolioSize,
531 "Failed to build portfolio (got " << portfolio->size() <<
" expected " << portfolioSize <<
")");
536void test_performance(
bool bigPortfolio,
bool bigScenario,
bool lotsOfSensis,
bool crossGammas,
540 Size portfolioSize = bigPortfolio ? 100 : 1;
541 string om_str = (om == ObservationMode::Mode::None)
543 : (om == ObservationMode::Mode::Disable)
545 : (om == ObservationMode::Mode::Defer)
547 : (om == ObservationMode::Mode::Unregister) ?
"Unregister" :
"???";
548 string bigPfolioStr = bigPortfolio ?
"big" :
"small";
549 string bigScenarioStr = bigScenario ?
"big" :
"small";
550 string lotsOfSensisStr = lotsOfSensis ?
"lots" :
"few";
551 string crossGammasStr = crossGammas ?
"included" :
"excluded";
553 BOOST_TEST_MESSAGE(
"Testing Sensitivity Performance "
554 <<
"(portfolio=" << bigPfolioStr <<
")"
555 <<
"(scenarioSize=" << bigScenarioStr <<
")"
556 <<
"(numSensis=" << lotsOfSensisStr <<
")"
557 <<
"(crossGammas=" << crossGammasStr <<
")"
558 <<
"(observation=" << om_str <<
")...");
560 SavedSettings backup;
562 ObservationMode::instance().setMode(om);
564 Date today = Date(14, April, 2016);
565 Settings::instance().evaluationDate() = today;
568 QuantLib::ext::shared_ptr<Market> initMarket = QuantLib::ext::make_shared<testsuite::TestMarket>(today);
571 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> simMarketData =
setupSimMarketData5();
574 simMarketData = setupSimMarketData5Big();
577 sensiData = setupSensitivityScenarioData5Big();
580 addCrossGammas(sensiData->crossGammaFilter());
587 QuantLib::ext::shared_ptr<EngineData>
data = QuantLib::ext::make_shared<EngineData>();
588 data->model(
"Swap") =
"DiscountedCashflows";
589 data->engine(
"Swap") =
"DiscountingSwapEngine";
590 data->model(
"EuropeanSwaption") =
"BlackBachelier";
591 data->engine(
"EuropeanSwaption") =
"BlackBachelierSwaptionEngine";
593 QuantLib::ext::shared_ptr<Portfolio> portfolio =
buildPortfolio(portfolioSize);
597 QuantLib::ext::shared_ptr<SensitivityAnalysis> sa = QuantLib::ext::make_shared<SensitivityAnalysis>(
599 sa->generateSensitivities();
601 Real elapsed = t2.elapsed().wall * 1e-9;
602 Size numScenarios = sa->scenarioGenerator()->samples();
603 Size scenarioSize = sa->scenarioGenerator()->scenarios().front()->keys().size();
604 BOOST_TEST_MESSAGE(
"number of scenarios=" << numScenarios);
605 BOOST_TEST_MESSAGE(
"Size of scenario = " << scenarioSize <<
" keys");
606 BOOST_TEST_MESSAGE(
"time = " << elapsed <<
" seconds");
607 Real avTime = (elapsed / ((Real)(numScenarios * portfolioSize)));
608 BOOST_TEST_MESSAGE(
"Average pricing time = " << avTime <<
" seconds");
611 ObservationMode::instance().setMode(backupOm);
614 BOOST_TEST_MESSAGE(
"total time = " << t_base.format(default_places,
"%w") <<
" seconds");
620BOOST_AUTO_TEST_SUITE(SensitivityPerformanceTest, *boost::unit_test::disabled())
627 test_performance(
false,
false,
false,
false, ObservationMode::Mode::Disable);
635 test_performance(
false,
false,
false,
false, ObservationMode::Mode::Unregister);
666BOOST_AUTO_TEST_SUITE_END()
668BOOST_AUTO_TEST_SUITE_END()
ScenarioSimMarket description.
static const string defaultConfiguration
OREAnalytics Top level fixture.
Scenario generation using cross asset model paths.
unsigned long randInt(MersenneTwisterUniformRng &rng, Size min, Size max)
bool randBoolean(MersenneTwisterUniformRng &rng)
const string & randString(MersenneTwisterUniformRng &rng, const vector< string > &strs)
QuantLib::ext::shared_ptr< Portfolio > buildPortfolio(Size portfolioSize, QuantLib::ext::shared_ptr< EngineFactory > &factory)
Class that wraps a sensitivity stream and filters out negligible records.
A cube implementation that stores the cube in memory.
RandomVariable max(RandomVariable x, const RandomVariable &y)
RandomVariable min(RandomVariable x, const RandomVariable &y)
QuantLib::ext::shared_ptr< Trade > buildSwap(string id, string ccy, bool isPayer, Real notional, int start, Size term, Real rate, Real spread, string fixedFreq, string fixedDC, string floatFreq, string floatDC, string index, Calendar calendar, Natural spotDays, bool spotStartLag)
QuantLib::ext::shared_ptr< Trade > buildEuropeanSwaption(string id, string longShort, string ccy, bool isPayer, Real notional, int start, Size term, Real rate, Real spread, string fixedFreq, string fixedDC, string floatFreq, string floatDC, string index, string cashPhysical, Real premium, string premiumCcy, string premiumDate)
Singleton class to hold global Observation Mode.
Fixture that can be used at top level of OREAnalytics test suites.
Perform parametric var calculation for a given portfolio.
risk class and type filter
A Market class that can be updated by Scenarios.
A class to hold Scenario parameters for scenarioSimMarket.
Class for aggregating SensitivityRecords.
Perform sensitivity analysis for a given portfolio.
Class for streaming SensitivityRecords from a SensitivityCube.
Class for streaming SensitivityRecords from file.
Class for streaming SensitivityRecords from in-memory container.
Struct for holding a sensitivity record.
Base class for sensitivity record streamer.
factory classes for simple scenarios
perform a stress testing analysis for a given portfolio.
vector< Period > shiftTenors
vector< Period > shiftTerms
vector< Real > shiftStrikes
vector< Period > shiftExpiries
QuantLib::ext::shared_ptr< SensitivityScenarioData > setupSensitivityScenarioData5(bool parConversion)
QuantLib::ext::shared_ptr< analytics::ScenarioSimMarketParameters > setupSimMarketData5()
The counterparty cube calculator interface.