Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
parsensitivityanalysis.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
20#include "testmarket.hpp"
21#include "testportfolio.hpp"
22
24#include <orea/cube/npvcube.hpp>
36
52
53#include <ql/termstructures/yield/piecewiseyieldcurve.hpp>
54#include <ql/time/calendars/target.hpp>
55#include <ql/time/date.hpp>
56#include <ql/time/daycounters/actualactual.hpp>
57
59
60#include <boost/timer/timer.hpp>
61
62using namespace std;
63using namespace QuantLib;
64using namespace QuantExt;
65using namespace boost::unit_test_framework;
66using namespace ore;
67using namespace ore::data;
68using namespace ore::analytics;
69
70QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> setupSimMarketData2() {
71 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> simMarketData(
73 simMarketData->baseCcy() = "EUR";
74 simMarketData->ccys() = {"EUR", "GBP", "USD"};
75 simMarketData->setDiscountCurveNames({"EUR", "GBP", "USD"});
76 simMarketData->setYieldCurveTenors("", {1 * Months, 6 * Months, 1 * Years, 2 * Years, 3 * Years, 4 * Years,
77 5 * Years, 6 * Years, 7 * Years, 8 * Years, 9 * Years, 10 * Years,
78 12 * Years, 15 * Years, 20 * Years, 25 * Years, 30 * Years});
79 simMarketData->setIndices({"EUR-EURIBOR-6M", "GBP-LIBOR-6M"});
80 simMarketData->interpolation() = "LogLinear";
81
82 simMarketData->setDefaultNames({"BondIssuer1"});
83
84 simMarketData->setDefaultTenors(
85 "", {6 * Months, 1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 15 * Years, 20 * Years});
86 simMarketData->setSimulateSurvivalProbabilities(true);
87 simMarketData->setDefaultCurveCalendars("", "TARGET");
88
89 simMarketData->setSwapVolTerms(
90 "", {1 * Years, 2 * Years, 3 * Years, 4 * Years, 5 * Years, 7 * Years, 10 * Years, 20 * Years});
91 simMarketData->setSwapVolExpiries(
92 "", {6 * Months, 1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 20 * Years});
93 simMarketData->setSwapVolKeys({"EUR", "GBP"});
94 simMarketData->swapVolDecayMode() = "ForwardVariance";
95 simMarketData->setSimulateSwapVols(true);
96
97 simMarketData->setFxVolExpiries("",
98 vector<Period>{1 * Months, 3 * Months, 6 * Months, 2 * Years, 3 * Years, 4 * Years, 5 * Years});
99 simMarketData->setFxVolDecayMode(string("ConstantVariance"));
100 simMarketData->setSimulateFXVols(true);
101 simMarketData->setFxVolCcyPairs({"EURGBP"});
102 simMarketData->setFxVolIsSurface(true);
103 simMarketData->setFxVolMoneyness(vector<Real>{0.1, 0.5, 1, 1.5, 2, 2.5, 2});
104
105 simMarketData->setFxCcyPairs({"EURGBP"});
106
107 simMarketData->setSimulateCapFloorVols(false);
108 simMarketData->setEquityNames({"SP5", "Lufthansa"});
109 simMarketData->setEquityDividendTenors("SP5", {6 * Months, 1 * Years, 2 * Years});
110 simMarketData->setEquityDividendTenors("Lufthansa", {6 * Months, 1 * Years, 2 * Years});
111
112 simMarketData->setSimulateEquityVols(true);
113 simMarketData->setEquityVolDecayMode("ForwardVariance");
114 simMarketData->setEquityVolNames({"SP5", "Lufthansa"});
115 simMarketData->setEquityVolExpiries("", {2 * Weeks, 1 * Months, 3 * Months, 6 * Months, 1 * Years,
116 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years,
117 13 * Years, 15 * Years, 20 * Years, 30 * Years});
118 simMarketData->setEquityVolIsSurface("", true);
119 simMarketData->setEquityVolMoneyness("", {0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 1.0, 1.05, 1.1, 1.2,
120 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.5, 3.0});
121
122 simMarketData->setYoyInflationIndices({"UKRP1"});
123 simMarketData->setYoyInflationTenors(
124 "UKRP1", {1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 15 * Years, 20 * Years});
125
126 simMarketData->setSimulateYoYInflationCapFloorVols(true);
127 simMarketData->setYoYInflationCapFloorVolNames({"UKRP1"});
128 simMarketData->setYoYInflationCapFloorVolExpiries(
129 "UKRP1", {1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 15 * Years, 20 * Years});
130 simMarketData->setYoYInflationCapFloorVolStrikes("", {-0.02, -0.01, 0.00, 0.01, 0.02, 0.03});
131 simMarketData->yoyInflationCapFloorVolDecayMode() = "ForwardVariance";
132
133 return simMarketData;
134}
135
136QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> setupSimMarketData5() {
137 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> simMarketData(
139
140 simMarketData->baseCcy() = "EUR";
141
142 simMarketData->setDiscountCurveNames({"EUR", "GBP", "USD", "CHF", "JPY"});
143 simMarketData->setYieldCurveNames({"BondCurve1"});
144 simMarketData->yieldCurveCurrencies()["BondCurve1"] = "EUR";
145 simMarketData->setYieldCurveTenors("", {1 * Months, 6 * Months, 1 * Years, 2 * Years, 3 * Years, 4 * Years,
146 5 * Years, 7 * Years, 10 * Years, 15 * Years, 20 * Years, 30 * Years});
147 simMarketData->setIndices(
148 {"EUR-EURIBOR-6M", "USD-LIBOR-3M", "USD-LIBOR-6M", "GBP-LIBOR-6M", "CHF-LIBOR-6M", "JPY-LIBOR-6M"});
149 simMarketData->interpolation() = "LogLinear";
150
151 simMarketData->setDefaultNames({"BondIssuer1", "dc"});
152 simMarketData->setDefaultTenors(
153 "", {6 * Months, 1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 15 * Years, 20 * Years});
154 simMarketData->setSimulateSurvivalProbabilities(true);
155 simMarketData->setSecurities({"Bond1"});
156 simMarketData->setDefaultCurveCalendars("", "TARGET");
157
158 simMarketData->setSwapVolTerms("", {1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 20 * Years});
159 simMarketData->setSwapVolExpiries(
160 "", {6 * Months, 1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 20 * Years});
161 simMarketData->setSwapVolKeys({"EUR", "GBP", "USD", "CHF", "JPY"});
162 simMarketData->swapVolDecayMode() = "ForwardVariance";
163 simMarketData->setSimulateSwapVols(true); // false;
164
165 simMarketData->setFxVolExpiries("",
166 vector<Period>{1 * Months, 3 * Months, 6 * Months, 2 * Years, 3 * Years, 4 * Years, 5 * Years});
167 simMarketData->setFxVolDecayMode(string("ConstantVariance"));
168 simMarketData->setSimulateFXVols(true); // false;
169 simMarketData->setFxVolCcyPairs({"EURUSD", "EURGBP", "EURCHF", "EURJPY"});
170 simMarketData->setFxVolIsSurface(true);
171 simMarketData->setFxVolMoneyness(vector<Real>{0.1, 0.5, 1, 1.5, 2, 2.5, 3});
172
173 simMarketData->setFxCcyPairs({"EURUSD", "EURGBP", "EURCHF", "EURJPY"});
174
175 simMarketData->setSimulateCapFloorVols(true);
176 simMarketData->capFloorVolDecayMode() = "ForwardVariance";
177 simMarketData->setCapFloorVolKeys({"EUR", "USD"});
178 simMarketData->setCapFloorVolExpiries(
179 "", {6 * Months, 1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 15 * Years, 20 * Years});
180 simMarketData->setCapFloorVolStrikes("", {0.00, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06});
181
182 simMarketData->setSimulateCdsVols(true);
183 simMarketData->cdsVolExpiries() = {6 * Months, 1 * Years, 2 * Years, 3 * Years, 5 * Years, 10 * Years};
184 simMarketData->cdsVolDecayMode() = "ForwardVariance";
185 simMarketData->setCdsVolNames({"dc"});
186
187 simMarketData->setEquityNames({"SP5", "Lufthansa"});
188 simMarketData->setEquityDividendTenors("SP5", {6 * Months, 1 * Years, 2 * Years});
189 simMarketData->setEquityDividendTenors("Lufthansa", {6 * Months, 1 * Years, 2 * Years});
190
191 simMarketData->setSimulateEquityVols(true);
192 simMarketData->setEquityVolDecayMode("ForwardVariance");
193 simMarketData->setEquityVolNames({"SP5", "Lufthansa"});
194 simMarketData->setEquityVolExpiries("", {2 * Weeks, 1 * Months, 3 * Months, 6 * Months, 1 * Years,
195 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years,
196 13 * Years, 15 * Years, 20 * Years, 30 * Years});
197 simMarketData->setEquityVolIsSurface("", true);
198 simMarketData->setEquityVolMoneyness("", {0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 1.0, 1.05, 1.1, 1.2,
199 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.5, 3.0});
200
201 simMarketData->setYoyInflationIndices({"UKRP1"});
202 simMarketData->setYoyInflationTenors(
203 "UKRP1", {1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 15 * Years, 20 * Years});
204
205 simMarketData->setSimulateYoYInflationCapFloorVols(true);
206 simMarketData->setYoYInflationCapFloorVolNames({"UKRP1"});
207 simMarketData->setYoYInflationCapFloorVolExpiries(
208 "UKRP1", {1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 15 * Years, 20 * Years});
209 simMarketData->setYoYInflationCapFloorVolStrikes("", {-0.02, -0.01, 0.00, 0.01, 0.02, 0.03});
210 simMarketData->yoyInflationCapFloorVolDecayMode() = "ForwardVariance";
211
212 return simMarketData;
213}
214
217 cvsData.shiftTenors = {6 * Months, 1 * Years, 2 * Years, 3 * Years, 5 * Years,
218 7 * Years, 10 * Years, 15 * Years, 20 * Years}; // multiple tenors: triangular shifts
219 cvsData.shiftType = ShiftType::Absolute;
220 cvsData.shiftSize = 0.0001;
221 cvsData.parInstruments = {"DEP", "IRS", "IRS", "IRS", "IRS", "IRS", "IRS", "IRS", "IRS"};
222
223 return cvsData;
224}
225QuantLib::ext::shared_ptr<SensitivityScenarioData> setupSensitivityScenarioData2() {
226 QuantLib::ext::shared_ptr<SensitivityScenarioData> sensiData = QuantLib::ext::make_shared<SensitivityScenarioData>(false);
227
229 fxsData.shiftType = ShiftType::Relative;
230 fxsData.shiftSize = 0.01;
231
233 fxvsData.shiftType = ShiftType::Relative;
234 fxvsData.shiftSize = 1.0;
235 fxvsData.shiftExpiries = {2 * Years, 5 * Years};
236
238 cfvsData.shiftType = ShiftType::Absolute;
239 cfvsData.shiftSize = 0.0001;
240 cfvsData.shiftExpiries = {1 * Years, 2 * Years, 3 * Years, 5 * Years, 10 * Years};
241 cfvsData.shiftStrikes = {0.05};
242
244 swvsData.shiftType = ShiftType::Relative;
245 swvsData.shiftSize = 0.01;
246 swvsData.shiftExpiries = {3 * Years, 5 * Years, 10 * Years};
247 swvsData.shiftTerms = {2 * Years, 5 * Years, 10 * Years};
248
250 eurDiscountData.parInstrumentSingleCurve = true;
251 eurDiscountData.parInstrumentConventions["DEP"] = "EUR-DEP-CONVENTIONS";
252 eurDiscountData.parInstrumentConventions["IRS"] = "EUR-6M-SWAP-CONVENTIONS";
253 sensiData->discountCurveShiftData()["EUR"] =
254 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(eurDiscountData);
255
257 gbpDiscountData.parInstrumentSingleCurve = true;
258 gbpDiscountData.parInstrumentConventions["DEP"] = "GBP-DEP-CONVENTIONS";
259 gbpDiscountData.parInstrumentConventions["IRS"] = "GBP-6M-SWAP-CONVENTIONS";
260 sensiData->discountCurveShiftData()["GBP"] =
261 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(gbpDiscountData);
262
264 eurIndexData.parInstrumentSingleCurve = false;
265 eurIndexData.parInstrumentConventions["DEP"] = "EUR-DEP-CONVENTIONS";
266 eurIndexData.parInstrumentConventions["IRS"] = "EUR-6M-SWAP-CONVENTIONS";
267 sensiData->indexCurveShiftData()["EUR-EURIBOR-6M"] =
268 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(eurIndexData);
269
271 gbpIndexData.parInstrumentSingleCurve = false;
272 gbpIndexData.parInstrumentConventions["DEP"] = "GBP-DEP-CONVENTIONS";
273 gbpIndexData.parInstrumentConventions["IRS"] = "GBP-6M-SWAP-CONVENTIONS";
274 sensiData->indexCurveShiftData()["GBP-LIBOR-6M"] =
275 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(gbpIndexData);
276
277 sensiData->fxShiftData()["EURGBP"] = fxsData;
278
279 sensiData->fxVolShiftData()["EURGBP"] = fxvsData;
280
281 sensiData->swaptionVolShiftData()["EUR"] = swvsData;
282 sensiData->swaptionVolShiftData()["GBP"] = swvsData;
283
284 sensiData->creditCcys()["BondIssuer1"] = "EUR";
286 bondData.parInstruments = {"CDS", "CDS", "CDS", "CDS", "CDS", "CDS", "CDS", "CDS", "CDS"};
287 bondData.parInstrumentSingleCurve = false;
288 bondData.parInstrumentConventions["CDS"] = "CDS-STANDARD-CONVENTIONS";
289 sensiData->creditCurveShiftData()["BondIssuer1"] =
290 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(bondData);
291
293 eqsData.shiftType = ShiftType::Relative;
294 eqsData.shiftSize = 0.01;
295
297 eqvsData.shiftType = ShiftType::Relative;
298 eqvsData.shiftSize = 0.01;
299 eqvsData.shiftExpiries = {2 * Weeks, 1 * Months, 3 * Months, 6 * Months, 1 * Years, 2 * Years, 3 * Years,
300 5 * Years, 7 * Years, 10 * Years, 13 * Years, 15 * Years, 20 * Years, 30 * Years};
301
303 eqdivData.shiftType = ShiftType::Absolute;
304 eqdivData.shiftSize = 0.00001;
305 eqdivData.shiftTenors = {6 * Months, 1 * Years, 2 * Years};
306
307 sensiData->equityShiftData()["SP5"] = eqsData;
308 sensiData->equityShiftData()["Lufthansa"] = eqsData;
309
310 sensiData->equityVolShiftData()["SP5"] = eqvsData;
311 sensiData->equityVolShiftData()["Lufthansa"] = eqvsData;
312
313 QuantLib::ext::shared_ptr<ore::analytics::SensitivityScenarioData::CurveShiftParData> yinfData =
314 QuantLib::ext::make_shared<ore::analytics::SensitivityScenarioData::CurveShiftParData>();
315 yinfData->shiftType = ShiftType::Absolute;
316 yinfData->shiftSize = 0.0001;
317 yinfData->shiftTenors = {1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 15 * Years, 20 * Years};
318 yinfData->parInstruments = {"YYS", "YYS", "YYS", "YYS", "YYS", "YYS", "YYS", "YYS"};
319 yinfData->parInstrumentConventions["ZIS"] = "UKRP1";
320 yinfData->parInstrumentConventions["YYS"] = "UKRP1";
321 sensiData->yoyInflationCurveShiftData()["UKRP1"] = yinfData;
322
323 auto yinfCfData = QuantLib::ext::make_shared<ore::analytics::SensitivityScenarioData::CapFloorVolShiftParData>();
324 yinfCfData->shiftType = ShiftType::Absolute;
325 yinfCfData->shiftSize = 0.00001;
326 yinfCfData->shiftExpiries = {1 * Years, 2 * Years, 3 * Years, 5 * Years,
327 7 * Years, 10 * Years, 15 * Years, 20 * Years};
328 yinfCfData->shiftStrikes = {-0.02, -0.01, 0.00, 0.01, 0.02, 0.03};
329 yinfCfData->parInstruments = {"YYS", "YYS", "YYS", "YYS", "YYS", "YYS", "YYS", "YYS"};
330 yinfCfData->parInstrumentSingleCurve = false;
331 yinfCfData->parInstrumentConventions["ZIS"] = "UKRP1";
332 yinfCfData->parInstrumentConventions["YYS"] = "UKRP1";
333 sensiData->yoyInflationCapFloorVolShiftData()["UKRP1"] = yinfCfData;
334
335 return sensiData;
336}
337
338QuantLib::ext::shared_ptr<SensitivityScenarioData> setupSensitivityScenarioData5(bool parConversion) {
339 QuantLib::ext::shared_ptr<SensitivityScenarioData> sensiData =
340 QuantLib::ext::make_shared<SensitivityScenarioData>(parConversion);
341
343
344 fxsData.shiftType = ShiftType::Relative;
345 fxsData.shiftSize = 0.01;
346
348 fxvsData.shiftType = ShiftType::Relative;
349 fxvsData.shiftSize = 1.0;
350 fxvsData.shiftExpiries = {5 * Years};
351
353 cfvsData.shiftType = ShiftType::Absolute;
354 cfvsData.shiftSize = 0.0001;
355 cfvsData.shiftExpiries = {1 * Years, 2 * Years, 3 * Years, 5 * Years, 10 * Years};
356 cfvsData.shiftStrikes = {0.01, 0.02, 0.03, 0.04, 0.05};
357
359 swvsData.shiftType = ShiftType::Relative;
360 swvsData.shiftSize = 0.01;
361 swvsData.shiftExpiries = {2 * Years, 5 * Years, 10 * Years};
362 swvsData.shiftTerms = {5 * Years, 10 * Years};
363
365 cdsvsData.shiftType = ShiftType::Relative;
366 cdsvsData.shiftSize = 0.01;
367 cdsvsData.shiftExpiries = {6 * Months, 1 * Years, 2 * Years, 3 * Years, 5 * Years, 10 * Years};
368
369 // sensiData->creditCurveShiftData()["dc"] = cvsData;
370
372 eurDiscountData.parInstrumentSingleCurve = true;
373 eurDiscountData.parInstrumentConventions["DEP"] = "EUR-DEP-CONVENTIONS";
374 eurDiscountData.parInstrumentConventions["IRS"] = "EUR-6M-SWAP-CONVENTIONS";
375 sensiData->discountCurveShiftData()["EUR"] =
376 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(eurDiscountData);
377
379 usdDiscountData.parInstrumentSingleCurve = true;
380 usdDiscountData.parInstrumentConventions["DEP"] = "USD-DEP-CONVENTIONS";
381 usdDiscountData.parInstrumentConventions["IRS"] = "USD-3M-SWAP-CONVENTIONS";
382 sensiData->discountCurveShiftData()["USD"] =
383 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(usdDiscountData);
384
386 gbpDiscountData.parInstrumentSingleCurve = true;
387 gbpDiscountData.parInstrumentConventions["DEP"] = "GBP-DEP-CONVENTIONS";
388 gbpDiscountData.parInstrumentConventions["IRS"] = "GBP-6M-SWAP-CONVENTIONS";
389 sensiData->discountCurveShiftData()["GBP"] =
390 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(gbpDiscountData);
391
393 jpyDiscountData.parInstrumentSingleCurve = true;
394 jpyDiscountData.parInstrumentConventions["DEP"] = "JPY-DEP-CONVENTIONS";
395 jpyDiscountData.parInstrumentConventions["IRS"] = "JPY-6M-SWAP-CONVENTIONS";
396 sensiData->discountCurveShiftData()["JPY"] =
397 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(jpyDiscountData);
398
400 chfDiscountData.parInstrumentSingleCurve = true;
401 chfDiscountData.parInstrumentConventions["DEP"] = "CHF-DEP-CONVENTIONS";
402 chfDiscountData.parInstrumentConventions["IRS"] = "CHF-6M-SWAP-CONVENTIONS";
403 sensiData->discountCurveShiftData()["CHF"] =
404 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(chfDiscountData);
405
407 bondData.parInstrumentSingleCurve = true;
408 bondData.parInstrumentConventions["DEP"] = "EUR-DEP-CONVENTIONS";
409 bondData.parInstrumentConventions["IRS"] = "EUR-6M-SWAP-CONVENTIONS";
410 sensiData->yieldCurveShiftData()["BondCurve1"] =
411 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(bondData);
412
414 eurIndexData.parInstrumentSingleCurve = false;
415 eurIndexData.parInstrumentConventions["DEP"] = "EUR-DEP-CONVENTIONS";
416 eurIndexData.parInstrumentConventions["IRS"] = "EUR-6M-SWAP-CONVENTIONS";
417 sensiData->indexCurveShiftData()["EUR-EURIBOR-6M"] =
418 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(eurIndexData);
419
421 usdIndexData.parInstrumentSingleCurve = false;
422 usdIndexData.parInstrumentConventions["DEP"] = "USD-DEP-CONVENTIONS";
423 usdIndexData.parInstrumentConventions["IRS"] = "USD-3M-SWAP-CONVENTIONS";
424 sensiData->indexCurveShiftData()["USD-LIBOR-3M"] =
425 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(usdIndexData);
426
428 gbpIndexData.parInstrumentSingleCurve = false;
429 gbpIndexData.parInstrumentConventions["DEP"] = "GBP-DEP-CONVENTIONS";
430 gbpIndexData.parInstrumentConventions["IRS"] = "GBP-6M-SWAP-CONVENTIONS";
431 sensiData->indexCurveShiftData()["GBP-LIBOR-6M"] =
432 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(gbpIndexData);
433
435 jpyIndexData.parInstrumentSingleCurve = false;
436 jpyIndexData.parInstrumentConventions["DEP"] = "JPY-DEP-CONVENTIONS";
437 jpyIndexData.parInstrumentConventions["IRS"] = "JPY-6M-SWAP-CONVENTIONS";
438 sensiData->indexCurveShiftData()["JPY-LIBOR-6M"] =
439 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(jpyIndexData);
440
442 chfIndexData.parInstrumentSingleCurve = false;
443 chfIndexData.parInstrumentConventions["DEP"] = "CHF-DEP-CONVENTIONS";
444 chfIndexData.parInstrumentConventions["IRS"] = "CHF-6M-SWAP-CONVENTIONS";
445 sensiData->indexCurveShiftData()["CHF-LIBOR-6M"] =
446 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(chfIndexData);
447
448 sensiData->fxShiftData()["EURUSD"] = fxsData;
449 sensiData->fxShiftData()["EURGBP"] = fxsData;
450 sensiData->fxShiftData()["EURJPY"] = fxsData;
451 sensiData->fxShiftData()["EURCHF"] = fxsData;
452
453 sensiData->fxVolShiftData()["EURUSD"] = fxvsData;
454 sensiData->fxVolShiftData()["EURGBP"] = fxvsData;
455 sensiData->fxVolShiftData()["EURJPY"] = fxvsData;
456 sensiData->fxVolShiftData()["EURCHF"] = fxvsData;
457
458 sensiData->swaptionVolShiftData()["EUR"] = swvsData;
459 sensiData->swaptionVolShiftData()["GBP"] = swvsData;
460 sensiData->swaptionVolShiftData()["USD"] = swvsData;
461 sensiData->swaptionVolShiftData()["JPY"] = swvsData;
462 sensiData->swaptionVolShiftData()["CHF"] = swvsData;
463
464 sensiData->capFloorVolShiftData()["EUR"] =
465 QuantLib::ext::make_shared<SensitivityScenarioData::CapFloorVolShiftData>(cfvsData);
466 sensiData->capFloorVolShiftData()["EUR"]->indexName = "EUR-EURIBOR-6M";
467 sensiData->capFloorVolShiftData()["USD"] =
468 QuantLib::ext::make_shared<SensitivityScenarioData::CapFloorVolShiftData>(cfvsData);
469 sensiData->capFloorVolShiftData()["USD"]->indexName = "USD-LIBOR-3M";
470
472 dcData.parInstruments = {"CDS", "CDS", "CDS", "CDS", "CDS", "CDS", "CDS", "CDS", "CDS"};
473 dcData.parInstrumentSingleCurve = false;
474 dcData.parInstrumentConventions["CDS"] = "CDS-STANDARD-CONVENTIONS";
475 sensiData->creditCurveShiftData()["dc"] =
476 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(dcData);
477 sensiData->creditCcys()["dc"] = "EUR";
478
480 bondIssData.parInstruments = {"CDS", "CDS", "CDS", "CDS", "CDS", "CDS", "CDS", "CDS", "CDS"};
481 bondIssData.parInstrumentSingleCurve = false;
482 bondIssData.parInstrumentConventions["CDS"] = "CDS-STANDARD-CONVENTIONS";
483 sensiData->creditCurveShiftData()["BondIssuer1"] =
484 QuantLib::ext::make_shared<SensitivityScenarioData::CurveShiftParData>(bondIssData);
485 sensiData->creditCcys()["BondIssuer1"] = "EUR";
486
487 sensiData->cdsVolShiftData()["dc"] = cdsvsData;
488
490 eqsData.shiftType = ShiftType::Relative;
491 eqsData.shiftSize = 0.01;
492
494 eqvsData.shiftType = ShiftType::Relative;
495 eqvsData.shiftSize = 0.01;
496 eqvsData.shiftExpiries = {2 * Weeks, 1 * Months, 3 * Months, 6 * Months, 1 * Years, 2 * Years, 3 * Years,
497 5 * Years, 10 * Years, 13 * Years, 15 * Years, 20 * Years, 30 * Years};
498
500 eqdivData.shiftType = ShiftType::Absolute;
501 eqdivData.shiftSize = 0.00001;
502 eqdivData.shiftTenors = {6 * Months, 1 * Years, 2 * Years};
503
504 sensiData->equityShiftData()["SP5"] = eqsData;
505 sensiData->equityShiftData()["Lufthansa"] = eqsData;
506
507 sensiData->equityVolShiftData()["SP5"] = eqvsData;
508 sensiData->equityVolShiftData()["Lufthansa"] = eqvsData;
509
510 QuantLib::ext::shared_ptr<ore::analytics::SensitivityScenarioData::CurveShiftParData> yinfData =
511 QuantLib::ext::make_shared<ore::analytics::SensitivityScenarioData::CurveShiftParData>();
512 yinfData->shiftType = ShiftType::Absolute;
513 yinfData->shiftSize = 0.0001;
514 yinfData->shiftTenors = {1 * Years, 2 * Years, 3 * Years, 5 * Years, 7 * Years, 10 * Years, 15 * Years, 20 * Years};
515 yinfData->parInstruments = {"YYS", "YYS", "YYS", "YYS", "YYS", "YYS", "YYS", "YYS"};
516 yinfData->parInstrumentConventions["ZIS"] = "UKRP1";
517 yinfData->parInstrumentConventions["YYS"] = "UKRP1";
518 sensiData->yoyInflationCurveShiftData()["UKRP1"] = yinfData;
519
520 auto yinfCfData = QuantLib::ext::make_shared<ore::analytics::SensitivityScenarioData::CapFloorVolShiftParData>();
521 yinfCfData->shiftType = ShiftType::Absolute;
522 yinfCfData->shiftSize = 0.00001;
523 yinfCfData->shiftExpiries = {1 * Years, 2 * Years, 3 * Years, 5 * Years,
524 7 * Years, 10 * Years, 15 * Years, 20 * Years};
525 yinfCfData->shiftStrikes = {-0.02, -0.01, 0.00, 0.01, 0.02, 0.03};
526 yinfCfData->parInstruments = {"YYS", "YYS", "YYS", "YYS", "YYS", "YYS", "YYS", "YYS"};
527 yinfCfData->parInstrumentSingleCurve = false;
528 yinfCfData->parInstrumentConventions["ZIS"] = "UKRP1";
529 yinfCfData->parInstrumentConventions["YYS"] = "UKRP1";
530 sensiData->yoyInflationCapFloorVolShiftData()["UKRP1"] = yinfCfData;
531
532 return sensiData;
533}
534
535namespace testsuite {
536
538 BOOST_TEST_MESSAGE("Testing Portfolio sensitivity");
539
540 SavedSettings backup;
541 ObservationMode::Mode backupMode = ObservationMode::instance().mode();
542 ObservationMode::instance().setMode(ObservationMode::Mode::None);
543
544 Date today = Date(14, April, 2016); // Settings::instance().evaluationDate();
545 Settings::instance().evaluationDate() = today;
546
547 BOOST_TEST_MESSAGE("Today is " << today);
548
549 // Init market
550 QuantLib::ext::shared_ptr<Market> initMarket = QuantLib::ext::make_shared<TestMarket>(today);
551
552 // build scenario sim market parameters
553 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> simMarketData = setupSimMarketData5();
554
555 // sensitivity config
556 QuantLib::ext::shared_ptr<SensitivityScenarioData> sensiData = setupSensitivityScenarioData5(false);
557 // build scenario sim market
558 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarket> simMarket =
559 QuantLib::ext::make_shared<analytics::ScenarioSimMarket>(initMarket, simMarketData);
560
561 // build scenario factory
562 QuantLib::ext::shared_ptr<Scenario> baseScenario = simMarket->baseScenario();
563 QuantLib::ext::shared_ptr<ScenarioFactory> scenarioFactory =
564 QuantLib::ext::make_shared<ore::analytics::DeltaScenarioFactory>(baseScenario);
565
566 // build scenario generator
567 QuantLib::ext::shared_ptr<SensitivityScenarioGenerator> scenarioGenerator =
568 QuantLib::ext::make_shared<SensitivityScenarioGenerator>(sensiData, baseScenario, simMarketData, simMarket,
569 scenarioFactory, false);
570 simMarket->scenarioGenerator() = scenarioGenerator;
571
572 // build porfolio
573 QuantLib::ext::shared_ptr<EngineData> data = QuantLib::ext::make_shared<EngineData>();
574 data->model("Swap") = "DiscountedCashflows";
575 data->engine("Swap") = "DiscountingSwapEngine";
576 data->model("CrossCurrencySwap") = "DiscountedCashflows";
577 data->engine("CrossCurrencySwap") = "DiscountingCrossCurrencySwapEngine";
578 data->model("EuropeanSwaption") = "BlackBachelier";
579 data->engine("EuropeanSwaption") = "BlackBachelierSwaptionEngine";
580 data->model("FxForward") = "DiscountedCashflows";
581 data->engine("FxForward") = "DiscountingFxForwardEngine";
582 data->model("FxOption") = "GarmanKohlhagen";
583 data->engine("FxOption") = "AnalyticEuropeanEngine";
584 data->model("CapFloor") = "IborCapModel";
585 data->engine("CapFloor") = "IborCapEngine";
586 data->model("CapFlooredIborLeg") = "BlackOrBachelier";
587 data->engine("CapFlooredIborLeg") = "BlackIborCouponPricer";
588 data->model("YYCapFloor") = "YYCapModel";
589 data->engine("YYCapFloor") = "YYCapEngine";
590 data->model("IndexCreditDefaultSwapOption") = "Black";
591 data->engine("IndexCreditDefaultSwapOption") = "BlackIndexCdsOptionEngine";
592 map<string, string> engineParamMap1;
593 engineParamMap1["Curve"] = "Underlying";
594 data->engineParameters("IndexCreditDefaultSwapOption") = engineParamMap1;
595
596 data->model("IndexCreditDefaultSwap") = "DiscountedCashflows";
597 data->engine("IndexCreditDefaultSwap") = "MidPointIndexCdsEngine";
598 map<string, string> engineParamMap2;
599 engineParamMap2["Curve"] = "Underlying";
600 data->engineParameters("IndexCreditDefaultSwap") = engineParamMap2;
601 data->model("Bond") = "DiscountedCashflows";
602 data->engine("Bond") = "DiscountingRiskyBondEngine";
603 data->engineParameters("Bond")["TimestepPeriod"] = "6M";
604 data->model("EquityOption") = "BlackScholesMerton";
605 data->engine("EquityOption") = "AnalyticEuropeanEngine";
606 QuantLib::ext::shared_ptr<EngineFactory> factory = QuantLib::ext::make_shared<EngineFactory>(data, simMarket);
607
608 // QuantLib::ext::shared_ptr<Portfolio> portfolio = buildSwapPortfolio(portfolioSize, factory);
609 QuantLib::ext::shared_ptr<Portfolio> portfolio(new Portfolio());
610 portfolio->add(buildSwap("1_Swap_EUR", "EUR", true, 10000000.0, 0, 10, 0.03, 0.00, "1Y",
611 "30/360", "6M", "A360", "EUR-EURIBOR-6M"));
612 portfolio->add(buildSwap("2_Swap_USD", "USD", true, 10000000.0, 0, 15, 0.02, 0.00, "6M",
613 "30/360", "3M", "A360", "USD-LIBOR-3M"));
614 portfolio->add(buildSwap("3_Swap_GBP", "GBP", true, 10000000.0, 0, 20, 0.04, 0.00, "6M",
615 "30/360", "3M", "A360", "GBP-LIBOR-6M"));
616 portfolio->add(buildSwap("4_Swap_JPY", "JPY", true, 1000000000.0, 0, 5, 0.01, 0.00, "6M",
617 "30/360", "3M", "A360", "JPY-LIBOR-6M"));
618 portfolio->add(buildEuropeanSwaption("5_Swaption_EUR", "Long", "EUR", true, 1000000.0, 10, 10,
619 0.02, 0.00, "1Y", "30/360", "6M", "A360", "EUR-EURIBOR-6M",
620 "Physical"));
621 portfolio->add(buildEuropeanSwaption("6_Swaption_EUR", "Long", "EUR", true, 1000000.0, 2, 5,
622 0.02, 0.00, "1Y", "30/360", "6M", "A360", "EUR-EURIBOR-6M",
623 "Physical"));
624 portfolio->add(buildFxOption("7_FxOption_EUR_USD", "Long", "Call", 3, "EUR", 10000000.0, "USD",
625 11000000.0));
626 portfolio->add(buildFxOption("8_FxOption_EUR_GBP", "Long", "Call", 7, "EUR", 10000000.0, "GBP",
627 11000000.0));
628 portfolio->add(buildCap("9_Cap_EUR", "EUR", "Long", 0.05, 1000000.0, 0, 10, "6M", "A360",
629 "EUR-EURIBOR-6M"));
630 portfolio->add(buildFloor("10_Floor_USD", "USD", "Long", 0.01, 1000000.0, 0, 10, "3M", "A360",
631 "USD-LIBOR-3M"));
632
633 // vector<string> names(1, "dc");
634 // vector<string> ccys(1, "EUR");
635 // vector<Real> notionals(1, 1000000.0);
636 // QuantLib::ext::shared_ptr<CdsConvention> cdsConv =
637 // QuantLib::ext::dynamic_pointer_cast<CdsConvention>(InstrumentConventions::instance().conventions()->get("CDS-STANDARD-CONVENTIONS"));
638 // portfolio->add(buildIndexCdsOption(
639 // "11_CDSOption_EUR", "dc", names, "Long", "EUR", ccys, true, notionals, 1000000.0, 1, 4, 0.4, 0.1,
640 // ore::data::to_string(Period(cdsConv->frequency())), ore::data::to_string(cdsConv->dayCounter()),
641 // "Physical"));
642 portfolio->add(
643 buildEquityOption("12_EquityOption_SP5", "Long", "Call", 2, "SP5", "USD", 2147.56, 1000));
644 portfolio->add(buildEquityOption("13_EquityOption_Lufthansa", "Long", "Call", 2, "Lufthansa",
645 "EUR", 12.75, 775));
646
647 portfolio->add(buildYYInflationCapFloor("14_YoYInflationCap_UKRPI", "GBP", 100000.0, true, true,
648 0.02, 0, 10, "1Y", "ACT/ACT", "UKRP1", "2M", 2));
649 portfolio->build(factory);
650
651 BOOST_TEST_MESSAGE("Portfolio size after build: " << portfolio->size());
652 // build the scenario valuation engine
653 QuantLib::ext::shared_ptr<DateGrid> dg = QuantLib::ext::make_shared<DateGrid>(
654 "1,0W"); // TODO - extend the DateGrid interface so that it can actually take a vector of dates as input
655 vector<QuantLib::ext::shared_ptr<ValuationCalculator>> calculators;
656 calculators.push_back(QuantLib::ext::make_shared<NPVCalculator>(simMarketData->baseCcy()));
657 ValuationEngine engine(today, dg, simMarket);
658 // run scenarios and fill the cube
659 boost::timer::cpu_timer t;
660 QuantLib::ext::shared_ptr<NPVCube> cube = QuantLib::ext::make_shared<DoublePrecisionInMemoryCube>(
661 today, portfolio->ids(), vector<Date>(1, today), scenarioGenerator->samples());
662 engine.buildCube(portfolio, cube, calculators);
663 double elapsed = t.elapsed().wall * 1e-9;
664
665 struct Results {
666 string id;
667 string label;
668 Real npv;
669 Real sensi;
670 };
671
672 std::vector<Results> cachedResults = {
673 {"1_Swap_EUR", "Up:DiscountCurve/EUR/0/6M", -928826, -2.51631},
674 {"1_Swap_EUR", "Up:DiscountCurve/EUR/1/1Y", -928826, 14.6846},
675 {"1_Swap_EUR", "Up:DiscountCurve/EUR/2/2Y", -928826, 19.0081},
676 {"1_Swap_EUR", "Up:DiscountCurve/EUR/3/3Y", -928826, 46.1186},
677 {"1_Swap_EUR", "Up:DiscountCurve/EUR/4/5Y", -928826, 85.1033},
678 {"1_Swap_EUR", "Up:DiscountCurve/EUR/5/7Y", -928826, 149.43},
679 {"1_Swap_EUR", "Up:DiscountCurve/EUR/6/10Y", -928826, 205.064},
680 {"1_Swap_EUR", "Down:DiscountCurve/EUR/0/6M", -928826, 2.51644},
681 {"1_Swap_EUR", "Down:DiscountCurve/EUR/1/1Y", -928826, -14.6863},
682 {"1_Swap_EUR", "Down:DiscountCurve/EUR/2/2Y", -928826, -19.0137},
683 {"1_Swap_EUR", "Down:DiscountCurve/EUR/3/3Y", -928826, -46.1338},
684 {"1_Swap_EUR", "Down:DiscountCurve/EUR/4/5Y", -928826, -85.1406},
685 {"1_Swap_EUR", "Down:DiscountCurve/EUR/5/7Y", -928826, -149.515},
686 {"1_Swap_EUR", "Down:DiscountCurve/EUR/6/10Y", -928826, -205.239},
687 {"1_Swap_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/0/6M", -928826, -495.013},
688 {"1_Swap_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/1/1Y", -928826, 14.7304},
689 {"1_Swap_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/2/2Y", -928826, 38.7816},
690 {"1_Swap_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/3/3Y", -928826, 94.186},
691 {"1_Swap_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/4/5Y", -928826, 173.125},
692 {"1_Swap_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/5/7Y", -928826, 304.648},
693 {"1_Swap_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/6/10Y", -928826, 8479.55},
694 {"1_Swap_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/0/6M", -928826, 495.037},
695 {"1_Swap_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/1/1Y", -928826, -14.5864},
696 {"1_Swap_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/2/2Y", -928826, -38.4045},
697 {"1_Swap_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/3/3Y", -928826, -93.532},
698 {"1_Swap_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/4/5Y", -928826, -171.969},
699 {"1_Swap_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/5/7Y", -928826, -302.864},
700 {"1_Swap_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/6/10Y", -928826, -8478.14},
701 {"2_Swap_USD", "Up:DiscountCurve/USD/0/6M", 980404, -1.04797},
702 {"2_Swap_USD", "Up:DiscountCurve/USD/1/1Y", 980404, -6.06931},
703 {"2_Swap_USD", "Up:DiscountCurve/USD/2/2Y", 980404, -15.8605},
704 {"2_Swap_USD", "Up:DiscountCurve/USD/3/3Y", 980404, -38.0708},
705 {"2_Swap_USD", "Up:DiscountCurve/USD/4/5Y", 980404, -68.7288},
706 {"2_Swap_USD", "Up:DiscountCurve/USD/5/7Y", 980404, -118.405},
707 {"2_Swap_USD", "Up:DiscountCurve/USD/6/10Y", 980404, -244.946},
708 {"2_Swap_USD", "Up:DiscountCurve/USD/7/15Y", 980404, -202.226},
709 {"2_Swap_USD", "Up:DiscountCurve/USD/8/20Y", 980404, 0.0148314},
710 {"2_Swap_USD", "Down:DiscountCurve/USD/0/6M", 980404, 1.04797},
711 {"2_Swap_USD", "Down:DiscountCurve/USD/1/1Y", 980404, 6.06959},
712 {"2_Swap_USD", "Down:DiscountCurve/USD/2/2Y", 980404, 15.8623},
713 {"2_Swap_USD", "Down:DiscountCurve/USD/3/3Y", 980404, 38.0784},
714 {"2_Swap_USD", "Down:DiscountCurve/USD/4/5Y", 980404, 68.7502},
715 {"2_Swap_USD", "Down:DiscountCurve/USD/5/7Y", 980404, 118.458},
716 {"2_Swap_USD", "Down:DiscountCurve/USD/6/10Y", 980404, 245.108},
717 {"2_Swap_USD", "Down:DiscountCurve/USD/7/15Y", 980404, 202.42},
718 {"2_Swap_USD", "Down:DiscountCurve/USD/8/20Y", 980404, -0.0148314},
719 {"2_Swap_USD", "Up:IndexCurve/USD-LIBOR-3M/0/6M", 980404, -201.015},
720 {"2_Swap_USD", "Up:IndexCurve/USD-LIBOR-3M/1/1Y", 980404, 18.134},
721 {"2_Swap_USD", "Up:IndexCurve/USD-LIBOR-3M/2/2Y", 980404, 47.3066},
722 {"2_Swap_USD", "Up:IndexCurve/USD-LIBOR-3M/3/3Y", 980404, 113.4},
723 {"2_Swap_USD", "Up:IndexCurve/USD-LIBOR-3M/4/5Y", 980404, 205.068},
724 {"2_Swap_USD", "Up:IndexCurve/USD-LIBOR-3M/5/7Y", 980404, 352.859},
725 {"2_Swap_USD", "Up:IndexCurve/USD-LIBOR-3M/6/10Y", 980404, 730.076},
726 {"2_Swap_USD", "Up:IndexCurve/USD-LIBOR-3M/7/15Y", 980404, 8626.78},
727 {"2_Swap_USD", "Up:IndexCurve/USD-LIBOR-3M/8/20Y", 980404, 5.86437},
728 {"2_Swap_USD", "Down:IndexCurve/USD-LIBOR-3M/0/6M", 980404, 201.03},
729 {"2_Swap_USD", "Down:IndexCurve/USD-LIBOR-3M/1/1Y", 980404, -18.0746},
730 {"2_Swap_USD", "Down:IndexCurve/USD-LIBOR-3M/2/2Y", 980404, -47.1526},
731 {"2_Swap_USD", "Down:IndexCurve/USD-LIBOR-3M/3/3Y", 980404, -113.136},
732 {"2_Swap_USD", "Down:IndexCurve/USD-LIBOR-3M/4/5Y", 980404, -204.611},
733 {"2_Swap_USD", "Down:IndexCurve/USD-LIBOR-3M/5/7Y", 980404, -352.166},
734 {"2_Swap_USD", "Down:IndexCurve/USD-LIBOR-3M/6/10Y", 980404, -729.248},
735 {"2_Swap_USD", "Down:IndexCurve/USD-LIBOR-3M/7/15Y", 980404, -8626.13},
736 {"2_Swap_USD", "Down:IndexCurve/USD-LIBOR-3M/8/20Y", 980404, -5.86436},
737 {"2_Swap_USD", "Up:FXSpot/EURUSD/0/spot", 980404, -9706.97},
738 {"2_Swap_USD", "Down:FXSpot/EURUSD/0/spot", 980404, 9903.07},
739 {"3_Swap_GBP", "Up:DiscountCurve/GBP/0/6M", 69795.3, 2.12392},
740 {"3_Swap_GBP", "Up:DiscountCurve/GBP/1/1Y", 69795.3, -0.646097},
741 {"3_Swap_GBP", "Up:DiscountCurve/GBP/2/2Y", 69795.3, -1.75066},
742 {"3_Swap_GBP", "Up:DiscountCurve/GBP/3/3Y", 69795.3, -4.24827},
743 {"3_Swap_GBP", "Up:DiscountCurve/GBP/4/5Y", 69795.3, -7.2252},
744 {"3_Swap_GBP", "Up:DiscountCurve/GBP/5/7Y", 69795.3, -12.5287},
745 {"3_Swap_GBP", "Up:DiscountCurve/GBP/6/10Y", 69795.3, -24.7828},
746 {"3_Swap_GBP", "Up:DiscountCurve/GBP/7/15Y", 69795.3, -39.2456},
747 {"3_Swap_GBP", "Up:DiscountCurve/GBP/8/20Y", 69795.3, 31.2081},
748 {"3_Swap_GBP", "Down:DiscountCurve/GBP/0/6M", 69795.3, -2.12413},
749 {"3_Swap_GBP", "Down:DiscountCurve/GBP/1/1Y", 69795.3, 0.645698},
750 {"3_Swap_GBP", "Down:DiscountCurve/GBP/2/2Y", 69795.3, 1.74981},
751 {"3_Swap_GBP", "Down:DiscountCurve/GBP/3/3Y", 69795.3, 4.2473},
752 {"3_Swap_GBP", "Down:DiscountCurve/GBP/4/5Y", 69795.3, 7.22426},
753 {"3_Swap_GBP", "Down:DiscountCurve/GBP/5/7Y", 69795.3, 12.5298},
754 {"3_Swap_GBP", "Down:DiscountCurve/GBP/6/10Y", 69795.3, 24.7939},
755 {"3_Swap_GBP", "Down:DiscountCurve/GBP/7/15Y", 69795.3, 39.2773},
756 {"3_Swap_GBP", "Down:DiscountCurve/GBP/8/20Y", 69795.3, -31.2925},
757 {"3_Swap_GBP", "Up:IndexCurve/GBP-LIBOR-6M/0/6M", 69795.3, -308.49},
758 {"3_Swap_GBP", "Up:IndexCurve/GBP-LIBOR-6M/1/1Y", 69795.3, 68.819},
759 {"3_Swap_GBP", "Up:IndexCurve/GBP-LIBOR-6M/2/2Y", 69795.3, 81.3735},
760 {"3_Swap_GBP", "Up:IndexCurve/GBP-LIBOR-6M/3/3Y", 69795.3, 239.034},
761 {"3_Swap_GBP", "Up:IndexCurve/GBP-LIBOR-6M/4/5Y", 69795.3, 372.209},
762 {"3_Swap_GBP", "Up:IndexCurve/GBP-LIBOR-6M/5/7Y", 69795.3, 654.949},
763 {"3_Swap_GBP", "Up:IndexCurve/GBP-LIBOR-6M/6/10Y", 69795.3, 1343.01},
764 {"3_Swap_GBP", "Up:IndexCurve/GBP-LIBOR-6M/7/15Y", 69795.3, 2139.68},
765 {"3_Swap_GBP", "Up:IndexCurve/GBP-LIBOR-6M/8/20Y", 69795.3, 12633.8},
766 {"3_Swap_GBP", "Down:IndexCurve/GBP-LIBOR-6M/0/6M", 69795.3, 308.513},
767 {"3_Swap_GBP", "Down:IndexCurve/GBP-LIBOR-6M/1/1Y", 69795.3, -68.7287},
768 {"3_Swap_GBP", "Down:IndexCurve/GBP-LIBOR-6M/2/2Y", 69795.3, -81.1438},
769 {"3_Swap_GBP", "Down:IndexCurve/GBP-LIBOR-6M/3/3Y", 69795.3, -238.649},
770 {"3_Swap_GBP", "Down:IndexCurve/GBP-LIBOR-6M/4/5Y", 69795.3, -371.553},
771 {"3_Swap_GBP", "Down:IndexCurve/GBP-LIBOR-6M/5/7Y", 69795.3, -653.972},
772 {"3_Swap_GBP", "Down:IndexCurve/GBP-LIBOR-6M/6/10Y", 69795.3, -1341.88},
773 {"3_Swap_GBP", "Down:IndexCurve/GBP-LIBOR-6M/7/15Y", 69795.3, -2138.11},
774 {"3_Swap_GBP", "Down:IndexCurve/GBP-LIBOR-6M/8/20Y", 69795.3, -12632.5},
775 {"3_Swap_GBP", "Up:FXSpot/EURGBP/0/spot", 69795.3, -691.043},
776 {"3_Swap_GBP", "Down:FXSpot/EURGBP/0/spot", 69795.3, 705.003},
777 {"4_Swap_JPY", "Up:DiscountCurve/JPY/0/6M", 871.03, -0.00750246},
778 {"4_Swap_JPY", "Up:DiscountCurve/JPY/1/1Y", 871.03, -0.00147994},
779 {"4_Swap_JPY", "Up:DiscountCurve/JPY/2/2Y", 871.03, -0.020079},
780 {"4_Swap_JPY", "Up:DiscountCurve/JPY/3/3Y", 871.03, -0.0667249},
781 {"4_Swap_JPY", "Up:DiscountCurve/JPY/4/5Y", 871.03, 4.75708},
782 {"4_Swap_JPY", "Down:DiscountCurve/JPY/0/6M", 871.03, 0.00747801},
783 {"4_Swap_JPY", "Down:DiscountCurve/JPY/1/1Y", 871.03, 0.00140807},
784 {"4_Swap_JPY", "Down:DiscountCurve/JPY/2/2Y", 871.03, 0.0199001},
785 {"4_Swap_JPY", "Down:DiscountCurve/JPY/3/3Y", 871.03, 0.0664106},
786 {"4_Swap_JPY", "Down:DiscountCurve/JPY/4/5Y", 871.03, -4.75978},
787 {"4_Swap_JPY", "Up:IndexCurve/JPY-LIBOR-6M/0/6M", 871.03, -193.514},
788 {"4_Swap_JPY", "Up:IndexCurve/JPY-LIBOR-6M/1/1Y", 871.03, 2.95767},
789 {"4_Swap_JPY", "Up:IndexCurve/JPY-LIBOR-6M/2/2Y", 871.03, 7.81453},
790 {"4_Swap_JPY", "Up:IndexCurve/JPY-LIBOR-6M/3/3Y", 871.03, 19.3576},
791 {"4_Swap_JPY", "Up:IndexCurve/JPY-LIBOR-6M/4/5Y", 871.03, 3832.83},
792 {"4_Swap_JPY", "Down:IndexCurve/JPY-LIBOR-6M/0/6M", 871.03, 193.528},
793 {"4_Swap_JPY", "Down:IndexCurve/JPY-LIBOR-6M/1/1Y", 871.03, -2.90067},
794 {"4_Swap_JPY", "Down:IndexCurve/JPY-LIBOR-6M/2/2Y", 871.03, -7.6631},
795 {"4_Swap_JPY", "Down:IndexCurve/JPY-LIBOR-6M/3/3Y", 871.03, -19.0907},
796 {"4_Swap_JPY", "Down:IndexCurve/JPY-LIBOR-6M/4/5Y", 871.03, -3832.59},
797 {"4_Swap_JPY", "Up:FXSpot/EURJPY/0/spot", 871.03, -8.62406},
798 {"4_Swap_JPY", "Down:FXSpot/EURJPY/0/spot", 871.03, 8.79829},
799 {"5_Swaption_EUR", "Up:DiscountCurve/EUR/6/10Y", 37524.3, -10.0118},
800 {"5_Swaption_EUR", "Up:DiscountCurve/EUR/7/15Y", 37524.3, -28.0892},
801 {"5_Swaption_EUR", "Up:DiscountCurve/EUR/8/20Y", 37524.3, -17.527},
802 {"5_Swaption_EUR", "Down:DiscountCurve/EUR/6/10Y", 37524.3, 10.0186},
803 {"5_Swaption_EUR", "Down:DiscountCurve/EUR/7/15Y", 37524.3, 28.117},
804 {"5_Swaption_EUR", "Down:DiscountCurve/EUR/8/20Y", 37524.3, 17.5502},
805 {"5_Swaption_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/6/10Y", 37524.3, -395.215},
806 {"5_Swaption_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/7/15Y", 37524.3, 56.7319},
807 {"5_Swaption_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/8/20Y", 37524.3, 722.287},
808 {"5_Swaption_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/6/10Y", 37524.3, 397.907},
809 {"5_Swaption_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/7/15Y", 37524.3, -56.508},
810 {"5_Swaption_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/8/20Y", 37524.3, -713.45},
811 {"5_Swaption_EUR", "Up:SwaptionVolatility/EUR/5/10Y/10Y/ATM", 37524.3, 367.609},
812 {"5_Swaption_EUR", "Down:SwaptionVolatility/EUR/5/10Y/10Y/ATM", 37524.3, -367.608},
813 {"6_Swaption_EUR", "Up:DiscountCurve/EUR/2/2Y", 10738, -0.485552},
814 {"6_Swaption_EUR", "Up:DiscountCurve/EUR/3/3Y", 10738, -1.09018},
815 {"6_Swaption_EUR", "Up:DiscountCurve/EUR/4/5Y", 10738, -1.98726},
816 {"6_Swaption_EUR", "Up:DiscountCurve/EUR/5/7Y", 10738, -0.591243},
817 {"6_Swaption_EUR", "Up:DiscountCurve/EUR/6/10Y", 10738, 0.00670807},
818 {"6_Swaption_EUR", "Down:DiscountCurve/EUR/2/2Y", 10738, 0.485614},
819 {"6_Swaption_EUR", "Down:DiscountCurve/EUR/3/3Y", 10738, 1.09029},
820 {"6_Swaption_EUR", "Down:DiscountCurve/EUR/4/5Y", 10738, 1.9877},
821 {"6_Swaption_EUR", "Down:DiscountCurve/EUR/5/7Y", 10738, 0.591282},
822 {"6_Swaption_EUR", "Down:DiscountCurve/EUR/6/10Y", 10738, -0.00670808},
823 {"6_Swaption_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/2/2Y", 10738, -97.3791},
824 {"6_Swaption_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/3/3Y", 10738, 4.0232},
825 {"6_Swaption_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/4/5Y", 10738, 8.90271},
826 {"6_Swaption_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/5/7Y", 10738, 322.893},
827 {"6_Swaption_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/6/10Y", 10738, 1.23647},
828 {"6_Swaption_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/2/2Y", 10738, 97.9474},
829 {"6_Swaption_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/3/3Y", 10738, -3.98874},
830 {"6_Swaption_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/4/5Y", 10738, -8.83916},
831 {"6_Swaption_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/5/7Y", 10738, -316.846},
832 {"6_Swaption_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/6/10Y", 10738, -1.23638},
833 {"6_Swaption_EUR", "Up:SwaptionVolatility/EUR/0/2Y/5Y/ATM", 10738, 102.503},
834 {"6_Swaption_EUR", "Up:SwaptionVolatility/EUR/2/5Y/5Y/ATM", 10738, 0.187152},
835 {"6_Swaption_EUR", "Down:SwaptionVolatility/EUR/0/2Y/5Y/ATM", 10738, -102.502},
836 {"6_Swaption_EUR", "Down:SwaptionVolatility/EUR/2/5Y/5Y/ATM", 10738, -0.187152},
837 {"7_FxOption_EUR_USD", "Up:DiscountCurve/EUR/3/3Y", 1.36968e+06, -2107.81},
838 {"7_FxOption_EUR_USD", "Up:DiscountCurve/EUR/4/5Y", 1.36968e+06, -3.85768},
839 {"7_FxOption_EUR_USD", "Up:DiscountCurve/USD/3/3Y", 1.36968e+06, 1698.91},
840 {"7_FxOption_EUR_USD", "Up:DiscountCurve/USD/4/5Y", 1.36968e+06, 3.10717},
841 {"7_FxOption_EUR_USD", "Down:DiscountCurve/EUR/3/3Y", 1.36968e+06, 2109.74},
842 {"7_FxOption_EUR_USD", "Down:DiscountCurve/EUR/4/5Y", 1.36968e+06, 3.85768},
843 {"7_FxOption_EUR_USD", "Down:DiscountCurve/USD/3/3Y", 1.36968e+06, -1698.12},
844 {"7_FxOption_EUR_USD", "Down:DiscountCurve/USD/4/5Y", 1.36968e+06, -3.10717},
845 {"7_FxOption_EUR_USD", "Up:FXSpot/EURUSD/0/spot", 1.36968e+06, 56850.7},
846 {"7_FxOption_EUR_USD", "Down:FXSpot/EURUSD/0/spot", 1.36968e+06, -56537.6},
847 {"7_FxOption_EUR_USD", "Up:FXVolatility/EURUSD/0/5Y/ATM", 1.36968e+06, 672236},
848 {"7_FxOption_EUR_USD", "Down:FXVolatility/EURUSD/0/5Y/ATM", 1.36968e+06, -329688},
849 {"8_FxOption_EUR_GBP", "Up:DiscountCurve/EUR/5/7Y", 798336, -2435.22},
850 {"8_FxOption_EUR_GBP", "Up:DiscountCurve/GBP/5/7Y", 798336, 1880.89},
851 {"8_FxOption_EUR_GBP", "Down:DiscountCurve/EUR/5/7Y", 798336, 2441.08},
852 {"8_FxOption_EUR_GBP", "Down:DiscountCurve/GBP/5/7Y", 798336, -1878.05},
853 {"8_FxOption_EUR_GBP", "Up:FXSpot/EURGBP/0/spot", 798336, 27009.9},
854 {"8_FxOption_EUR_GBP", "Down:FXSpot/EURGBP/0/spot", 798336, -26700.2},
855 {"8_FxOption_EUR_GBP", "Up:FXVolatility/EURGBP/0/5Y/ATM", 798336, 1.36635e+06},
856 {"8_FxOption_EUR_GBP", "Down:FXVolatility/EURGBP/0/5Y/ATM", 798336, -798336},
857 {"9_Cap_EUR", "Up:DiscountCurve/EUR/2/2Y", 289.105, -7.28588e-07},
858 {"9_Cap_EUR", "Up:DiscountCurve/EUR/3/3Y", 289.105, -0.000381869},
859 {"9_Cap_EUR", "Up:DiscountCurve/EUR/4/5Y", 289.105, -0.00790528},
860 {"9_Cap_EUR", "Up:DiscountCurve/EUR/5/7Y", 289.105, -0.0764893},
861 {"9_Cap_EUR", "Up:DiscountCurve/EUR/6/10Y", 289.105, -0.162697},
862 {"9_Cap_EUR", "Down:DiscountCurve/EUR/2/2Y", 289.105, 7.28664e-07},
863 {"9_Cap_EUR", "Down:DiscountCurve/EUR/3/3Y", 289.105, 0.000381934},
864 {"9_Cap_EUR", "Down:DiscountCurve/EUR/4/5Y", 289.105, 0.00790776},
865 {"9_Cap_EUR", "Down:DiscountCurve/EUR/5/7Y", 289.105, 0.0765231},
866 {"9_Cap_EUR", "Down:DiscountCurve/EUR/6/10Y", 289.105, 0.162824},
867 {"9_Cap_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/1/1Y", 289.105, -1.81582e-05},
868 {"9_Cap_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/2/2Y", 289.105, -0.00670729},
869 {"9_Cap_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/3/3Y", 289.105, -0.330895},
870 {"9_Cap_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/4/5Y", 289.105, -2.03937},
871 {"9_Cap_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/5/7Y", 289.105, -6.42991},
872 {"9_Cap_EUR", "Up:IndexCurve/EUR-EURIBOR-6M/6/10Y", 289.105, 15.5182},
873 {"9_Cap_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/1/1Y", 289.105, 1.97218e-05},
874 {"9_Cap_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/2/2Y", 289.105, 0.00746096},
875 {"9_Cap_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/3/3Y", 289.105, 0.353405},
876 {"9_Cap_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/4/5Y", 289.105, 2.24481},
877 {"9_Cap_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/5/7Y", 289.105, 7.1522},
878 {"9_Cap_EUR", "Down:IndexCurve/EUR-EURIBOR-6M/6/10Y", 289.105, -14.6675},
879 {"9_Cap_EUR", "Up:OptionletVolatility/EUR/4/1Y/0.05", 289.105, 8.49293e-05},
880 {"9_Cap_EUR", "Up:OptionletVolatility/EUR/9/2Y/0.05", 289.105, 0.0150901},
881 {"9_Cap_EUR", "Up:OptionletVolatility/EUR/14/3Y/0.05", 289.105, 0.620393},
882 {"9_Cap_EUR", "Up:OptionletVolatility/EUR/19/5Y/0.05", 289.105, 17.2057},
883 {"9_Cap_EUR", "Up:OptionletVolatility/EUR/24/10Y/0.05", 289.105, 24.4267},
884 {"9_Cap_EUR", "Down:OptionletVolatility/EUR/4/1Y/0.05", 289.105, -6.97789e-05},
885 {"9_Cap_EUR", "Down:OptionletVolatility/EUR/9/2Y/0.05", 289.105, -0.0125099},
886 {"9_Cap_EUR", "Down:OptionletVolatility/EUR/14/3Y/0.05", 289.105, -0.554344},
887 {"9_Cap_EUR", "Down:OptionletVolatility/EUR/19/5Y/0.05", 289.105, -16.1212},
888 {"9_Cap_EUR", "Down:OptionletVolatility/EUR/24/10Y/0.05", 289.105, -23.0264},
889 {"10_Floor_USD", "Up:DiscountCurve/USD/0/6M", 3406.46, -7.03494e-09},
890 {"10_Floor_USD", "Up:DiscountCurve/USD/1/1Y", 3406.46, -8.41429e-05},
891 {"10_Floor_USD", "Up:DiscountCurve/USD/2/2Y", 3406.46, -0.00329744},
892 {"10_Floor_USD", "Up:DiscountCurve/USD/3/3Y", 3406.46, -0.053884},
893 {"10_Floor_USD", "Up:DiscountCurve/USD/4/5Y", 3406.46, -0.269714},
894 {"10_Floor_USD", "Up:DiscountCurve/USD/5/7Y", 3406.46, -0.989583},
895 {"10_Floor_USD", "Up:DiscountCurve/USD/6/10Y", 3406.46, -1.26544},
896 {"10_Floor_USD", "Down:DiscountCurve/USD/0/6M", 3406.46, 7.0354e-09},
897 {"10_Floor_USD", "Down:DiscountCurve/USD/1/1Y", 3406.46, 8.41464e-05},
898 {"10_Floor_USD", "Down:DiscountCurve/USD/2/2Y", 3406.46, 0.00329786},
899 {"10_Floor_USD", "Down:DiscountCurve/USD/3/3Y", 3406.46, 0.0538949},
900 {"10_Floor_USD", "Down:DiscountCurve/USD/4/5Y", 3406.46, 0.269802},
901 {"10_Floor_USD", "Down:DiscountCurve/USD/5/7Y", 3406.46, 0.990038},
902 {"10_Floor_USD", "Down:DiscountCurve/USD/6/10Y", 3406.46, 1.26635},
903 {"10_Floor_USD", "Up:IndexCurve/USD-LIBOR-3M/0/6M", 3406.46, 0.00150733},
904 {"10_Floor_USD", "Up:IndexCurve/USD-LIBOR-3M/1/1Y", 3406.46, 0.240284},
905 {"10_Floor_USD", "Up:IndexCurve/USD-LIBOR-3M/2/2Y", 3406.46, 2.17175},
906 {"10_Floor_USD", "Up:IndexCurve/USD-LIBOR-3M/3/3Y", 3406.46, 7.77249},
907 {"10_Floor_USD", "Up:IndexCurve/USD-LIBOR-3M/4/5Y", 3406.46, 12.9642},
908 {"10_Floor_USD", "Up:IndexCurve/USD-LIBOR-3M/5/7Y", 3406.46, 16.8269},
909 {"10_Floor_USD", "Up:IndexCurve/USD-LIBOR-3M/6/10Y", 3406.46, -81.4363},
910 {"10_Floor_USD", "Down:IndexCurve/USD-LIBOR-3M/0/6M", 3406.46, -0.00139804},
911 {"10_Floor_USD", "Down:IndexCurve/USD-LIBOR-3M/1/1Y", 3406.46, -0.230558},
912 {"10_Floor_USD", "Down:IndexCurve/USD-LIBOR-3M/2/2Y", 3406.46, -2.00123},
913 {"10_Floor_USD", "Down:IndexCurve/USD-LIBOR-3M/3/3Y", 3406.46, -7.14862},
914 {"10_Floor_USD", "Down:IndexCurve/USD-LIBOR-3M/4/5Y", 3406.46, -11.2003},
915 {"10_Floor_USD", "Down:IndexCurve/USD-LIBOR-3M/5/7Y", 3406.46, -13.7183},
916 {"10_Floor_USD", "Down:IndexCurve/USD-LIBOR-3M/6/10Y", 3406.46, 84.0113},
917 {"10_Floor_USD", "Up:FXSpot/EURUSD/0/spot", 3406.46, -33.7273},
918 {"10_Floor_USD", "Down:FXSpot/EURUSD/0/spot", 3406.46, 34.4087},
919 {"10_Floor_USD", "Up:OptionletVolatility/USD/0/1Y/0.01", 3406.46, 0.402913},
920 {"10_Floor_USD", "Up:OptionletVolatility/USD/5/2Y/0.01", 3406.46, 3.32861},
921 {"10_Floor_USD", "Up:OptionletVolatility/USD/10/3Y/0.01", 3406.46, 16.8798},
922 {"10_Floor_USD", "Up:OptionletVolatility/USD/15/5Y/0.01", 3406.46, 96.415},
923 {"10_Floor_USD", "Up:OptionletVolatility/USD/20/10Y/0.01", 3406.46, 92.2212},
924 {"10_Floor_USD", "Down:OptionletVolatility/USD/0/1Y/0.01", 3406.46, -0.37428},
925 {"10_Floor_USD", "Down:OptionletVolatility/USD/5/2Y/0.01", 3406.46, -3.14445},
926 {"10_Floor_USD", "Down:OptionletVolatility/USD/10/3Y/0.01", 3406.46, -16.3074},
927 {"10_Floor_USD", "Down:OptionletVolatility/USD/15/5Y/0.01", 3406.46, -94.5309},
928 {"10_Floor_USD", "Down:OptionletVolatility/USD/20/10Y/0.01", 3406.46, -90.9303},
929 // {"11_CDSOption_EUR", "Up:DiscountCurve/EUR/0/6M", 56003.6, -0.0395449},
930 // {"11_CDSOption_EUR", "Up:DiscountCurve/EUR/1/1Y", 56003.6, -5.57561},
931 // {"11_CDSOption_EUR", "Up:DiscountCurve/EUR/2/2Y", 56003.6, 0.0377165},
932 // {"11_CDSOption_EUR", "Up:DiscountCurve/EUR/3/3Y", 56003.6, 0.0799626},
933 // {"11_CDSOption_EUR", "Up:DiscountCurve/EUR/4/5Y", 56003.6, 0.0998674},
934 // {"11_CDSOption_EUR", "Up:DiscountCurve/EUR/5/7Y", 56003.6, 0.00709491},
935 // {"11_CDSOption_EUR", "Up:SurvivalProbability/dc/0/6M", 56003.6, -0.00227111},
936 // {"11_CDSOption_EUR", "Up:SurvivalProbability/dc/1/1Y", 56003.6, 53.186},
937 // {"11_CDSOption_EUR", "Up:SurvivalProbability/dc/2/2Y", 56003.6, 0.206306},
938 // {"11_CDSOption_EUR", "Up:SurvivalProbability/dc/3/3Y", 56003.6, 0.396504},
939 // {"11_CDSOption_EUR", "Up:SurvivalProbability/dc/4/5Y", 56003.6, 2.63},
940 // {"11_CDSOption_EUR", "Up:SurvivalProbability/dc/5/7Y", 56003.6, 0.259055},
941 // {"11_CDSOption_EUR", "Down:DiscountCurve/EUR/0/6M", 56003.6, 0.0395562},
942 // {"11_CDSOption_EUR", "Down:DiscountCurve/EUR/1/1Y", 56003.6, 5.57616},
943 // {"11_CDSOption_EUR", "Down:DiscountCurve/EUR/2/2Y", 56003.6, -0.0377084},
944 // {"11_CDSOption_EUR", "Down:DiscountCurve/EUR/3/3Y", 56003.6, -0.0799231},
945 // {"11_CDSOption_EUR", "Down:DiscountCurve/EUR/4/5Y", 56003.6, -0.0926819},
946 // {"11_CDSOption_EUR", "Down:DiscountCurve/EUR/5/7Y", 56003.6, -0.00709513},
947 // {"11_CDSOption_EUR", "Down:SurvivalProbability/dc/0/6M", 56003.6, 0.00227126},
948 // {"11_CDSOption_EUR", "Down:SurvivalProbability/dc/1/1Y", 56003.6, -53.1913},
949 // {"11_CDSOption_EUR", "Down:SurvivalProbability/dc/2/2Y", 56003.6, -0.206064},
950 // {"11_CDSOption_EUR", "Down:SurvivalProbability/dc/3/3Y", 56003.6, -0.395576},
951 // {"11_CDSOption_EUR", "Down:SurvivalProbability/dc/4/5Y", 56003.6, -2.58855},
952 // {"11_CDSOption_EUR", "Down:SurvivalProbability/dc/5/7Y", 56003.6, -0.258819},
953 // {"11_CDSOption_EUR", "Up:CDSVolatility/dc/1/1Y/ATM", 56003.6, 10.5781},
954 // {"11_CDSOption_EUR", "Down:CDSVolatility/dc/1/1Y/ATM", 56003.6, -10.0622},
955 { "12_EquityOption_SP5", "Up:DiscountCurve/USD/2/2Y", 278936, 158.718 },
956 { "12_EquityOption_SP5", "Up:DiscountCurve/USD/3/3Y", 278936, 1.31198 },
957 { "12_EquityOption_SP5", "Down:DiscountCurve/USD/2/2Y", 278936, -158.676 },
958 { "12_EquityOption_SP5", "Down:DiscountCurve/USD/3/3Y", 278936, -1.31197 },
959 { "12_EquityOption_SP5", "Up:FXSpot/EURUSD/0/spot", 278936, -2761.74 },
960 { "12_EquityOption_SP5", "Down:FXSpot/EURUSD/0/spot", 278936, 2817.53 },
961 { "12_EquityOption_SP5", "Up:EquitySpot/SP5/0/spot", 278936, 10869.4 },
962 { "12_EquityOption_SP5", "Down:EquitySpot/SP5/0/spot", 278936, -10681 },
963 { "12_EquityOption_SP5", "Up:EquityVolatility/SP5/5/2Y/ATM", 278936, 2388.21 },
964 { "12_EquityOption_SP5", "Down:EquityVolatility/SP5/5/2Y/ATM", 278936, -2388.67 },
965 { "13_EquityOption_Lufthansa", "Up:DiscountCurve/EUR/2/2Y", 1830.8, 0.854602 },
966 { "13_EquityOption_Lufthansa", "Up:DiscountCurve/EUR/3/3Y", 1830.8, 0.0070644 },
967 { "13_EquityOption_Lufthansa", "Down:DiscountCurve/EUR/2/2Y", 1830.8, -0.854422 },
968 { "13_EquityOption_Lufthansa", "Down:DiscountCurve/EUR/3/3Y", 1830.8, -0.00706439 },
969 { "13_EquityOption_Lufthansa", "Up:EquitySpot/Lufthansa/0/spot", 1830.8, 61.7512 },
970 { "13_EquityOption_Lufthansa", "Down:EquitySpot/Lufthansa/0/spot", 1830.8, -60.866 },
971 { "13_EquityOption_Lufthansa", "Up:EquityVolatility/Lufthansa/5/2Y/ATM", 1830.8, 15.975 },
972 { "13_EquityOption_Lufthansa", "Down:EquityVolatility/Lufthansa/5/2Y/ATM", 1830.8, -15.9808 },
973 {"14_YoYInflationCap_UKRPI", "Up:DiscountCurve/GBP/1/1Y", 3495.36, -0.0190824},
974 {"14_YoYInflationCap_UKRPI", "Up:DiscountCurve/GBP/2/2Y", 3495.36, -0.0518755},
975 {"14_YoYInflationCap_UKRPI", "Up:DiscountCurve/GBP/3/3Y", 3495.36, -0.159743},
976 {"14_YoYInflationCap_UKRPI", "Up:DiscountCurve/GBP/4/5Y", 3495.36, -0.346412},
977 {"14_YoYInflationCap_UKRPI", "Up:DiscountCurve/GBP/5/7Y", 3495.36, -0.701974},
978 {"14_YoYInflationCap_UKRPI", "Up:DiscountCurve/GBP/6/10Y", 3495.36, -0.837257},
979 {"14_YoYInflationCap_UKRPI", "Down:DiscountCurve/GBP/1/1Y", 3495.36, 0.0190843},
980 {"14_YoYInflationCap_UKRPI", "Down:DiscountCurve/GBP/2/2Y", 3495.36, 0.0518857},
981 {"14_YoYInflationCap_UKRPI", "Down:DiscountCurve/GBP/3/3Y", 3495.36, 0.159784},
982 {"14_YoYInflationCap_UKRPI", "Down:DiscountCurve/GBP/4/5Y", 3495.36, 0.346541},
983 {"14_YoYInflationCap_UKRPI", "Down:DiscountCurve/GBP/5/7Y", 3495.36, 0.702328},
984 {"14_YoYInflationCap_UKRPI", "Down:DiscountCurve/GBP/6/10Y", 3495.36, 0.83791},
985 {"14_YoYInflationCap_UKRPI", "Up:FXSpot/EURGBP/0/spot", 3495.36, -34.6075},
986 {"14_YoYInflationCap_UKRPI", "Down:FXSpot/EURGBP/0/spot", 3495.36, 35.3067},
987 {"14_YoYInflationCap_UKRPI", "Up:YoYInflationCurve/UKRP1/0/1Y", 3495.36, 6.11718},
988 {"14_YoYInflationCap_UKRPI", "Up:YoYInflationCurve/UKRP1/1/2Y", 3495.36, 5.77751},
989 {"14_YoYInflationCap_UKRPI", "Up:YoYInflationCurve/UKRP1/2/3Y", 3495.36, 8.22785},
990 {"14_YoYInflationCap_UKRPI", "Up:YoYInflationCurve/UKRP1/3/5Y", 3495.36, 10.2605},
991 {"14_YoYInflationCap_UKRPI", "Up:YoYInflationCurve/UKRP1/4/7Y", 3495.36, 11.7006},
992 {"14_YoYInflationCap_UKRPI", "Up:YoYInflationCurve/UKRP1/5/10Y", 3495.36, 8.6242},
993 {"14_YoYInflationCap_UKRPI", "Down:YoYInflationCurve/UKRP1/0/1Y", 3495.36, -5.99639},
994 {"14_YoYInflationCap_UKRPI", "Down:YoYInflationCurve/UKRP1/1/2Y", 3495.36, -5.6966},
995 {"14_YoYInflationCap_UKRPI", "Down:YoYInflationCurve/UKRP1/2/3Y", 3495.36, -8.15092},
996 {"14_YoYInflationCap_UKRPI", "Down:YoYInflationCurve/UKRP1/3/5Y", 3495.36, -10.1917},
997 {"14_YoYInflationCap_UKRPI", "Down:YoYInflationCurve/UKRP1/4/7Y", 3495.36, -11.6375},
998 {"14_YoYInflationCap_UKRPI", "Down:YoYInflationCurve/UKRP1/5/10Y", 3495.36, -8.58138},
999 {"14_YoYInflationCap_UKRPI", "Up:YoYInflationCapFloorVolatility/UKRP1/4/1Y/0.02", 3495.36, 0.706362},
1000 {"14_YoYInflationCap_UKRPI", "Up:YoYInflationCapFloorVolatility/UKRP1/10/2Y/0.02", 3495.36, 0.575052},
1001 {"14_YoYInflationCap_UKRPI", "Up:YoYInflationCapFloorVolatility/UKRP1/16/3Y/0.02", 3495.36, 1.21162},
1002 {"14_YoYInflationCap_UKRPI", "Up:YoYInflationCapFloorVolatility/UKRP1/22/5Y/0.02", 3495.36, 1.83575},
1003 {"14_YoYInflationCap_UKRPI", "Up:YoYInflationCapFloorVolatility/UKRP1/28/7Y/0.02", 3495.36, 2.52242},
1004 {"14_YoYInflationCap_UKRPI", "Up:YoYInflationCapFloorVolatility/UKRP1/34/10Y/0.02", 3495.36, 1.8872},
1005 {"14_YoYInflationCap_UKRPI", "Down:YoYInflationCapFloorVolatility/UKRP1/4/1Y/0.02", 3495.36, -0.706362},
1006 {"14_YoYInflationCap_UKRPI", "Down:YoYInflationCapFloorVolatility/UKRP1/10/2Y/0.02", 3495.36, -0.575052},
1007 {"14_YoYInflationCap_UKRPI", "Down:YoYInflationCapFloorVolatility/UKRP1/16/3Y/0.02", 3495.36, -1.21162},
1008 {"14_YoYInflationCap_UKRPI", "Down:YoYInflationCapFloorVolatility/UKRP1/22/5Y/0.02", 3495.36, -1.83575},
1009 {"14_YoYInflationCap_UKRPI", "Down:YoYInflationCapFloorVolatility/UKRP1/28/7Y/0.02", 3495.36, -2.52242},
1010 {"14_YoYInflationCap_UKRPI", "Down:YoYInflationCapFloorVolatility/UKRP1/34/10Y/0.02", 3495.36, -1.8872}};
1011
1012 std::map<pair<string, string>, Real> npvMap, sensiMap;
1013 for (Size i = 0; i < cachedResults.size(); ++i) {
1014 pair<string, string> p(cachedResults[i].id, cachedResults[i].label);
1015 npvMap[p] = cachedResults[i].npv;
1016 sensiMap[p] = cachedResults[i].sensi;
1017 }
1018 vector<pair<string, string>> ids;
1019 Real tiny = 1.0e-10;
1020 Real tolerance = 0.01;
1021 Size count = 0;
1022 vector<ShiftScenarioGenerator::ScenarioDescription> desc = scenarioGenerator->scenarioDescriptions();
1023 size_t currentTradeIdx = 0;
1024 for (const auto& [tradeId, _] : portfolio->trades()) {
1025 Real npv0 = cube->getT0(currentTradeIdx, 0);
1026 for (Size j = 1; j < scenarioGenerator->samples(); ++j) { // skip j = 0, this is the base scenario
1027 Real npv = cube->get(currentTradeIdx, 0, j, 0);
1028 Real sensi = npv - npv0;
1029 string label = to_string(desc[j]);
1030 if (fabs(sensi) > tiny) {
1031 count++;
1032
1033 pair<string, string> p(tradeId, label);
1034 ids.push_back(p);
1035 QL_REQUIRE(npvMap.find(p) != npvMap.end(),
1036 "pair (" << p.first << ", " << p.second << ") not found in npv map");
1037 QL_REQUIRE(sensiMap.find(p) != sensiMap.end(),
1038 "pair (" << p.first << ", " << p.second << ") not found in sensi map");
1039 BOOST_CHECK_MESSAGE(fabs(npv0 - npvMap[p]) < tolerance || fabs((npv0 - npvMap[p]) / npv0) < tolerance,
1040 "npv regression failed for pair (" << p.first << ", " << p.second << "): " << npv0
1041 << " vs " << npvMap[p]);
1042 BOOST_CHECK_MESSAGE(fabs(sensi - sensiMap[p]) < tolerance ||
1043 fabs((sensi - sensiMap[p]) / sensi) < tolerance,
1044 "sensitivity regression failed for pair ("
1045 << p.first << ", " << p.second << "): " << sensi << " vs " << sensiMap[p]);
1046 // uncomment to output code for cached results
1047 // BOOST_TEST_MESSAGE("{\"" << p.first << "\", \"" << p.second << "\", " << npv0 << ", " << sensi <<
1048 // "},");
1049 }
1050 }
1051 currentTradeIdx++;
1052 }
1053 BOOST_CHECK_MESSAGE(count == cachedResults.size(), "number of non-zero sensitivities ("
1054 << count << ") do not match regression data ("
1055 << cachedResults.size() << ")");
1056
1057 BOOST_TEST_MESSAGE("Cube generated in " << elapsed << " seconds");
1058 ObservationMode::instance().setMode(backupMode);
1059 IndexManager::instance().clearHistories();
1060}
1061
1063
1064 SavedSettings backup;
1065
1066 ObservationMode::Mode backupMode = ObservationMode::instance().mode();
1067 ObservationMode::instance().setMode(om);
1068
1069 Date today = Date(14, April, 2016); // Settings::instance().evaluationDate();
1070 Settings::instance().evaluationDate() = today;
1071
1072 BOOST_TEST_MESSAGE("Today is " << today);
1073
1074 // build model
1075 string baseCcy = "EUR";
1076 vector<string> ccys;
1077 ccys.push_back(baseCcy);
1078 ccys.push_back("GBP");
1079 ccys.push_back("CHF");
1080 ccys.push_back("USD");
1081 ccys.push_back("JPY");
1082
1083 // Init market
1084 QuantLib::ext::shared_ptr<Market> initMarket = QuantLib::ext::make_shared<TestMarket>(today);
1085
1086 // build scenario sim market parameters
1087 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> simMarketData = setupSimMarketData5();
1088
1089 // sensitivity config
1090 QuantLib::ext::shared_ptr<SensitivityScenarioData> sensiData = setupSensitivityScenarioData5(true);
1091
1092 // build scenario sim market
1093 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarket> simMarket =
1094 QuantLib::ext::make_shared<analytics::ScenarioSimMarket>(initMarket, simMarketData);
1095
1096 // build scenario factory
1097 QuantLib::ext::shared_ptr<Scenario> baseScenario = simMarket->baseScenario();
1098 QuantLib::ext::shared_ptr<ScenarioFactory> scenarioFactory =
1099 QuantLib::ext::make_shared<ore::analytics::DeltaScenarioFactory>(baseScenario);
1100
1101 // build scenario generator
1102 QuantLib::ext::shared_ptr<SensitivityScenarioGenerator> scenarioGenerator =
1103 QuantLib::ext::make_shared<SensitivityScenarioGenerator>(sensiData, baseScenario, simMarketData, simMarket,
1104 scenarioFactory, false);
1105 simMarket->scenarioGenerator() = scenarioGenerator;
1106
1107 // build porfolio
1108 QuantLib::ext::shared_ptr<EngineData> engineData = QuantLib::ext::make_shared<EngineData>();
1109 engineData->model("Swap") = "DiscountedCashflows";
1110 engineData->engine("Swap") = "DiscountingSwapEngine";
1111 engineData->model("CrossCurrencySwap") = "DiscountedCashflows";
1112 engineData->engine("CrossCurrencySwap") = "DiscountingCrossCurrencySwapEngine";
1113 engineData->model("EuropeanSwaption") = "BlackBachelier";
1114 engineData->engine("EuropeanSwaption") = "BlackBachelierSwaptionEngine";
1115 engineData->model("FxForward") = "DiscountedCashflows";
1116 engineData->engine("FxForward") = "DiscountingFxForwardEngine";
1117 engineData->model("FxOption") = "GarmanKohlhagen";
1118 engineData->engine("FxOption") = "AnalyticEuropeanEngine";
1119 engineData->model("CapFloor") = "IborCapModel";
1120 engineData->engine("CapFloor") = "IborCapEngine";
1121 engineData->model("CapFlooredIborLeg") = "BlackOrBachelier";
1122 engineData->engine("CapFlooredIborLeg") = "BlackIborCouponPricer";
1123 engineData->model("YYCapFloor") = "YYCapModel";
1124 engineData->engine("YYCapFloor") = "YYCapEngine";
1125 engineData->model("Bond") = "DiscountedCashflows";
1126 engineData->engine("Bond") = "DiscountingRiskyBondEngine";
1127 engineData->engineParameters("Bond")["TimestepPeriod"] = "6M";
1128 engineData->model("CreditDefaultSwap") = "DiscountedCashflows";
1129 engineData->engine("CreditDefaultSwap") = "MidPointCdsEngine";
1130 engineData->model("EquityOption") = "BlackScholesMerton";
1131 engineData->engine("EquityOption") = "AnalyticEuropeanEngine";
1132 QuantLib::ext::shared_ptr<EngineFactory> factory = QuantLib::ext::make_shared<EngineFactory>(engineData, simMarket);
1133
1134 // QuantLib::ext::shared_ptr<Portfolio> portfolio = buildSwapPortfolio(portfolioSize, factory);
1135 QuantLib::ext::shared_ptr<Portfolio> portfolio(new Portfolio());
1136 portfolio->add(buildSwap("1_Swap_EUR", "EUR", true, 10000000.0, 0, 10, 0.03, 0.00, "1Y",
1137 "30/360", "6M", "A360", "EUR-EURIBOR-6M"));
1138 portfolio->add(buildSwap("2_Swap_USD", "USD", true, 10000000.0, 0, 15, 0.02, 0.00, "6M",
1139 "30/360", "3M", "A360", "USD-LIBOR-3M"));
1140 portfolio->add(buildCap("9_Cap_EUR", "EUR", "Long", 0.05, 1000000.0, 0, 10, "6M", "A360",
1141 "EUR-EURIBOR-6M"));
1142 portfolio->add(buildFloor("10_Floor_USD", "USD", "Long", 0.01, 1000000.0, 0, 10, "3M", "A360",
1143 "USD-LIBOR-3M"));
1144 portfolio->add(buildZeroBond("11_ZeroBond_EUR", "EUR", 1000000.0, 10));
1145 portfolio->add(buildZeroBond("12_ZeroBond_USD", "USD", 1000000.0, 10));
1146 portfolio->add(
1147 buildEquityOption("13_EquityOption_SP5", "Long", "Call", 2, "SP5", "USD", 2147.56, 1000));
1148 portfolio->add(buildYYInflationCapFloor("14_YoYInflationCap_UKRPI", "GBP", 100000.0, true, true,
1149 0.02, 0, 10, "1Y", "ACT/ACT", "UKRP1", "2M", 2));
1150 portfolio->build(factory);
1151 BOOST_TEST_MESSAGE("Portfolio size after build: " << portfolio->size());
1152
1153 // build the sensitivity analysis object
1154 // first build the par analysis object, so that we can align the pillars for the zero sensi analysis
1155 ParSensitivityAnalysis parAnalysis(today, simMarketData, *sensiData, Market::defaultConfiguration);
1156 parAnalysis.alignPillars();
1157 QuantLib::ext::shared_ptr<SensitivityAnalysis> zeroAnalysis = QuantLib::ext::make_shared<SensitivityAnalysis>(
1158 portfolio, initMarket, Market::defaultConfiguration, engineData, simMarketData, sensiData, false);
1159 BOOST_TEST_MESSAGE("SensitivityAnalysis object built");
1160 zeroAnalysis->overrideTenors(true);
1161 zeroAnalysis->generateSensitivities();
1162 BOOST_TEST_MESSAGE("Raw sensitivity analsis done");
1163 BOOST_TEST_MESSAGE("Par sensitivity analsis object built");
1164
1165 // RL: CRITICAL CHANGE
1166 // // TODO: should the next two lines not come before call to zeroAnalysis->generateSensitivities();?
1167 // // PC, 30-07-2018, yes they should, cached results have to be updated then (postponed...)
1168 // parAnalysis.alignPillars();
1169 // zeroAnalysis->overrideTenors(true);
1170 parAnalysis.computeParInstrumentSensitivities(zeroAnalysis->simMarket());
1171 QuantLib::ext::shared_ptr<ParSensitivityConverter> parConverter =
1172 QuantLib::ext::make_shared<ParSensitivityConverter>(parAnalysis.parSensitivities(), parAnalysis.shiftSizes());
1173 QuantLib::ext::shared_ptr<SensitivityCube> sensiCube = zeroAnalysis->sensiCube();
1174 ZeroToParCube parCube(sensiCube, parConverter);
1175
1176 map<pair<string, string>, Real> parDelta;
1177 for (const auto& tradeId : portfolio->ids()) {
1178 // Fill the par deltas map
1179 auto temp = parCube.parDeltas(tradeId);
1180 for (const auto& kv : temp) {
1181 // We only care about the actual "converted" par deltas here
1182 if (ParSensitivityAnalysis::isParType(kv.first.keytype)) {
1183 string des = sensiCube->factorDescription(kv.first);
1184 parDelta[make_pair(tradeId, des)] = kv.second;
1185 }
1186 }
1187 }
1188
1189 struct Results {
1190 string id;
1191 string label;
1192 Real sensi;
1193 };
1194
1195 std::vector<Results> cachedResults = {
1196 {"10_Floor_USD", "DiscountCurve/USD/0/6M", -0.00112886},
1197 {"10_Floor_USD", "DiscountCurve/USD/1/1Y", 0.00675206},
1198 {"10_Floor_USD", "DiscountCurve/USD/2/2Y", 0.00900048},
1199 {"10_Floor_USD", "DiscountCurve/USD/3/3Y", -0.0302434},
1200 {"10_Floor_USD", "DiscountCurve/USD/4/5Y", -0.262464},
1201 {"10_Floor_USD", "DiscountCurve/USD/5/7Y", -1.07006},
1202 {"10_Floor_USD", "DiscountCurve/USD/6/10Y", -1.04325},
1203 {"10_Floor_USD", "IndexCurve/USD-LIBOR-3M/0/6M", 0.00386584},
1204 {"10_Floor_USD", "IndexCurve/USD-LIBOR-3M/1/1Y", 0.2381},
1205 {"10_Floor_USD", "IndexCurve/USD-LIBOR-3M/2/2Y", 2.2426},
1206 {"10_Floor_USD", "IndexCurve/USD-LIBOR-3M/3/3Y", 7.56822},
1207 {"10_Floor_USD", "IndexCurve/USD-LIBOR-3M/4/5Y", 15.9842},
1208 {"10_Floor_USD", "IndexCurve/USD-LIBOR-3M/5/7Y", 22.2464},
1209 {"10_Floor_USD", "IndexCurve/USD-LIBOR-3M/6/10Y", -89.3588},
1210 {"10_Floor_USD", "OptionletVolatility/USD/0/1Y/0.01", -0.622505},
1211 {"10_Floor_USD", "OptionletVolatility/USD/10/3Y/0.01", -2.20215},
1212 {"10_Floor_USD", "OptionletVolatility/USD/15/5Y/0.01", 1.77487},
1213 {"10_Floor_USD", "OptionletVolatility/USD/20/10Y/0.01", 207.854},
1214 {"10_Floor_USD", "OptionletVolatility/USD/5/2Y/0.01", 1.78417},
1215 {"11_ZeroBond_EUR", "SurvivalProbability/BondIssuer1/0/6M", 1.53634},
1216 {"11_ZeroBond_EUR", "SurvivalProbability/BondIssuer1/1/1Y", 3.53444},
1217 {"11_ZeroBond_EUR", "SurvivalProbability/BondIssuer1/2/2Y", 8.6117},
1218 {"11_ZeroBond_EUR", "SurvivalProbability/BondIssuer1/3/3Y", 18.5064},
1219 {"11_ZeroBond_EUR", "SurvivalProbability/BondIssuer1/4/5Y", 39.4197},
1220 {"11_ZeroBond_EUR", "SurvivalProbability/BondIssuer1/5/7Y", 36.4505},
1221 {"11_ZeroBond_EUR", "SurvivalProbability/BondIssuer1/6/10Y", -600.06},
1222 {"11_ZeroBond_EUR", "YieldCurve/BondCurve1/0/6M", -0.657215},
1223 {"11_ZeroBond_EUR", "YieldCurve/BondCurve1/1/1Y", 2.95782},
1224 {"11_ZeroBond_EUR", "YieldCurve/BondCurve1/2/2Y", 6.06677},
1225 {"11_ZeroBond_EUR", "YieldCurve/BondCurve1/3/3Y", 14.1153},
1226 {"11_ZeroBond_EUR", "YieldCurve/BondCurve1/4/5Y", 32.8224},
1227 {"11_ZeroBond_EUR", "YieldCurve/BondCurve1/5/7Y", 58.069},
1228 {"11_ZeroBond_EUR", "YieldCurve/BondCurve1/6/10Y", -690.301},
1229 {"12_ZeroBond_USD", "SurvivalProbability/BondIssuer1/0/6M", 1.28029},
1230 {"12_ZeroBond_USD", "SurvivalProbability/BondIssuer1/1/1Y", 2.94537},
1231 {"12_ZeroBond_USD", "SurvivalProbability/BondIssuer1/2/2Y", 7.17642},
1232 {"12_ZeroBond_USD", "SurvivalProbability/BondIssuer1/3/3Y", 15.422},
1233 {"12_ZeroBond_USD", "SurvivalProbability/BondIssuer1/4/5Y", 32.8498},
1234 {"12_ZeroBond_USD", "SurvivalProbability/BondIssuer1/5/7Y", 30.3754},
1235 {"12_ZeroBond_USD", "SurvivalProbability/BondIssuer1/6/10Y", -500.05},
1236 {"12_ZeroBond_USD", "YieldCurve/BondCurve1/0/6M", -0.547679},
1237 {"12_ZeroBond_USD", "YieldCurve/BondCurve1/1/1Y", 2.46485},
1238 {"12_ZeroBond_USD", "YieldCurve/BondCurve1/2/2Y", 5.05564},
1239 {"12_ZeroBond_USD", "YieldCurve/BondCurve1/3/3Y", 11.7627},
1240 {"12_ZeroBond_USD", "YieldCurve/BondCurve1/4/5Y", 27.352},
1241 {"12_ZeroBond_USD", "YieldCurve/BondCurve1/5/7Y", 48.3909},
1242 {"12_ZeroBond_USD", "YieldCurve/BondCurve1/6/10Y", -575.251},
1243 {"13_EquityOption_SP5", "DiscountCurve/USD/0/6M", 0.270388},
1244 {"13_EquityOption_SP5", "DiscountCurve/USD/1/1Y", -1.35418},
1245 {"13_EquityOption_SP5", "DiscountCurve/USD/2/2Y", 158.893},
1246 {"14_YoYInflationCap_UKRPI", "DiscountCurve/GBP/0/6M", 0.00347664},
1247 {"14_YoYInflationCap_UKRPI", "DiscountCurve/GBP/1/1Y", -0.00921372},
1248 {"14_YoYInflationCap_UKRPI", "DiscountCurve/GBP/2/2Y", -0.0271867},
1249 {"14_YoYInflationCap_UKRPI", "DiscountCurve/GBP/3/3Y", -0.0973079},
1250 {"14_YoYInflationCap_UKRPI", "DiscountCurve/GBP/4/5Y", -0.298947},
1251 {"14_YoYInflationCap_UKRPI", "DiscountCurve/GBP/5/7Y", -0.69657},
1252 {"14_YoYInflationCap_UKRPI", "DiscountCurve/GBP/6/10Y", -0.950666},
1253 {"14_YoYInflationCap_UKRPI", "YoYInflationCapFloorVolatility/UKRP1/10/2Y/0.02", 0.131713},
1254 {"14_YoYInflationCap_UKRPI", "YoYInflationCapFloorVolatility/UKRP1/16/3Y/0.02", -0.155071},
1255 {"14_YoYInflationCap_UKRPI", "YoYInflationCapFloorVolatility/UKRP1/22/5Y/0.02", 0.336249},
1256 {"14_YoYInflationCap_UKRPI", "YoYInflationCapFloorVolatility/UKRP1/28/7Y/0.02", -0.585254},
1257 {"14_YoYInflationCap_UKRPI", "YoYInflationCapFloorVolatility/UKRP1/34/10Y/0.02", 9.11852},
1258 {"14_YoYInflationCap_UKRPI", "YoYInflationCapFloorVolatility/UKRP1/4/1Y/0.02", -0.0981938},
1259 {"14_YoYInflationCap_UKRPI", "YoYInflationCurve/UKRP1/0/1Y", -0.501498},
1260 {"14_YoYInflationCap_UKRPI", "YoYInflationCurve/UKRP1/1/2Y", 0.104595},
1261 {"14_YoYInflationCap_UKRPI", "YoYInflationCurve/UKRP1/2/3Y", -0.258415},
1262 {"14_YoYInflationCap_UKRPI", "YoYInflationCurve/UKRP1/3/5Y", 1.13565},
1263 {"14_YoYInflationCap_UKRPI", "YoYInflationCurve/UKRP1/4/7Y", -2.64434},
1264 {"14_YoYInflationCap_UKRPI", "YoYInflationCurve/UKRP1/5/10Y", 52.8805},
1265 {"1_Swap_EUR", "DiscountCurve/EUR/0/6M", 3.55166},
1266 {"1_Swap_EUR", "DiscountCurve/EUR/1/1Y", 8.07755},
1267 {"1_Swap_EUR", "DiscountCurve/EUR/2/2Y", 15.787},
1268 {"1_Swap_EUR", "DiscountCurve/EUR/3/3Y", 36.2307},
1269 {"1_Swap_EUR", "DiscountCurve/EUR/4/5Y", 81.6737},
1270 {"1_Swap_EUR", "DiscountCurve/EUR/5/7Y", 146.97},
1271 {"1_Swap_EUR", "DiscountCurve/EUR/6/10Y", 170.249},
1272 {"1_Swap_EUR", "IndexCurve/EUR-EURIBOR-6M/0/6M", -492.385},
1273 {"1_Swap_EUR", "IndexCurve/EUR-EURIBOR-6M/1/1Y", 0.267094},
1274 {"1_Swap_EUR", "IndexCurve/EUR-EURIBOR-6M/2/2Y", -0.0571774},
1275 {"1_Swap_EUR", "IndexCurve/EUR-EURIBOR-6M/3/3Y", -0.00710812},
1276 {"1_Swap_EUR", "IndexCurve/EUR-EURIBOR-6M/4/5Y", -0.201881},
1277 {"1_Swap_EUR", "IndexCurve/EUR-EURIBOR-6M/5/7Y", 34.3404},
1278 {"1_Swap_EUR", "IndexCurve/EUR-EURIBOR-6M/6/10Y", 8928.34},
1279 {"2_Swap_USD", "DiscountCurve/USD/0/6M", -1.47948},
1280 {"2_Swap_USD", "DiscountCurve/USD/1/1Y", -3.99176},
1281 {"2_Swap_USD", "DiscountCurve/USD/2/2Y", -10.9621},
1282 {"2_Swap_USD", "DiscountCurve/USD/3/3Y", -25.1411},
1283 {"2_Swap_USD", "DiscountCurve/USD/4/5Y", -57.393},
1284 {"2_Swap_USD", "DiscountCurve/USD/5/7Y", -103.903},
1285 {"2_Swap_USD", "DiscountCurve/USD/6/10Y", -250.483},
1286 {"2_Swap_USD", "DiscountCurve/USD/7/15Y", -269.282},
1287 {"2_Swap_USD", "IndexCurve/USD-LIBOR-3M/0/6M", -198.455},
1288 {"2_Swap_USD", "IndexCurve/USD-LIBOR-3M/1/1Y", 0.163363},
1289 {"2_Swap_USD", "IndexCurve/USD-LIBOR-3M/2/2Y", -0.0310057},
1290 {"2_Swap_USD", "IndexCurve/USD-LIBOR-3M/3/3Y", -0.00237856},
1291 {"2_Swap_USD", "IndexCurve/USD-LIBOR-3M/4/5Y", -0.126057},
1292 {"2_Swap_USD", "IndexCurve/USD-LIBOR-3M/5/7Y", 0.117712},
1293 {"2_Swap_USD", "IndexCurve/USD-LIBOR-3M/6/10Y", 10.6825},
1294 {"2_Swap_USD", "IndexCurve/USD-LIBOR-3M/7/15Y", 9972.55},
1295 {"9_Cap_EUR", "DiscountCurve/EUR/0/6M", 0.000267715},
1296 {"9_Cap_EUR", "DiscountCurve/EUR/1/1Y", 1.93692e-06},
1297 {"9_Cap_EUR", "DiscountCurve/EUR/2/2Y", 0.00120582},
1298 {"9_Cap_EUR", "DiscountCurve/EUR/3/3Y", 0.0038175},
1299 {"9_Cap_EUR", "DiscountCurve/EUR/4/5Y", 0.00870478},
1300 {"9_Cap_EUR", "DiscountCurve/EUR/5/7Y", -0.0375854},
1301 {"9_Cap_EUR", "DiscountCurve/EUR/6/10Y", -0.25186},
1302 {"9_Cap_EUR", "IndexCurve/EUR-EURIBOR-6M/0/6M", 0.000685155},
1303 {"9_Cap_EUR", "IndexCurve/EUR-EURIBOR-6M/1/1Y", -0.00175651},
1304 {"9_Cap_EUR", "IndexCurve/EUR-EURIBOR-6M/2/2Y", -0.0118899},
1305 {"9_Cap_EUR", "IndexCurve/EUR-EURIBOR-6M/3/3Y", -0.301921},
1306 {"9_Cap_EUR", "IndexCurve/EUR-EURIBOR-6M/4/5Y", -2.28152},
1307 {"9_Cap_EUR", "IndexCurve/EUR-EURIBOR-6M/5/7Y", -7.16938},
1308 {"9_Cap_EUR", "IndexCurve/EUR-EURIBOR-6M/6/10Y", 16.3599},
1309 {"9_Cap_EUR", "OptionletVolatility/EUR/14/3Y/0.05", -0.0903623},
1310 {"9_Cap_EUR", "OptionletVolatility/EUR/19/5Y/0.05", 0.0577696},
1311 {"9_Cap_EUR", "OptionletVolatility/EUR/24/10Y/0.05", 41.9784},
1312 {"9_Cap_EUR", "OptionletVolatility/EUR/4/1Y/0.05", -0.0489527},
1313 {"9_Cap_EUR", "OptionletVolatility/EUR/9/2Y/0.05", 0.0995465}};
1314
1315 std::map<pair<string, string>, Real> sensiMap;
1316 for (Size i = 0; i < cachedResults.size(); ++i) {
1317 pair<string, string> p(cachedResults[i].id, cachedResults[i].label);
1318 sensiMap[p] = cachedResults[i].sensi;
1319 }
1320
1321 Real tolerance = 0.01;
1322 Size count = 0;
1323 for (auto data : parDelta) {
1324 pair<string, string> p = data.first;
1325 Real delta = data.second;
1326 if (fabs(delta) > 0.0) {
1327 count++;
1328 BOOST_CHECK_MESSAGE(sensiMap.find(p) != sensiMap.end(),
1329 "pair (" << p.first << ", " << p.second << ") not found in sensi map");
1330 if (sensiMap.find(p) != sensiMap.end()) {
1331 BOOST_CHECK_MESSAGE(fabs(delta - sensiMap[p]) < tolerance ||
1332 fabs((delta - sensiMap[p]) / delta) < tolerance,
1333 "sensitivity regression failed for pair ("
1334 << p.first << ", " << p.second << "): " << delta << " vs " << sensiMap[p]);
1335 }
1336 }
1337 }
1338 BOOST_CHECK_MESSAGE(count == cachedResults.size(), "number of non-zero par sensitivities ("
1339 << count << ") do not match regression data ("
1340 << cachedResults.size() << ")");
1341 ObservationMode::instance().setMode(backupMode);
1342 IndexManager::instance().clearHistories();
1343}
1344
1346 BOOST_TEST_MESSAGE("Testing Sensitivity Par Conversion (None observation mode)");
1347 testParConversion(ObservationMode::Mode::None);
1348}
1349
1351 BOOST_TEST_MESSAGE("Testing Sensitivity Par Conversion (Disable observation mode)");
1352 testParConversion(ObservationMode::Mode::Disable);
1353}
1354
1356 BOOST_TEST_MESSAGE("Testing Sensitivity Par Conversion (Defer observation mode)");
1357 testParConversion(ObservationMode::Mode::Defer);
1358}
1359
1361 BOOST_TEST_MESSAGE("Testing Sensitivity Par Conversion (Unregister observation mode)");
1362 testParConversion(ObservationMode::Mode::Unregister);
1363}
1364
1366 BOOST_TEST_MESSAGE("Testing 1d shifts");
1367
1368 SavedSettings backup;
1369 ObservationMode::Mode backupMode = ObservationMode::instance().mode();
1370 ObservationMode::instance().setMode(ObservationMode::Mode::None);
1371
1372 Date today = Date(14, April, 2016);
1373 Settings::instance().evaluationDate() = today;
1374
1375 BOOST_TEST_MESSAGE("Today is " << today);
1376
1377 // build model
1378 string baseCcy = "EUR";
1379 vector<string> ccys;
1380 ccys.push_back(baseCcy);
1381 ccys.push_back("GBP");
1382
1383 // Init market
1384 QuantLib::ext::shared_ptr<Market> initMarket = QuantLib::ext::make_shared<TestMarket>(today);
1385
1386 // build scenario sim market parameters
1387 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> simMarketData = setupSimMarketData2();
1388
1389 // build scenario sim market
1390 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarket> simMarket =
1391 QuantLib::ext::make_shared<analytics::ScenarioSimMarket>(initMarket, simMarketData);
1392
1393 // sensitivity config
1394 QuantLib::ext::shared_ptr<SensitivityScenarioData> sensiData = setupSensitivityScenarioData2();
1395
1396 // build scenario factory
1397 QuantLib::ext::shared_ptr<Scenario> baseScenario = simMarket->baseScenario();
1398 QuantLib::ext::shared_ptr<ScenarioFactory> scenarioFactory =
1399 QuantLib::ext::make_shared<ore::analytics::DeltaScenarioFactory>(baseScenario);
1400
1401 // build scenario generator
1402 QuantLib::ext::shared_ptr<SensitivityScenarioGenerator> scenarioGenerator =
1403 QuantLib::ext::make_shared<SensitivityScenarioGenerator>(sensiData, baseScenario, simMarketData, simMarket,
1404 scenarioFactory, false);
1405
1406 // cache initial zero rates
1407 vector<Period> tenors = simMarketData->yieldCurveTenors("");
1408 vector<Real> initialZeros(tenors.size());
1409 vector<Real> times(tenors.size());
1410 string ccy = simMarketData->ccys()[0];
1411 Handle<YieldTermStructure> ts = initMarket->discountCurve(ccy);
1412 DayCounter dc = ts->dayCounter();
1413 for (Size j = 0; j < tenors.size(); ++j) {
1414 Date d = today + simMarketData->yieldCurveTenors("")[j];
1415 initialZeros[j] = ts->zeroRate(d, dc, Continuous);
1416 times[j] = dc.yearFraction(today, d);
1417 }
1418
1419 // apply zero shifts for tenors on the shift curve
1420 // collect shifted data at tenors of the underlying curve
1421 // aggregate "observed" shifts
1422 // compare to expected total shifts
1423 vector<Period> shiftTenors = sensiData->discountCurveShiftData()["EUR"]->shiftTenors;
1424 vector<Time> shiftTimes(shiftTenors.size());
1425 for (Size i = 0; i < shiftTenors.size(); ++i)
1426 shiftTimes[i] = dc.yearFraction(today, today + shiftTenors[i]);
1427
1428 vector<Real> shiftedZeros(tenors.size());
1429 vector<Real> diffAbsolute(tenors.size(), 0.0);
1430 vector<Real> diffRelative(tenors.size(), 0.0);
1431 Real shiftSize = 0.01;
1432 ShiftType shiftTypeAbsolute = ShiftType::Absolute;
1433 ShiftType shiftTypeRelative = ShiftType::Relative;
1434 for (Size i = 0; i < shiftTenors.size(); ++i) {
1435 scenarioGenerator->applyShift(i, shiftSize, true, shiftTypeAbsolute, shiftTimes, initialZeros, times,
1436 shiftedZeros, true);
1437 for (Size j = 0; j < tenors.size(); ++j)
1438 diffAbsolute[j] += shiftedZeros[j] - initialZeros[j];
1439 scenarioGenerator->applyShift(i, shiftSize, true, shiftTypeRelative, shiftTimes, initialZeros, times,
1440 shiftedZeros, true);
1441 for (Size j = 0; j < tenors.size(); ++j)
1442 diffRelative[j] += shiftedZeros[j] / initialZeros[j] - 1.0;
1443 }
1444
1445 Real tolerance = 1.0e-10;
1446 for (Size j = 0; j < tenors.size(); ++j) {
1447 // BOOST_TEST_MESSAGE("1d shift: checking sensitivity to curve tenor point " << j << ": " << diff[j]);
1448 BOOST_CHECK_MESSAGE(fabs(diffAbsolute[j] - shiftSize) < tolerance,
1449 "inconsistency in absolute 1d shifts at curve tenor point " << j);
1450 BOOST_CHECK_MESSAGE(fabs(diffRelative[j] - shiftSize) < tolerance,
1451 "inconsistency in relative 1d shifts at curve tenor point " << j);
1452 }
1453 ObservationMode::instance().setMode(backupMode);
1454 IndexManager::instance().clearHistories();
1455}
1456
1458 BOOST_TEST_MESSAGE("Testing 2d shifts");
1459
1460 SavedSettings backup;
1461
1462 ObservationMode::Mode backupMode = ObservationMode::instance().mode();
1463 ObservationMode::instance().setMode(ObservationMode::Mode::None);
1464
1465 Date today = Date(14, April, 2016);
1466 Settings::instance().evaluationDate() = today;
1467
1468 BOOST_TEST_MESSAGE("Today is " << today);
1469
1470 // build model
1471 string baseCcy = "EUR";
1472 vector<string> ccys;
1473 ccys.push_back(baseCcy);
1474 ccys.push_back("GBP");
1475
1476 // Init market
1477 QuantLib::ext::shared_ptr<Market> initMarket = QuantLib::ext::make_shared<TestMarket>(today);
1478
1479 // build scenario sim market parameters
1480 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> simMarketData = setupSimMarketData2();
1481
1482 // build scenario sim market
1483 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarket> simMarket =
1484 QuantLib::ext::make_shared<analytics::ScenarioSimMarket>(initMarket, simMarketData);
1485
1486 // sensitivity config
1487 QuantLib::ext::shared_ptr<SensitivityScenarioData> sensiData = setupSensitivityScenarioData2();
1488
1489 // build scenario factory
1490 QuantLib::ext::shared_ptr<Scenario> baseScenario = simMarket->baseScenario();
1491 QuantLib::ext::shared_ptr<ScenarioFactory> scenarioFactory =
1492 QuantLib::ext::make_shared<ore::analytics::DeltaScenarioFactory>(baseScenario);
1493
1494 // build scenario generator
1495 QuantLib::ext::shared_ptr<SensitivityScenarioGenerator> scenarioGenerator =
1496 QuantLib::ext::make_shared<SensitivityScenarioGenerator>(sensiData, baseScenario, simMarketData, simMarket,
1497 scenarioFactory, false);
1498
1499 // cache initial zero rates
1500 vector<Period> expiries = simMarketData->swapVolExpiries("");
1501 vector<Period> terms = simMarketData->swapVolTerms("");
1502 vector<vector<Real>> initialData(expiries.size(), vector<Real>(terms.size(), 0.0));
1503 vector<Real> expiryTimes(expiries.size());
1504 vector<Real> termTimes(terms.size());
1505 string ccy = simMarketData->ccys()[0];
1506 Handle<SwaptionVolatilityStructure> ts = initMarket->swaptionVol(ccy);
1507 DayCounter dc = ts->dayCounter();
1508 for (Size i = 0; i < expiries.size(); ++i)
1509 expiryTimes[i] = dc.yearFraction(today, today + expiries[i]);
1510 for (Size j = 0; j < terms.size(); ++j)
1511 termTimes[j] = dc.yearFraction(today, today + terms[j]);
1512 for (Size i = 0; i < expiries.size(); ++i) {
1513 for (Size j = 0; j < terms.size(); ++j)
1514 initialData[i][j] = ts->volatility(expiries[i], terms[j], Null<Real>()); // ATM
1515 }
1516
1517 // apply shifts for tenors on the 2d shift grid
1518 // collect shifted data at tenors of the underlying 2d grid (different from the grid above)
1519 // aggregate "observed" shifts
1520 // compare to expected total shifts
1521 vector<Period> expiryShiftTenors = sensiData->swaptionVolShiftData()["EUR"].shiftExpiries;
1522 vector<Period> termShiftTenors = sensiData->swaptionVolShiftData()["EUR"].shiftTerms;
1523 vector<Real> shiftExpiryTimes(expiryShiftTenors.size());
1524 vector<Real> shiftTermTimes(termShiftTenors.size());
1525 for (Size i = 0; i < expiryShiftTenors.size(); ++i)
1526 shiftExpiryTimes[i] = dc.yearFraction(today, today + expiryShiftTenors[i]);
1527 for (Size j = 0; j < termShiftTenors.size(); ++j)
1528 shiftTermTimes[j] = dc.yearFraction(today, today + termShiftTenors[j]);
1529
1530 vector<vector<Real>> shiftedData(expiries.size(), vector<Real>(terms.size(), 0.0));
1531 vector<vector<Real>> diffAbsolute(expiries.size(), vector<Real>(terms.size(), 0.0));
1532 vector<vector<Real>> diffRelative(expiries.size(), vector<Real>(terms.size(), 0.0));
1533 Real shiftSize = 0.01; // arbitrary
1534 ShiftType shiftTypeAbsolute = ShiftType::Absolute;
1535 ShiftType shiftTypeRelative = ShiftType::Relative;
1536 for (Size i = 0; i < expiryShiftTenors.size(); ++i) {
1537 for (Size j = 0; j < termShiftTenors.size(); ++j) {
1538 scenarioGenerator->applyShift(i, j, shiftSize, true, shiftTypeAbsolute, shiftExpiryTimes, shiftTermTimes,
1539 expiryTimes, termTimes, initialData, shiftedData, true);
1540 for (Size k = 0; k < expiries.size(); ++k) {
1541 for (Size l = 0; l < terms.size(); ++l)
1542 diffAbsolute[k][l] += shiftedData[k][l] - initialData[k][l];
1543 }
1544 scenarioGenerator->applyShift(i, j, shiftSize, true, shiftTypeRelative, shiftExpiryTimes, shiftTermTimes,
1545 expiryTimes, termTimes, initialData, shiftedData, true);
1546 for (Size k = 0; k < expiries.size(); ++k) {
1547 for (Size l = 0; l < terms.size(); ++l)
1548 diffRelative[k][l] += shiftedData[k][l] / initialData[k][l] - 1.0;
1549 }
1550 }
1551 }
1552
1553 Real tolerance = 1.0e-10;
1554 for (Size k = 0; k < expiries.size(); ++k) {
1555 for (Size l = 0; l < terms.size(); ++l) {
1556 // BOOST_TEST_MESSAGE("2d shift: checking sensitivity to underlying grid point (" << k << ", " << l << "): "
1557 // << diff[k][l]);
1558 BOOST_CHECK_MESSAGE(fabs(diffAbsolute[k][l] - shiftSize) < tolerance,
1559 "inconsistency in absolute 2d shifts at grid point (" << k << ", " << l
1560 << "): " << diffAbsolute[k][l]);
1561 BOOST_CHECK_MESSAGE(fabs(diffRelative[k][l] - shiftSize) < tolerance,
1562 "inconsistency in relative 2d shifts at grid point (" << k << ", " << l
1563 << "): " << diffRelative[k][l]);
1564 }
1565 }
1566 ObservationMode::instance().setMode(backupMode);
1567 IndexManager::instance().clearHistories();
1568}
1569
1570BOOST_FIXTURE_TEST_SUITE(OREAnalyticsTestSuite, ore::test::OreaTopLevelFixture)
1571
1572BOOST_AUTO_TEST_SUITE(ParSensitivityAnalysis)
1573
1574BOOST_AUTO_TEST_CASE(ZeroShifts1d) {
1575 BOOST_TEST_MESSAGE("Testing 1-d Zero Shifts");
1577}
1578
1580 BOOST_TEST_MESSAGE("Testing 2-d Zero Shifts");
1582}
1583
1584BOOST_AUTO_TEST_CASE(ZeroSensitivity) {
1585 BOOST_TEST_MESSAGE("Testing Portfolio Zero Sensitivity");
1587}
1588
1589BOOST_AUTO_TEST_CASE(ParConversionNoneObs) {
1590 BOOST_TEST_MESSAGE("Testing Par Conversion NoneObs");
1592}
1593
1594BOOST_AUTO_TEST_CASE(ParConversionDisableObs) {
1595 BOOST_TEST_MESSAGE("Testing Par Conversion DisableObs");
1597}
1598
1599BOOST_AUTO_TEST_CASE(ParConversionDeferObs) {
1600 BOOST_TEST_MESSAGE("Testing Par Conversion DeferObs");
1602}
1603
1604BOOST_AUTO_TEST_CASE(ParConversionUnregisterObs) {
1605 BOOST_TEST_MESSAGE("Testing Par Conversion UnregisterObs");
1607}
1608
1609BOOST_AUTO_TEST_SUITE_END()
1610
1611BOOST_AUTO_TEST_SUITE_END()
1612
1613} // namespace testsuite
void alignPillars()
align pillars in scenario simulation market parameters with those of the par instruments
const ParContainer & parSensitivities() const
Return computed par sensitivities. Empty if they have not been computed yet.
std::map< ore::analytics::RiskFactorKey, std::pair< QuantLib::Real, QuantLib::Real > > shiftSizes() const
Return the zero rate and par rate absolute shift size for each risk factor key.
void computeParInstrumentSensitivities(const QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarket > &simMarket)
Compute par instrument sensitivities.
static bool isParType(ore::analytics::RiskFactorKey::KeyType type)
Returns true if risk factor type is applicable for par conversion.
void buildCube(const QuantLib::ext::shared_ptr< data::Portfolio > &portfolio, QuantLib::ext::shared_ptr< analytics::NPVCube > outputCube, std::vector< QuantLib::ext::shared_ptr< ValuationCalculator > > calculators, bool mporStickyDate=true, QuantLib::ext::shared_ptr< analytics::NPVCube > outputCubeNettingSet=nullptr, QuantLib::ext::shared_ptr< analytics::NPVCube > outputCptyCube=nullptr, std::vector< QuantLib::ext::shared_ptr< CounterpartyCalculator > > cptyCalculators={}, bool dryRun=false)
Build NPV cube.
std::map< ore::analytics::RiskFactorKey, QuantLib::Real > parDeltas(const std::string &tradeId) const
Return the non-zero par deltas for the given tradeId.
static const string defaultConfiguration
OREAnalytics Top level fixture.
static void testPortfolioZeroSensitivity()
Test that the portfolio shows the expected sensitivity (regression test)
static void test1dZeroShifts()
Test that shifting all shift curve tenor points by DELTA yields DELTA shifts at all tenor points of t...
static void test2dZeroShifts()
Test that shifting all 2-d shift tenor points by DELTA yields DELTA shifts at all 2-d grid points of ...
static void testParConversionDisableObs()
Test par conversion of sensitivities ("Disable" observation mode)
static void testParConversionDeferObs()
Test par conversion of sensitivities ("Defer" observation mode)
static void testParConversionUnregisterObs()
Test par conversion of sensitivities ("Unregister" observation mode)
static void testParConversionNoneObs()
Test par conversion of sensitivities ("None" observation mode)
factory class for cloning a cached scenario
A cube implementation that stores the cube in memory.
data
std::string to_string(const LocationInfo &l)
QuantLib::ext::shared_ptr< Trade > buildCap(string id, string ccy, string longShort, Real capRate, Real notional, int start, Size term, string floatFreq, string floatDC, string index, Calendar calendar, Natural spotDays, bool spotStartLag)
QuantLib::ext::shared_ptr< Trade > buildFxOption(string id, string longShort, string putCall, Size expiry, string boughtCcy, Real boughtAmount, string soldCcy, Real soldAmount, Real premium, string premiumCcy, string premiumDate)
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 > buildZeroBond(string id, string ccy, Real notional, Size term, string suffix)
QuantLib::ext::shared_ptr< Trade > buildEquityOption(string id, string longShort, string putCall, Size expiry, string equityName, string currency, Real strike, Real quantity, Real premium, string premiumCcy, string premiumDate)
QuantLib::ext::shared_ptr< Trade > buildFloor(string id, string ccy, string longShort, Real floorRate, Real notional, int start, Size term, 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)
BOOST_AUTO_TEST_CASE(ZeroShifts1d)
QuantLib::ext::shared_ptr< Trade > buildYYInflationCapFloor(string id, string ccy, Real notional, bool isCap, bool isLong, Real capFloorRate, int start, Size term, string yyFreq, string yyDC, string yyIndex, string observationLag, Size fixDays)
void testParConversion(ObservationMode::Mode om)
The base NPV cube class.
Singleton class to hold global Observation Mode.
Perfrom sensitivity analysis for a given portfolio.
Fixture that can be used at top level of OREAnalytics test suites.
std::size_t count
A Market class that can be updated by Scenarios.
A class to hold Scenario parameters for scenarioSimMarket.
Perform sensitivity analysis for a given portfolio.
A class to hold the parametrisation for building sensitivity scenarios.
Sensitivity scenario generation.
QuantLib::ext::shared_ptr< SensitivityScenarioData > setupSensitivityScenarioData2()
QuantLib::ext::shared_ptr< SensitivityScenarioData > setupSensitivityScenarioData5(bool parConversion)
QuantLib::ext::shared_ptr< analytics::ScenarioSimMarketParameters > setupSimMarketData5()
QuantLib::ext::shared_ptr< analytics::ScenarioSimMarketParameters > setupSimMarketData2()
SensitivityScenarioData::CurveShiftParData createCurveShiftData()
Par Sensitivity analysis tests.
The counterparty cube calculator interface.
The cube valuation core.
Class for converting zero sensitivities to par sensitivities.