Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Functions
swapperformance.cpp File Reference
#include <boost/test/unit_test.hpp>
#include <boost/timer/timer.hpp>
#include <orea/cube/inmemorycube.hpp>
#include <orea/cube/npvcube.hpp>
#include <orea/engine/filteredsensitivitystream.hpp>
#include <orea/engine/observationmode.hpp>
#include <orea/engine/parametricvar.hpp>
#include <orea/engine/riskfilter.hpp>
#include <orea/engine/sensitivityaggregator.hpp>
#include <orea/engine/sensitivityanalysis.hpp>
#include <orea/engine/sensitivitycubestream.hpp>
#include <orea/engine/sensitivityfilestream.hpp>
#include <orea/engine/sensitivityinmemorystream.hpp>
#include <orea/engine/sensitivityrecord.hpp>
#include <orea/engine/sensitivitystream.hpp>
#include <orea/engine/stresstest.hpp>
#include <orea/engine/valuationcalculator.hpp>
#include <orea/engine/valuationengine.hpp>
#include <orea/scenario/crossassetmodelscenariogenerator.hpp>
#include <orea/scenario/scenariosimmarket.hpp>
#include <orea/scenario/scenariosimmarketparameters.hpp>
#include <orea/scenario/simplescenariofactory.hpp>
#include <ored/model/crossassetmodelbuilder.hpp>
#include <ored/model/lgmdata.hpp>
#include <ored/model/irlgmdata.hpp>
#include <ored/portfolio/builders/swap.hpp>
#include <ored/portfolio/portfolio.hpp>
#include <ored/portfolio/swap.hpp>
#include <ored/utilities/log.hpp>
#include <ored/utilities/osutils.hpp>
#include <oret/toplevelfixture.hpp>
#include <ql/math/randomnumbers/mt19937uniformrng.hpp>
#include <ql/time/calendars/target.hpp>
#include <ql/time/date.hpp>
#include <ql/time/daycounters/actualactual.hpp>
#include <qle/methods/multipathgeneratorbase.hpp>
#include <test/oreatoplevelfixture.hpp>
#include "testmarket.hpp"

Go to the source code of this file.

Functions

unsigned long randInt (MersenneTwisterUniformRng &rng, Size min, Size max)
 
const string & randString (MersenneTwisterUniformRng &rng, const vector< string > &strs)
 
bool randBoolean (MersenneTwisterUniformRng &rng)
 
QuantLib::ext::shared_ptr< data::Conventionsconvs ()
 
QuantLib::ext::shared_ptr< PortfoliobuildPortfolio (Size portfolioSize, QuantLib::ext::shared_ptr< EngineFactory > &factory)
 
void test_performance (Size portfolioSize, ObservationMode::Mode om, double nonZeroPVRatio, vector< Real > &epe_archived, vector< Real > &ene_archived)
 
 BOOST_AUTO_TEST_CASE (testSwapPerformanceNoneObs)
 
 BOOST_AUTO_TEST_CASE (testSingleSwapPerformanceNoneObs)
 
 BOOST_AUTO_TEST_CASE (testSwapPerformanceDisableObs)
 
 BOOST_AUTO_TEST_CASE (testSingleSwapPerformanceDisableObs)
 
 BOOST_AUTO_TEST_CASE (testSwapPerformanceDeferObs)
 
 BOOST_AUTO_TEST_CASE (testSingleSwapPerformanceDeferObs)
 
 BOOST_AUTO_TEST_CASE (testSwapPerformanceUnregisterObs)
 
 BOOST_AUTO_TEST_CASE (testSingleSwapPerformanceUnregisterObs)
 

Function Documentation

◆ randInt()

unsigned long randInt ( MersenneTwisterUniformRng &  rng,
Size  min,
Size  max 
)

Definition at line 74 of file swapperformance.cpp.

74 {
75 return min + (rng.nextInt32() % (max + 1 - min));
76}
RandomVariable max(RandomVariable x, const RandomVariable &y)
RandomVariable min(RandomVariable x, const RandomVariable &y)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ randString()

const string & randString ( MersenneTwisterUniformRng &  rng,
const vector< string > &  strs 
)

Definition at line 78 of file swapperformance.cpp.

78 {
79 return strs[randInt(rng, 0, strs.size() - 1)];
80}
unsigned long randInt(MersenneTwisterUniformRng &rng, Size min, Size max)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ randBoolean()

bool randBoolean ( MersenneTwisterUniformRng &  rng)

Definition at line 82 of file swapperformance.cpp.

82{ return randInt(rng, 0, 1) == 1; }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convs()

QuantLib::ext::shared_ptr< data::Conventions > convs ( )

Definition at line 84 of file swapperformance.cpp.

84 {
85 QuantLib::ext::shared_ptr<data::Conventions> conventions(new data::Conventions());
86
87 QuantLib::ext::shared_ptr<data::Convention> swapIndexConv(
88 new data::SwapIndexConvention("EUR-CMS-2Y", "EUR-6M-SWAP-CONVENTIONS"));
89 conventions->add(swapIndexConv);
90
91 QuantLib::ext::shared_ptr<data::Convention> swapConv(
92 new data::IRSwapConvention("EUR-6M-SWAP-CONVENTIONS", "TARGET", "Annual", "MF", "30/360", "EUR-EURIBOR-6M"));
93 conventions->add(swapConv);
94
95 InstrumentConventions::instance().setConventions(conventions);
96
97 return conventions;
98}
+ Here is the caller graph for this function:

◆ buildPortfolio()

QuantLib::ext::shared_ptr< Portfolio > buildPortfolio ( Size  portfolioSize,
QuantLib::ext::shared_ptr< EngineFactory > &  factory 
)

Definition at line 100 of file swapperformance.cpp.

100 {
101
102 QuantLib::ext::shared_ptr<Portfolio> portfolio(new Portfolio());
103
104 vector<string> ccys = {"EUR", "USD", "GBP", "JPY", "CHF"};
105
106 map<string, vector<string>> indices = {{"EUR", {"EUR-EURIBOR-6M"}},
107 {"USD", {"USD-LIBOR-3M"}},
108 {"GBP", {"GBP-LIBOR-6M"}},
109 {"CHF", {"CHF-LIBOR-6M"}},
110 {"JPY", {"JPY-LIBOR-6M"}}};
111
112 vector<string> fixedTenors = {"6M", "1Y"};
113
114 Size minTerm = 2;
115 Size maxTerm = 30;
116
117 Size minFixedBps = 10;
118 Size maxFixedBps = 400;
119
120 Size seed = 5; // keep this constant to ensure portfolio doesn't change
121 MersenneTwisterUniformRng rng(seed);
122
123 Date today = Settings::instance().evaluationDate();
124 Calendar cal = TARGET();
125 string calStr = "TARGET";
126 string conv = "MF";
127 string rule = "Forward";
128 Size days = 2;
129 string fixDC = "30/360";
130 string floatDC = "ACT/365";
131
132 vector<double> notional(1, 1000000);
133 vector<double> spread(1, 0);
134
135 for (Size i = 0; i < portfolioSize; i++) {
136 Size term = portfolioSize == 1 ? 20 : randInt(rng, minTerm, maxTerm);
137
138 // Start today +/- 1 Year
139 Date startDate = portfolioSize == 1 ? cal.adjust(today) : cal.adjust(today - 365 + randInt(rng, 0, 730));
140 Date endDate = cal.adjust(startDate + term * Years);
141
142 // date 2 string
143 ostringstream oss;
144 oss << io::iso_date(startDate);
145 string start(oss.str());
146 oss.str("");
147 oss.clear();
148 oss << io::iso_date(endDate);
149 string end(oss.str());
150
151 // ccy + index
152 string ccy = portfolioSize == 1 ? "EUR" : randString(rng, ccys);
153 string index = portfolioSize == 1 ? "EUR-EURIBOR-6M" : randString(rng, indices[ccy]);
154 string floatFreq = portfolioSize == 1 ? "6M" : index.substr(index.find('-', 4) + 1);
155
156 // This variable is not used and only here to ensure that the random numbers generated in
157 // subsequent blocks produce a swap portfolio, which is compatible with the archived values.
158 string fixedTenor = portfolioSize == 1 ? "1Y" : randString(rng, fixedTenors);
159 fixedTenor = fixedTenor + "_";
160
161 // fixed details
162 Real fixedRate = portfolioSize == 1 ? 0.02 : randInt(rng, minFixedBps, maxFixedBps) / 100.0;
163 string fixFreq = portfolioSize == 1 ? "1Y" : randString(rng, fixedTenors);
164
165 // envelope
166 Envelope env("CP");
167
168 // Schedules
169 ScheduleData floatSchedule(ScheduleRules(start, end, floatFreq, calStr, conv, conv, rule));
170 ScheduleData fixedSchedule(ScheduleRules(start, end, fixFreq, calStr, conv, conv, rule));
171
172 bool isPayer = randBoolean(rng);
173
174 // fixed Leg - with dummy rate
175 LegData fixedLeg(QuantLib::ext::make_shared<FixedLegData>(vector<double>(1, fixedRate)), isPayer, ccy, fixedSchedule,
176 fixDC, notional);
177
178 // float Leg
179 vector<double> spreads(1, 0);
180 LegData floatingLeg(QuantLib::ext::make_shared<FloatingLegData>(index, days, false, spread), !isPayer, ccy,
181 floatSchedule, floatDC, notional);
182
183 QuantLib::ext::shared_ptr<Trade> swap(new data::Swap(env, floatingLeg, fixedLeg));
184
185 // id
186 oss.clear();
187 oss.str("");
188 oss << "Trade_" << i + 1;
189 swap->id() = oss.str();
190
191 portfolio->add(swap);
192 }
193 // portfolio->save("port.xml");
194
195 portfolio->build(factory);
196
197 if (portfolio->size() != portfolioSize)
198 BOOST_ERROR("Failed to build portfolio (got " << portfolio->size() << " expected " << portfolioSize << ")");
199
200 // Dump stats about portfolio
201 Time maturity = 0;
202 DayCounter dc = ActualActual(ActualActual::ISDA);
203 map<string, Size> fixedFreqs;
204 map<string, Size> floatFreqs;
205 for (const auto& [tradeId, trade] : portfolio->trades()) {
206 maturity += dc.yearFraction(today, trade->maturity());
207
208 // fixed Freq
209 QuantLib::ext::shared_ptr<data::Swap> swap = QuantLib::ext::dynamic_pointer_cast<data::Swap>(trade);
210 string floatFreq = swap->legData()[0].schedule().rules().front().tenor();
211 string fixFreq = swap->legData()[1].schedule().rules().front().tenor();
212 QL_REQUIRE(swap->legData()[0].legType() == "Floating" && swap->legData()[1].legType() == "Fixed", "Leg mixup");
213 if (fixedFreqs.find(fixFreq) == fixedFreqs.end())
214 fixedFreqs[fixFreq] = 1;
215 else
216 fixedFreqs[fixFreq]++;
217 if (floatFreqs.find(floatFreq) == floatFreqs.end())
218 floatFreqs[floatFreq] = 1;
219 else
220 floatFreqs[floatFreq]++;
221 }
222 maturity /= portfolioSize;
223 BOOST_TEST_MESSAGE("Portfolio Size : " << portfolioSize);
224 BOOST_TEST_MESSAGE("Average Maturity : " << maturity);
225 ostringstream oss;
226 for (Size i = 0; i < ccys.size(); i++)
227 oss << ccys[i] << " ";
228 BOOST_TEST_MESSAGE("Currencies : " << oss.str());
229 // dump % breakdown of tenors
230 map<string, Size>::iterator it;
231 BOOST_TEST_MESSAGE("Fixed Tenors : ");
232 for (it = fixedFreqs.begin(); it != fixedFreqs.end(); ++it) {
233 Real perc = 100 * it->second / (Real)portfolioSize;
234 BOOST_TEST_MESSAGE(" " << it->first << " " << perc << " %");
235 }
236 BOOST_TEST_MESSAGE("Floating Tenors : ");
237 for (it = floatFreqs.begin(); it != floatFreqs.end(); ++it) {
238 Real perc = 100 * it->second / (Real)portfolioSize;
239 BOOST_TEST_MESSAGE(" " << it->first << " " << perc << " %");
240 }
241
242 return portfolio;
243}
Time maturity
bool randBoolean(MersenneTwisterUniformRng &rng)
const string & randString(MersenneTwisterUniformRng &rng, const vector< string > &strs)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ test_performance()

void test_performance ( Size  portfolioSize,
ObservationMode::Mode  om,
double  nonZeroPVRatio,
vector< Real > &  epe_archived,
vector< Real > &  ene_archived 
)

Definition at line 245 of file swapperformance.cpp.

246 {
247 BOOST_TEST_MESSAGE("Testing Swap Exposure Performance size=" << portfolioSize << "...");
248
249 SavedSettings backup;
250 ObservationMode::Mode backupOm = ObservationMode::instance().mode();
251 ObservationMode::instance().setMode(om);
252
253 // Log::instance().registerLogger(QuantLib::ext::make_shared<StderrLogger>());
254 // Log::instance().switchOn();
255
256 Date today = Date(14, April, 2016); // Settings::instance().evaluationDate();
257 Settings::instance().evaluationDate() = today;
258
259 BOOST_TEST_MESSAGE("Today is " << today);
260
261 string dateGridStr = "80,3M"; // 20 years
262 QuantLib::ext::shared_ptr<DateGrid> dg = QuantLib::ext::make_shared<DateGrid>(dateGridStr);
263 Size samples = 1000;
264
265 BOOST_TEST_MESSAGE("Date Grid : " << dateGridStr);
266 BOOST_TEST_MESSAGE("Samples : " << samples);
267 BOOST_TEST_MESSAGE("Swaps : " << portfolioSize);
268
269 // build model
270 string baseCcy = "EUR";
271 vector<string> ccys;
272 ccys.push_back(baseCcy);
273 ccys.push_back("GBP");
274 ccys.push_back("CHF");
275 ccys.push_back("USD");
276 ccys.push_back("JPY");
277
278 // Init market
279 QuantLib::ext::shared_ptr<Market> initMarket = QuantLib::ext::make_shared<TestMarket>(today);
280
281 // build scenario sim market parameters
282 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> parameters(new analytics::ScenarioSimMarketParameters());
283 parameters->baseCcy() = "EUR";
284 parameters->setDiscountCurveNames({"EUR", "GBP", "USD", "CHF", "JPY"});
285 parameters->setYieldCurveTenors("",
286 {1 * Months, 6 * Months, 1 * Years, 2 * Years, 5 * Years, 10 * Years, 20 * Years});
287 parameters->setIndices({"EUR-EURIBOR-6M", "USD-LIBOR-3M", "GBP-LIBOR-6M", "CHF-LIBOR-6M", "JPY-LIBOR-6M"});
288
289 parameters->interpolation() = "LogLinear";
290
291 parameters->setSimulateSwapVols(false);
292 parameters->setSwapVolTerms("", {6 * Months, 1 * Years});
293 parameters->setSwapVolExpiries("", {1 * Years, 2 * Years});
294 parameters->swapVolKeys() = ccys;
295 parameters->swapVolDecayMode() = "ForwardVariance";
296
297 parameters->setFxVolExpiries("",
298 vector<Period>{1 * Months, 3 * Months, 6 * Months, 2 * Years, 3 * Years, 4 * Years, 5 * Years});
299 parameters->setFxVolDecayMode(string("ConstantVariance"));
300 parameters->setSimulateFXVols(false);
301
302 parameters->setFxVolCcyPairs({"USDEUR", "GBPEUR", "CHFEUR", "JPYEUR"});
303 parameters->setFxCcyPairs({"USDEUR", "GBPEUR", "CHFEUR", "JPYEUR"});
304
305 parameters->setEquityVolExpiries("", {1 * Months, 3 * Months, 6 * Months, 2 * Years, 3 * Years, 4 * Years, 5 * Years});
306 parameters->setEquityVolDecayMode("ConstantVariance");
307 parameters->setSimulateEquityVols(false);
308
309 // Config
310
311 // Build IR configurations
312 CalibrationType calibrationType = CalibrationType::Bootstrap;
313 LgmData::ReversionType revType = LgmData::ReversionType::HullWhite;
314 LgmData::VolatilityType volType = LgmData::VolatilityType::Hagan;
315 vector<string> swaptionExpiries = {"1Y", "2Y", "3Y", "5Y", "7Y", "10Y", "15Y", "20Y", "30Y"};
316 vector<string> swaptionTerms = {"5Y", "5Y", "5Y", "5Y", "5Y", "5Y", "5Y", "5Y", "5Y"};
317 vector<string> swaptionStrikes(swaptionExpiries.size(), "ATM");
318 vector<Time> hTimes = {};
319 vector<Time> aTimes = {};
320
321 std::vector<QuantLib::ext::shared_ptr<IrModelData>> irConfigs;
322
323 vector<Real> hValues = {0.02};
324 vector<Real> aValues = {0.008};
325 irConfigs.push_back(QuantLib::ext::make_shared<IrLgmData>(
326 "EUR", calibrationType, revType, volType, false, ParamType::Constant, hTimes, hValues, true,
327 ParamType::Piecewise, aTimes, aValues, 0.0, 1.0, swaptionExpiries, swaptionTerms, swaptionStrikes));
328
329 hValues = {0.03};
330 aValues = {0.009};
331 irConfigs.push_back(QuantLib::ext::make_shared<IrLgmData>(
332 "USD", calibrationType, revType, volType, false, ParamType::Constant, hTimes, hValues, true,
333 ParamType::Piecewise, aTimes, aValues, 0.0, 1.0, swaptionExpiries, swaptionTerms, swaptionStrikes));
334
335 hValues = {0.04};
336 aValues = {0.01};
337 irConfigs.push_back(QuantLib::ext::make_shared<IrLgmData>(
338 "GBP", calibrationType, revType, volType, false, ParamType::Constant, hTimes, hValues, true,
339 ParamType::Piecewise, aTimes, aValues, 0.0, 1.0, swaptionExpiries, swaptionTerms, swaptionStrikes));
340
341 hValues = {0.04};
342 aValues = {0.01};
343 irConfigs.push_back(QuantLib::ext::make_shared<IrLgmData>(
344 "CHF", calibrationType, revType, volType, false, ParamType::Constant, hTimes, hValues, true,
345 ParamType::Piecewise, aTimes, aValues, 0.0, 1.0, swaptionExpiries, swaptionTerms, swaptionStrikes));
346
347 hValues = {0.04};
348 aValues = {0.01};
349 irConfigs.push_back(QuantLib::ext::make_shared<IrLgmData>(
350 "JPY", calibrationType, revType, volType, false, ParamType::Constant, hTimes, hValues, true,
351 ParamType::Piecewise, aTimes, aValues, 0.0, 1.0, swaptionExpiries, swaptionTerms, swaptionStrikes));
352
353 // Compile FX configurations
354 vector<string> optionExpiries = {"1Y", "2Y", "3Y", "5Y", "7Y", "10Y"};
355 vector<string> optionStrikes(optionExpiries.size(), "ATMF");
356 vector<Time> sigmaTimes = {};
357
358 std::vector<QuantLib::ext::shared_ptr<FxBsData>> fxConfigs;
359
360 vector<Real> sigmaValues = {0.15};
361 fxConfigs.push_back(QuantLib::ext::make_shared<FxBsData>("USD", "EUR", calibrationType, true, ParamType::Piecewise,
362 sigmaTimes, sigmaValues, optionExpiries, optionStrikes));
363
364 sigmaValues = {0.20};
365 fxConfigs.push_back(QuantLib::ext::make_shared<FxBsData>("GBP", "EUR", calibrationType, true, ParamType::Piecewise,
366 sigmaTimes, sigmaValues, optionExpiries, optionStrikes));
367
368 sigmaValues = {0.20};
369 fxConfigs.push_back(QuantLib::ext::make_shared<FxBsData>("CHF", "EUR", calibrationType, true, ParamType::Piecewise,
370 sigmaTimes, sigmaValues, optionExpiries, optionStrikes));
371
372 sigmaValues = {0.20};
373 fxConfigs.push_back(QuantLib::ext::make_shared<FxBsData>("JPY", "EUR", calibrationType, true, ParamType::Piecewise,
374 sigmaTimes, sigmaValues, optionExpiries, optionStrikes));
375
376 map<CorrelationKey, Handle<Quote>> corr;
377 CorrelationFactor f_1{ CrossAssetModel::AssetType::IR, "EUR", 0 };
378 CorrelationFactor f_2{ CrossAssetModel::AssetType::IR, "USD", 0 };
379 corr[make_pair(f_1, f_2)] = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.6));
380
381 QuantLib::ext::shared_ptr<CrossAssetModelData> config(QuantLib::ext::make_shared<CrossAssetModelData>(irConfigs, fxConfigs, corr));
382
383 // Model Builder & Model
384 // model builder
385 QuantLib::ext::shared_ptr<CrossAssetModelBuilder> modelBuilder(new CrossAssetModelBuilder(initMarket, config));
386 QuantLib::ext::shared_ptr<QuantExt::CrossAssetModel> model = *modelBuilder->model();
387 modelBuilder = NULL;
388
389 // Path generator
390 Size seed = 5;
391 bool antithetic = false;
392 if (auto tmp = QuantLib::ext::dynamic_pointer_cast<CrossAssetStateProcess>(model->stateProcess())) {
393 tmp->resetCache(dg->timeGrid().size() - 1);
394 }
395 QuantLib::ext::shared_ptr<QuantExt::MultiPathGeneratorBase> pathGen =
396 QuantLib::ext::make_shared<MultiPathGeneratorMersenneTwister>(model->stateProcess(), dg->timeGrid(), seed, antithetic);
397
398 // build scenario generator
399 QuantLib::ext::shared_ptr<ScenarioFactory> scenarioFactory = QuantLib::ext::make_shared<SimpleScenarioFactory>(true);
400 QuantLib::ext::shared_ptr<ScenarioGenerator> scenarioGenerator = QuantLib::ext::make_shared<CrossAssetModelScenarioGenerator>(
401 model, pathGen, scenarioFactory, parameters, today, dg, initMarket);
402
403 // build scenario sim market
404 convs();
405 auto simMarket = QuantLib::ext::make_shared<analytics::ScenarioSimMarket>(initMarket, parameters);
406 simMarket->scenarioGenerator() = scenarioGenerator;
407
408 // Build Portfolio
409 QuantLib::ext::shared_ptr<EngineData> data = QuantLib::ext::make_shared<EngineData>();
410 data->model("Swap") = "DiscountedCashflows";
411 data->engine("Swap") = "DiscountingSwapEngine";
412 QuantLib::ext::shared_ptr<EngineFactory> factory = QuantLib::ext::make_shared<EngineFactory>(data, simMarket);
413
414 QuantLib::ext::shared_ptr<Portfolio> portfolio = buildPortfolio(portfolioSize, factory);
415
416 BOOST_TEST_MESSAGE("Portfolio size after build: " << portfolio->size());
417
418 // Now calculate exposure
419 ValuationEngine valEngine(today, dg, simMarket);
420
421 // Calculate Cube
422 boost::timer::cpu_timer t;
423 QuantLib::ext::shared_ptr<NPVCube> cube =
424 QuantLib::ext::make_shared<DoublePrecisionInMemoryCube>(today, portfolio->ids(), dg->dates(), samples);
425 vector<QuantLib::ext::shared_ptr<ValuationCalculator>> calculators;
426 calculators.push_back(QuantLib::ext::make_shared<NPVCalculator>(baseCcy));
427 valEngine.buildCube(portfolio, cube, calculators);
428 t.stop();
429 double elapsed = t.elapsed().wall * 1e-9;
430
431 BOOST_TEST_MESSAGE("Cube generated in " << elapsed << " seconds");
432
433 Size dates = dg->dates().size();
434 Size numNPVs = dates * samples * portfolioSize;
435 BOOST_TEST_MESSAGE("Cube size = " << numNPVs << " elements");
436 BOOST_TEST_MESSAGE("Cube elements theoretical storage " << numNPVs * sizeof(Real) / (1024 * 1024) << " MB");
437 Real pricingTimeMicroSeconds = elapsed * 1000000 / numNPVs;
438 BOOST_TEST_MESSAGE("Avg Pricing time = " << pricingTimeMicroSeconds << " microseconds");
439
440 // Count the number of times we have an empty line, ie. swap expired.
441 // cube is trades/dates/samples
442 Size count = 0;
443 for (Size i = 0; i < portfolioSize; ++i) {
444 for (Size j = 0; j < dates; ++j) {
445 if (cube->get(i, j, 0) == 0 && cube->get(i, j, 1) == 0 && cube->get(i, j, 2) == 0)
446 ++count;
447 }
448 }
449 Real nonZeroPerc = 100 * (1 - (count / ((Real)portfolioSize * dates)));
450 BOOST_TEST_MESSAGE("Percentage of cube that is non-expired : " << nonZeroPerc << " %");
451 BOOST_TEST_MESSAGE("Avg Pricing time (for non-expired trades) = " << pricingTimeMicroSeconds * 100 / nonZeroPerc
452 << " microseconds");
453
454 // BOOST_TEST_MESSAGE(os::getSystemDetails());
455
456 // Compute portfolio EPE and ENE
457 vector<Real> eeVec, eneVec;
458 for (Size i = 0; i < dates; ++i) {
459 Real epe = 0.0, ene = 0.0;
460 for (Size j = 0; j < samples; ++j) {
461 Real npv = 0.0;
462 for (Size k = 0; k < portfolioSize; ++k)
463 npv += cube->get(k, i, j);
464 epe += std::max(npv, 0.0);
465 ene += std::max(-npv, 0.0);
466 }
467 epe /= samples;
468 ene /= samples;
469 // BOOST_TEST_MESSAGE("Exposures, " << i << " " << epe << " " << ene);
470 eeVec.push_back(epe);
471 eneVec.push_back(ene);
472 }
473
474 ObservationMode::instance().setMode(backupOm);
475 IndexManager::instance().clearHistories();
476
477 // check results
478 BOOST_CHECK_CLOSE(nonZeroPVRatio, nonZeroPerc, 0.005);
479
480 for (Size i = 0; i < epe_archived.size(); ++i) {
481 BOOST_CHECK_CLOSE(eeVec[i], epe_archived[i], 0.01);
482 }
483
484 for (Size i = 0; i < ene_archived.size(); ++i) {
485 BOOST_CHECK_CLOSE(eneVec[i], ene_archived[i], 0.01);
486 }
487}
data
CalibrationType
std::size_t count
QuantLib::ext::shared_ptr< Portfolio > buildPortfolio(Size portfolioSize, QuantLib::ext::shared_ptr< EngineFactory > &factory)
QuantLib::ext::shared_ptr< data::Conventions > convs()
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ BOOST_AUTO_TEST_CASE() [1/8]

BOOST_AUTO_TEST_CASE ( testSwapPerformanceNoneObs  )

Definition at line 528 of file swapperformance.cpp.

528 {
529 BOOST_TEST_MESSAGE("Testing Swap Performance (None observation mode)");
530 test_performance(100, ObservationMode::Mode::None, 70.5875, swap_epe_archived, swap_ene_archived);
531}
void test_performance(Size portfolioSize, ObservationMode::Mode om, double nonZeroPVRatio, vector< Real > &epe_archived, vector< Real > &ene_archived)
+ Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE() [2/8]

BOOST_AUTO_TEST_CASE ( testSingleSwapPerformanceNoneObs  )

Definition at line 533 of file swapperformance.cpp.

533 {
534 BOOST_TEST_MESSAGE("Testing Single Swap Performance (None observation mode)");
535 test_performance(1, ObservationMode::Mode::None, 98.75, single_swap_epe_archived, single_swap_ene_archived);
536}
+ Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE() [3/8]

BOOST_AUTO_TEST_CASE ( testSwapPerformanceDisableObs  )

Definition at line 538 of file swapperformance.cpp.

538 {
539 BOOST_TEST_MESSAGE("Testing Swap Performance (Disable observation mode)");
540 test_performance(100, ObservationMode::Mode::None, 70.5875, swap_epe_archived, swap_ene_archived);
541}
+ Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE() [4/8]

BOOST_AUTO_TEST_CASE ( testSingleSwapPerformanceDisableObs  )

Definition at line 543 of file swapperformance.cpp.

543 {
544 BOOST_TEST_MESSAGE("Testing Single Swap Performance (Disable observation mode)");
545 test_performance(1, ObservationMode::Mode::None, 98.75, single_swap_epe_archived, single_swap_ene_archived);
546}
+ Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE() [5/8]

BOOST_AUTO_TEST_CASE ( testSwapPerformanceDeferObs  )

Definition at line 548 of file swapperformance.cpp.

548 {
549 BOOST_TEST_MESSAGE("Testing Swap Performance (Defer observation mode)");
550 test_performance(100, ObservationMode::Mode::None, 70.5875, swap_epe_archived, swap_ene_archived);
551}
+ Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE() [6/8]

BOOST_AUTO_TEST_CASE ( testSingleSwapPerformanceDeferObs  )

Definition at line 553 of file swapperformance.cpp.

553 {
554 BOOST_TEST_MESSAGE("Testing Single Swap Performance (Defer observation mode)");
555 test_performance(1, ObservationMode::Mode::None, 98.75, single_swap_epe_archived, single_swap_ene_archived);
556}
+ Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE() [7/8]

BOOST_AUTO_TEST_CASE ( testSwapPerformanceUnregisterObs  )

Definition at line 558 of file swapperformance.cpp.

558 {
559 BOOST_TEST_MESSAGE("Testing Swap Performance (Unregister observation mode)");
560 test_performance(100, ObservationMode::Mode::None, 70.5875, swap_epe_archived, swap_ene_archived);
561}
+ Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE() [8/8]

BOOST_AUTO_TEST_CASE ( testSingleSwapPerformanceUnregisterObs  )

Definition at line 563 of file swapperformance.cpp.

563 {
564 BOOST_TEST_MESSAGE("Testing Single Swap Performance (Unregister observation mode)");
565 test_performance(1, ObservationMode::Mode::None, 98.75, single_swap_epe_archived, single_swap_ene_archived);
566}
+ Here is the call graph for this function: