147 {
148 SavedSettings backup;
149
150
151
152
153 Date today = Date(14, April, 2016);
154 Settings::instance().evaluationDate() = today;
155
156
157 QuantLib::ext::shared_ptr<DateGrid> dg = QuantLib::ext::make_shared<DateGrid>(dateGridString);
158 Size samples = 100;
159
160 BOOST_TEST_MESSAGE("Date Grid : " << dateGridString);
161
162
163 string baseCcy = "EUR";
164 vector<string> ccys;
165 ccys.push_back(baseCcy);
166 ccys.push_back("GBP");
167 ccys.push_back("CHF");
168 ccys.push_back("USD");
169 ccys.push_back("JPY");
170
171
172 QuantLib::ext::shared_ptr<Market> initMarket = QuantLib::ext::make_shared<TestMarket>(today);
173
174
176 parameters->baseCcy() = "EUR";
177 parameters->setDiscountCurveNames({"EUR", "GBP", "USD", "CHF", "JPY"});
178 parameters->setYieldCurveTenors("",
179 {1 * Months, 6 * Months, 1 * Years, 2 * Years, 5 * Years, 10 * Years, 20 * Years});
180 parameters->setIndices({"EUR-EURIBOR-6M", "USD-LIBOR-3M", "GBP-LIBOR-6M", "CHF-LIBOR-6M", "JPY-LIBOR-6M"});
181 parameters->interpolation() = "LogLinear";
182
183 parameters->setSwapVolTerms("", {6 * Months, 1 * Years});
184 parameters->setSwapVolExpiries("", {1 * Years, 2 * Years});
185 parameters->setSwapVolKeys(ccys);
186 parameters->swapVolDecayMode() = "ForwardVariance";
187 parameters->setSimulateSwapVols(false);
188
189 parameters->setFxVolExpiries("",
190 vector<Period>{1 * Months, 3 * Months, 6 * Months, 2 * Years, 3 * Years, 4 * Years, 5 * Years});
191 parameters->setFxVolDecayMode(string("ConstantVariance"));
192 parameters->setSimulateFXVols(false);
193
194 parameters->setFxVolCcyPairs({"USDEUR", "GBPEUR", "CHFEUR", "JPYEUR"});
195
196 parameters->setFxCcyPairs({"USDEUR", "GBPEUR", "CHFEUR", "JPYEUR"});
197
198 parameters->additionalScenarioDataIndices() = {"EUR-EURIBOR-6M", "USD-LIBOR-3M", "GBP-LIBOR-6M", "CHF-LIBOR-6M",
199 "JPY-LIBOR-6M"};
200 parameters->additionalScenarioDataCcys() = {"EUR", "GBP", "USD", "CHF", "JPY"};
201
202
203
204
208 vector<string> swaptionExpiries = {"1Y", "2Y", "3Y", "5Y", "7Y", "10Y", "15Y", "20Y", "30Y"};
209 vector<string> swaptionTerms = {"5Y", "5Y", "5Y", "5Y", "5Y", "5Y", "5Y", "5Y", "5Y"};
210 vector<string> swaptionStrikes(swaptionExpiries.size(), "ATM");
211 vector<Time> hTimes = {};
212 vector<Time> aTimes = {};
213
214 std::vector<QuantLib::ext::shared_ptr<IrModelData>> irConfigs;
215
216 vector<Real> hValues = {0.02};
217 vector<Real> aValues = {0.008};
218 irConfigs.push_back(QuantLib::ext::make_shared<IrLgmData>(
219 "EUR", calibrationType, revType, volType, false, ParamType::Constant, hTimes, hValues, true,
220 ParamType::Piecewise, aTimes, aValues, 0.0, 1.0, swaptionExpiries, swaptionTerms, swaptionStrikes));
221
222 hValues = {0.03};
223 aValues = {0.009};
224 irConfigs.push_back(QuantLib::ext::make_shared<IrLgmData>(
225 "USD", calibrationType, revType, volType, false, ParamType::Constant, hTimes, hValues, true,
226 ParamType::Piecewise, aTimes, aValues, 0.0, 1.0, swaptionExpiries, swaptionTerms, swaptionStrikes));
227
228 hValues = {0.04};
229 aValues = {0.01};
230 irConfigs.push_back(QuantLib::ext::make_shared<IrLgmData>(
231 "GBP", calibrationType, revType, volType, false, ParamType::Constant, hTimes, hValues, true,
232 ParamType::Piecewise, aTimes, aValues, 0.0, 1.0, swaptionExpiries, swaptionTerms, swaptionStrikes));
233
234 hValues = {0.04};
235 aValues = {0.01};
236 irConfigs.push_back(QuantLib::ext::make_shared<IrLgmData>(
237 "CHF", calibrationType, revType, volType, false, ParamType::Constant, hTimes, hValues, true,
238 ParamType::Piecewise, aTimes, aValues, 0.0, 1.0, swaptionExpiries, swaptionTerms, swaptionStrikes));
239
240 hValues = {0.04};
241 aValues = {0.01};
242 irConfigs.push_back(QuantLib::ext::make_shared<IrLgmData>(
243 "JPY", calibrationType, revType, volType, false, ParamType::Constant, hTimes, hValues, true,
244 ParamType::Piecewise, aTimes, aValues, 0.0, 1.0, swaptionExpiries, swaptionTerms, swaptionStrikes));
245
246
247 vector<string> optionExpiries = {"1Y", "2Y", "3Y", "5Y", "7Y", "10Y"};
248 vector<string> optionStrikes(optionExpiries.size(), "ATMF");
249 vector<Time> sigmaTimes = {};
250
251 std::vector<QuantLib::ext::shared_ptr<FxBsData>> fxConfigs;
252 vector<Real> sigmaValues = {0.15};
253 fxConfigs.push_back(QuantLib::ext::make_shared<FxBsData>("USD", "EUR", calibrationType, true, ParamType::Piecewise,
254 sigmaTimes, sigmaValues, optionExpiries, optionStrikes));
255
256 sigmaValues = {0.20};
257 fxConfigs.push_back(QuantLib::ext::make_shared<FxBsData>("GBP", "EUR", calibrationType, true, ParamType::Piecewise,
258 sigmaTimes, sigmaValues, optionExpiries, optionStrikes));
259
260 sigmaValues = {0.20};
261 fxConfigs.push_back(QuantLib::ext::make_shared<FxBsData>("CHF", "EUR", calibrationType, true, ParamType::Piecewise,
262 sigmaTimes, sigmaValues, optionExpiries, optionStrikes));
263
264 sigmaValues = {0.20};
265 fxConfigs.push_back(QuantLib::ext::make_shared<FxBsData>("JPY", "EUR", calibrationType, true, ParamType::Piecewise,
266 sigmaTimes, sigmaValues, optionExpiries, optionStrikes));
267
268 map<CorrelationKey, Handle<Quote>> corr;
271 corr[make_pair(f_1, f_2)] = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.6));
272
273 QuantLib::ext::shared_ptr<CrossAssetModelData> config(QuantLib::ext::make_shared<CrossAssetModelData>(irConfigs, fxConfigs, corr));
274
275
276
277 QuantLib::ext::shared_ptr<CrossAssetModelBuilder> modelBuilder(
new CrossAssetModelBuilder(initMarket, config));
278 QuantLib::ext::shared_ptr<QuantExt::CrossAssetModel> model = *modelBuilder->model();
279 modelBuilder = NULL;
280
281
282 BigNatural seed = 5;
283 bool antithetic = false;
284 if (auto tmp = QuantLib::ext::dynamic_pointer_cast<CrossAssetStateProcess>(model->stateProcess())) {
285 tmp->resetCache(dg->timeGrid().size() - 1);
286 }
287 QuantLib::ext::shared_ptr<QuantExt::MultiPathGeneratorBase> pathGen =
288 QuantLib::ext::make_shared<MultiPathGeneratorMersenneTwister>(model->stateProcess(), dg->timeGrid(), seed, antithetic);
289
290
291 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarket> simMarket =
292 QuantLib::ext::make_shared<analytics::ScenarioSimMarket>(initMarket, parameters);
293
294
295 QuantLib::ext::shared_ptr<ScenarioFactory> scenarioFactory =
296 QuantLib::ext::make_shared<SimpleScenarioFactory>(true);
297 QuantLib::ext::shared_ptr<ScenarioGenerator> scenarioGenerator = QuantLib::ext::make_shared<CrossAssetModelScenarioGenerator>(
298 model, pathGen, scenarioFactory, parameters, today, dg, initMarket);
299 simMarket->scenarioGenerator() = scenarioGenerator;
300
301
302 QuantLib::ext::shared_ptr<EngineData>
data = QuantLib::ext::make_shared<EngineData>();
303 data->model(
"Swap") =
"DiscountedCashflows";
304 data->engine(
"Swap") =
"DiscountingSwapEngine";
305 QuantLib::ext::shared_ptr<EngineFactory> factory = QuantLib::ext::make_shared<EngineFactory>(data, simMarket);
306
307 QuantLib::ext::shared_ptr<Portfolio> portfolio =
buildPortfolio(factory);
308
309
310 if (checkFixings) {
311 QuantLib::ext::shared_ptr<InMemoryAggregationScenarioData> inMemoryScenarioData =
312 QuantLib::ext::make_shared<InMemoryAggregationScenarioData>(dg->size(), samples);
313
314 simMarket->aggregationScenarioData() = inMemoryScenarioData;
315 }
316
317
319
320
321 cpu_timer t;
322 QuantLib::ext::shared_ptr<NPVCube> cube =
323 QuantLib::ext::make_shared<DoublePrecisionInMemoryCube>(today, portfolio->ids(), dg->dates(), samples);
324 vector<QuantLib::ext::shared_ptr<ValuationCalculator>> calculators;
325 calculators.push_back(QuantLib::ext::make_shared<NPVCalculator>(baseCcy));
326 valEngine.buildCube(portfolio, cube, calculators);
327 t.stop();
328
329 BOOST_TEST_MESSAGE("Cube generated in " << t.format(default_places, "%w") << " seconds");
330
331 map<string, vector<Real>> referenceFixings;
332
333 referenceFixings["11,1Y"] = {0.00739033, 0.0281673, 0.0344399, 0.03362, 0.0325276, 0.030573,
334 0.00895957, 0.0165584, 0.0194418, 0.0112834, 0.0239227};
335
336
337 referenceFixings["10,1Y"] = {0.00739033, 0.0296998, 0.0339535, 0.012449, 0.0134939, 0.0148095,
338 0.0188541, 0.0277254, 0.035063, 0.0105228, 0.0103237};
339
340 if (simMarket->aggregationScenarioData()) {
341 QL_REQUIRE(dateGridString == "10,1Y" || dateGridString == "11,1Y",
342 "date grid string " << dateGridString << " unexpected");
343
344 Size dateIndex = 5;
345 Size maxSample = 10;
346 string qualifier = "EUR-EURIBOR-6M";
347 Real tolerance = 1.0e-6;
348 for (Size sampleIndex = 0; sampleIndex <= maxSample; ++sampleIndex) {
349 Real fix = simMarket->aggregationScenarioData()->get(dateIndex, sampleIndex,
350 AggregationScenarioDataType::IndexFixing, qualifier);
351 Real ref = referenceFixings[dateGridString][sampleIndex];
352 if (fabs(fix - ref) > tolerance)
353 BOOST_FAIL("Stored fixing differs from reference value, found " << fix << ", expected " << ref);
354 }
355 }
356}
ScenarioSimMarket description.
QuantLib::ext::shared_ptr< Portfolio > buildPortfolio(QuantLib::ext::shared_ptr< EngineFactory > &factory)