Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Functions
nettedexpsoure.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/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"
#include <orea/aggregation/exposurecalculator.hpp>
#include <orea/aggregation/nettedexposurecalculator.hpp>
#include <orea/aggregation/dimcalculator.hpp>
#include <orea/aggregation/dimregressioncalculator.hpp>
#include <orea/scenario/scenariogeneratordata.hpp>
#include <orea/scenario/aggregationscenariodata.hpp>
#include <ored/portfolio/nettingsetdetails.hpp>
#include <ored/portfolio/nettingsetdefinition.hpp>
#include <ored/portfolio/nettingsetmanager.hpp>
#include <orea/cube/cube_io.hpp>
#include <orea/engine/mporcalculator.hpp>
#include <ql/utilities/dataparsers.hpp>
#include <cmath>

Go to the source code of this file.

Functions

QuantLib::ext::shared_ptr< data::Conventionsconvs ()
 
QuantLib::ext::shared_ptr< PortfoliobuildPortfolio (Size portfolioSize, QuantLib::ext::shared_ptr< EngineFactory > &factory)
 
QuantLib::ext::shared_ptr< CrossAssetModelbuildCrossAssetModel (QuantLib::ext::shared_ptr< Market > &initMarket)
 
QuantLib::ext::shared_ptr< analytics::ScenarioSimMarketbuildScenarioSimMarket (QuantLib::ext::shared_ptr< DateGrid > dateGrid, QuantLib::ext::shared_ptr< Market > &initMarket, QuantLib::ext::shared_ptr< CrossAssetModel > &model, Size samples=1, Size seed=5, bool antithetic=false)
 
QuantLib::ext::shared_ptr< NPVCubebuildNPVCube (QuantLib::ext::shared_ptr< DateGrid > dateGrid, bool withCloseOutGrid, QuantLib::ext::shared_ptr< analytics::ScenarioSimMarket > &simMarket, QuantLib::ext::shared_ptr< Portfolio > &portfolio, bool mporStickyDate=false, Size samples=1, Size seed=5)
 
 BOOST_AUTO_TEST_CASE (NettedExposureCalculatorTest)
 

Function Documentation

◆ convs()

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

Definition at line 77 of file nettedexpsoure.cpp.

77 {
78 QuantLib::ext::shared_ptr<data::Conventions> conventions(new data::Conventions());
79
80 QuantLib::ext::shared_ptr<data::Convention> swapIndexConv(
81 new data::SwapIndexConvention("EUR-CMS-2Y", "EUR-6M-SWAP-CONVENTIONS"));
82 conventions->add(swapIndexConv);
83
84 QuantLib::ext::shared_ptr<data::Convention> swapConv(
85 new data::IRSwapConvention("EUR-6M-SWAP-CONVENTIONS", "TARGET", "Annual", "MF", "30/360", "EUR-EURIBOR-6M"));
86 conventions->add(swapConv);
87
88 InstrumentConventions::instance().setConventions(conventions);
89
90 return conventions;
91}
+ 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 93 of file nettedexpsoure.cpp.

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

◆ buildCrossAssetModel()

QuantLib::ext::shared_ptr< CrossAssetModel > buildCrossAssetModel ( QuantLib::ext::shared_ptr< Market > &  initMarket)

Definition at line 219 of file nettedexpsoure.cpp.

219 {
220 // Config
221 // Build IR configurations
222 CalibrationType calibrationType = CalibrationType::Bootstrap;
223 LgmData::ReversionType revType = LgmData::ReversionType::HullWhite;
224 LgmData::VolatilityType volType = LgmData::VolatilityType::Hagan;
225 vector<string> swaptionExpiries = {"1Y", "2Y", "3Y", "5Y", "7Y", "10Y", "15Y", "20Y", "30Y"};
226 vector<string> swaptionTerms = {"5Y", "5Y", "5Y", "5Y", "5Y", "5Y", "5Y", "5Y", "5Y"};
227 vector<string> swaptionStrikes(swaptionExpiries.size(), "ATM");
228 vector<Time> hTimes = {};
229 vector<Time> aTimes = {};
230
231 std::vector<QuantLib::ext::shared_ptr<IrModelData>> irConfigs;
232
233 vector<Real> hValues = {0.02};
234 vector<Real> aValues = {0.008};
235 irConfigs.push_back(QuantLib::ext::make_shared<IrLgmData>(
236 "EUR", calibrationType, revType, volType, false, ParamType::Constant, hTimes, hValues, true,
237 ParamType::Piecewise, aTimes, aValues, 0.0, 1.0, swaptionExpiries, swaptionTerms, swaptionStrikes));
238
239 hValues = {0.03};
240 aValues = {0.009};
241 irConfigs.push_back(QuantLib::ext::make_shared<IrLgmData>(
242 "USD", calibrationType, revType, volType, false, ParamType::Constant, hTimes, hValues, true,
243 ParamType::Piecewise, aTimes, aValues, 0.0, 1.0, swaptionExpiries, swaptionTerms, swaptionStrikes));
244
245
246 // Compile FX configurations
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
253 vector<Real> sigmaValues = {0.15};
254 fxConfigs.push_back(QuantLib::ext::make_shared<FxBsData>("USD", "EUR", calibrationType, true, ParamType::Piecewise,
255 sigmaTimes, sigmaValues, optionExpiries, optionStrikes));
256
257 map<CorrelationKey, Handle<Quote>> corr;
258 CorrelationFactor f_1{ CrossAssetModel::AssetType::IR, "EUR", 0 };
259 CorrelationFactor f_2{ CrossAssetModel::AssetType::IR, "USD", 0 };
260 corr[make_pair(f_1, f_2)] = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.6));
261
262 QuantLib::ext::shared_ptr<CrossAssetModelData> config(QuantLib::ext::make_shared<CrossAssetModelData>(irConfigs, fxConfigs, corr));
263
264 // Model Builder & Model
265 // model builder
266 QuantLib::ext::shared_ptr<CrossAssetModelBuilder> modelBuilder(new CrossAssetModelBuilder(initMarket, config));
267 return *modelBuilder->model();
268
269}
CalibrationType

◆ buildScenarioSimMarket()

QuantLib::ext::shared_ptr< analytics::ScenarioSimMarket > buildScenarioSimMarket ( QuantLib::ext::shared_ptr< DateGrid dateGrid,
QuantLib::ext::shared_ptr< Market > &  initMarket,
QuantLib::ext::shared_ptr< CrossAssetModel > &  model,
Size  samples = 1,
Size  seed = 5,
bool  antithetic = false 
)

Definition at line 271 of file nettedexpsoure.cpp.

276 {
277 // build scenario sim market parameters
278 Date today = initMarket->asofDate();
279
280 string baseCcy = "EUR";
281 vector<string> ccys;
282 ccys.push_back(baseCcy);
283 ccys.push_back("USD");
284
285 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> parameters(new analytics::ScenarioSimMarketParameters());
286 parameters->baseCcy() = baseCcy;
287 parameters->setDiscountCurveNames(ccys);
288 parameters->setYieldCurveTenors("",
289 {1 * Months, 6 * Months, 1 * Years, 2 * Years, 5 * Years, 10 * Years, 20 * Years});
290 parameters->setIndices({"EUR-EONIA", "EUR-EURIBOR-6M", "USD-LIBOR-3M"});
291
292 parameters->interpolation() = "LogLinear";
293
294 parameters->setSimulateSwapVols(false);
295 parameters->setSwapVolTerms("", {6 * Months, 1 * Years});
296 parameters->setSwapVolExpiries("", {1 * Years, 2 * Years});
297 parameters->swapVolKeys() = ccys;
298 parameters->swapVolDecayMode() = "ForwardVariance";
299
300 parameters->setFxVolExpiries("",
301 vector<Period>{1 * Months, 3 * Months, 6 * Months, 2 * Years, 3 * Years, 4 * Years, 5 * Years});
302 parameters->setFxVolDecayMode(string("ConstantVariance"));
303 parameters->setSimulateFXVols(false);
304
305 parameters->setFxVolCcyPairs({"USDEUR"});
306 parameters->setFxCcyPairs({"USDEUR"});
307
308 parameters->setAdditionalScenarioDataIndices({"EUR-EONIA"});
309 parameters->setAdditionalScenarioDataCcys({"EUR"});
310
311 // Path generator
312 if (auto tmp = QuantLib::ext::dynamic_pointer_cast<CrossAssetStateProcess>(model->stateProcess())) {
313 tmp->resetCache(dateGrid->timeGrid().size() - 1);
314 }
315 QuantLib::ext::shared_ptr<QuantExt::MultiPathGeneratorBase> pathGen =
316 QuantLib::ext::make_shared<MultiPathGeneratorMersenneTwister>(model->stateProcess(), dateGrid->timeGrid(), seed, antithetic);
317
318 // build scenario generator
319 QuantLib::ext::shared_ptr<ScenarioFactory> scenarioFactory = QuantLib::ext::make_shared<SimpleScenarioFactory>();
320 QuantLib::ext::shared_ptr<ScenarioGenerator> scenarioGenerator = QuantLib::ext::make_shared<CrossAssetModelScenarioGenerator>(model,
321 pathGen,
322 scenarioFactory,
323 parameters,
324 today,
325 dateGrid,
326 initMarket);
327
328 // build scenario sim market
329 convs();
330 auto simMarket = QuantLib::ext::make_shared<analytics::ScenarioSimMarket>(initMarket, parameters);
331 simMarket->scenarioGenerator() = scenarioGenerator;
332
333 QuantLib::ext::shared_ptr<AggregationScenarioData> scenarioData = QuantLib::ext::make_shared<InMemoryAggregationScenarioData>(dateGrid->timeGrid().size(), samples);
334 simMarket->aggregationScenarioData() = scenarioData;
335
336 return simMarket;
337}
QuantLib::ext::shared_ptr< data::Conventions > convs()
+ Here is the call graph for this function:

◆ buildNPVCube()

QuantLib::ext::shared_ptr< NPVCube > buildNPVCube ( QuantLib::ext::shared_ptr< DateGrid dateGrid,
bool  withCloseOutGrid,
QuantLib::ext::shared_ptr< analytics::ScenarioSimMarket > &  simMarket,
QuantLib::ext::shared_ptr< Portfolio > &  portfolio,
bool  mporStickyDate = false,
Size  samples = 1,
Size  seed = 5 
)

Definition at line 339 of file nettedexpsoure.cpp.

345 {
346
347 Date today = Settings::instance().evaluationDate();
348 // Now calculate exposure
349 ValuationEngine valEngine(today, dateGrid, simMarket);
350
351 Size depth = 1;
352 if (withCloseOutGrid)
353 depth = 2;
354
355 // Calculate Cube
356 boost::timer::cpu_timer t;
357 //BOOST_TEST_MESSAGE("dg->numDates() " << dateGrid->valuationDates().size()<<", " <<"dg->dates() "<<dateGrid->dates().size());
358 QuantLib::ext::shared_ptr<NPVCube> cube =
359 QuantLib::ext::make_shared<DoublePrecisionInMemoryCubeN>(today, portfolio->ids(), dateGrid->valuationDates(), samples, depth);
360
361 vector<QuantLib::ext::shared_ptr<ValuationCalculator>> calculators;
362 QuantLib::ext::shared_ptr<NPVCalculator> npvCalc = QuantLib::ext::make_shared<NPVCalculator>("EUR");
363 calculators.push_back(npvCalc);
364 if (withCloseOutGrid)
365 calculators.push_back(QuantLib::ext::make_shared<MPORCalculator>(npvCalc));
366 BOOST_TEST_MESSAGE("mporStickyDate "<<mporStickyDate);
367 valEngine.buildCube(portfolio, cube, calculators, mporStickyDate);
368 t.stop();
369 double elapsed = t.elapsed().wall * 1e-9;
370
371 if (withCloseOutGrid){
372 std::string fileName = "scenarioData_closeout.csv";
373 saveAggregationScenarioData(fileName, *simMarket->aggregationScenarioData());
374 fileName = "cube_closeout.csv";
375 saveCube(fileName, NPVCubeWithMetaData{cube, nullptr, boost::none, boost::none});
376 }else{
377 std::string fileName = "scenarioData.csv";
378 saveAggregationScenarioData(fileName, *simMarket->aggregationScenarioData());
379 fileName = "cube.csv";
380 saveCube(fileName, NPVCubeWithMetaData{cube, nullptr, boost::none, boost::none});
381 }
382
383 BOOST_TEST_MESSAGE("Cube generated in " << elapsed << " seconds");
384 return cube;
385}
void saveCube(const std::string &filename, const NPVCubeWithMetaData &cube, const bool doublePrecision)
Definition: cube_io.cpp:167
void saveAggregationScenarioData(const std::string &filename, const AggregationScenarioData &cube)
Definition: cube_io.cpp:302
+ Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE()

BOOST_AUTO_TEST_CASE ( NettedExposureCalculatorTest  )

Definition at line 504 of file nettedexpsoure.cpp.

504 {
505
506
507
508 CachedResultsData cachedResults;
509 std::map<tuple<string, string, string, string, string, string>, vector<Date>> cachedDefaultDates = cachedResults.defaultDates;
510 std::map<tuple<string, string, string, string, string, string>, vector<Real>> cachedDefaultValues = cachedResults.defaultValues;
511 std::map<tuple<string, string, string, string, string, string>, vector<Date>> cachedCloseOutDates = cachedResults.closeOutDates;
512 std::map<tuple<string, string, string, string, string, string>, vector<Real>> cachedCloseOutValues = cachedResults.closeOutValues;
513
514
515 BOOST_TEST_MESSAGE("Running NettedExposureCalculatorTestWithCloseOutGrid...");
516 Date referenceDate = Date(14, April, 2016);
517 BOOST_TEST_MESSAGE("Reference Date is "<<QuantLib::io::iso_date(referenceDate));
518 Settings::instance().evaluationDate() = referenceDate;
519
520 string dateGridStr;
521 QuantLib::ext::shared_ptr<DateGrid> dateGrid;
522 std::string nettingSetMpor = "1W";
523 BOOST_TEST_MESSAGE("Neting-set mpor is "<< nettingSetMpor);
524 vector<bool> withCloseOutGrid = {false, true};
525 bool mporStickyDate = false;
526 string mporModeStr = mporStickyDate ? "StickyDate": "ActualDate";
527 bool withCompounding = false;
528 string compoundingStr = withCompounding ? "withCompounding" : "woCompounding";
529 string calcTypeStr;
530
531 for(Size k = 0; k<withCloseOutGrid.size(); k++){
532
533 string closeOutGridStr = withCloseOutGrid[k] ? "withCloseOutGrid": "woCloseOutGrid";
534 std::vector<CollateralExposureHelper::CalculationType> calcTypes;
535 if (withCloseOutGrid[k]){
536 dateGridStr = "13,1M";
537 dateGrid = QuantLib::ext::make_shared<DateGrid>(dateGridStr);
538 calcTypes= {CollateralExposureHelper::CalculationType::NoLag};
539 }
540 else{
541 dateGridStr = "13,1W";
542 dateGrid = QuantLib::ext::make_shared<DateGrid>(dateGridStr);
543 calcTypes= {CollateralExposureHelper::CalculationType::Symmetric,
544 CollateralExposureHelper::CalculationType::AsymmetricCVA,
545 CollateralExposureHelper::CalculationType::AsymmetricDVA
546 };
547 }
548 Period Mpor(1, Weeks);
549 if (withCloseOutGrid[k]){
550 BOOST_TEST_MESSAGE("With close-out grid!");
551 BOOST_TEST_MESSAGE("MPOR in close-out grid= "<< Mpor);
552 dateGrid->addCloseOutDates(Mpor);
553 if (mporStickyDate){
554 BOOST_TEST_MESSAGE("With mpor mode sticky date!");
555 }else
556 BOOST_TEST_MESSAGE("With mpor mode actual date!");
557 }else
558 BOOST_TEST_MESSAGE("Without close-out grid!");
559
560 TestData td(referenceDate, dateGrid, withCloseOutGrid[k], mporStickyDate);
561
562 BOOST_TEST_MESSAGE("DateGrid: ");
563 BOOST_TEST_MESSAGE("t_0, "<<io::iso_date(referenceDate));
564 for(Size i=0; i<dateGrid->times().size(); i++)
565 BOOST_TEST_MESSAGE("t_"<<i+1<<", "<<QuantLib::io::iso_date(dateGrid->dates()[i]));
566
567 QuantLib::ext::shared_ptr<Market> initMarket = td.initMarket_;
568 QuantLib::ext::shared_ptr<NPVCube> cube = td.cube_;
569 QuantLib::ext::shared_ptr<Portfolio> portfolio = td.portfolio_;
570
571 std::string nettingSetId = portfolio->trades().begin()->second->envelope().nettingSetId();
572 NettingSetDetails nettingSetDetails(nettingSetId);
573
574 if (withCloseOutGrid[k]){
575 Period nettingSetMporPeriod = PeriodParser::parse(nettingSetMpor);
576 QL_REQUIRE(nettingSetMporPeriod == Mpor, "Netting-set mpor is not consistent with the closeout grid!");
577 }
578
579 std::vector<std::string> elgColls = {"EUR"};
580 QuantLib::ext::shared_ptr<NettingSetDefinition> nettingSetDefinition = QuantLib::ext::make_shared<NettingSetDefinition>(nettingSetDetails,
581 "Bilateral", "EUR", "EUR-EONIA",
582 0.0, 0.0, 0.0, 0.0, 0.0,
583 "FIXED", "1D", "1D",
584 nettingSetMpor, 0.0, 0.0, elgColls);
585 QuantLib::ext::shared_ptr<NettingSetManager> nettingSetManager = QuantLib::ext::make_shared<NettingSetManager>();
586 nettingSetManager->add(nettingSetDefinition);
587
588 // Empty balances for now
589 QuantLib::ext::shared_ptr<CollateralBalances> collateralBalances = QuantLib::ext::make_shared<CollateralBalances>();
590
591 map<string, vector<vector<Real>>> nettingSetDefaultValue;
592 map<string, vector<vector<Real>>> nettingSetCloseOutValue;
593 map<string, vector<vector<Real>>> nettingSetMporPositiveFlow;
594 map<string, vector<vector<Real>>> nettingSetMporNegativeFlow;
595 map<string, vector<vector<Real>>> nettingSetValue;
596 vector<Real> collateralBalance;
597 vector<vector<Real>> defaultValue;
598
599 std::string fileName;
600 Handle<AggregationScenarioData> asd;
601 QuantLib::ext::shared_ptr<CubeInterpretation> cubeInterpreter;
602 if (withCloseOutGrid[k]) {
603 fileName = "scenarioData_closeout.csv";
604 asd = Handle<AggregationScenarioData>(loadAggregationScenarioData(fileName));
605 cubeInterpreter = QuantLib::ext::make_shared<CubeInterpretation>(true, true, asd, dateGrid);
606 } else {
607 fileName = "scenarioData.csv";
608 asd = Handle<AggregationScenarioData>(loadAggregationScenarioData(fileName));
609 cubeInterpreter = QuantLib::ext::make_shared<CubeInterpretation>(true, false, asd);
610 }
611
612 if (!withCompounding){
613 compoundingStr = "woCompounding";
614 for (Size i =0; i<cube->dates().size(); i++)
615 asd->set(i, 0, 0, AggregationScenarioDataType::IndexFixing, "EUR-EONIA");
616 }
617
618 vector<string> regressors = {"EUR-EURIBOR-6M"};
619 QuantLib::ext::shared_ptr<InputParameters> inputs = QuantLib::ext::make_shared<InputParameters>();
620 QuantLib::ext::shared_ptr<RegressionDynamicInitialMarginCalculator> dimCalculator =
621 QuantLib::ext::make_shared<RegressionDynamicInitialMarginCalculator>(inputs, portfolio, cube, cubeInterpreter, *asd,
622 0.99, 14, 2, regressors);
623
624 BOOST_TEST_MESSAGE("initial NPV at "<< QuantLib::io::iso_date(referenceDate)<<": "<<cube->getT0(0));
625 for (Size i = 0; i<cube->dates().size(); i++)
626 BOOST_TEST_MESSAGE("defaultValue at "<< QuantLib::io::iso_date(dateGrid->valuationDates()[i])<<": "<<cubeInterpreter->getDefaultNpv(cube, 0, i, 0));
627
628 for (Size i = 0; i<cube->dates().size(); i++){
629 if (withCloseOutGrid[k]){
630 if (i != cube->dates().size()-1)
631 BOOST_TEST_MESSAGE("closeOutValue at "<< QuantLib::io::iso_date(dateGrid->closeOutDates()[i])<<": "<<cubeInterpreter->getCloseOutNpv(cube, 0, i, 0));
632 }
633 else{
634 if (i != cube->dates().size()-1)
635 BOOST_TEST_MESSAGE("closeOutValue at "<< QuantLib::io::iso_date(dateGrid->valuationDates()[i])<<": "<<cubeInterpreter->getCloseOutNpv(cube, 0, i, 0));
636 }
637
638 }
639
640 for(auto calcType : calcTypes){
642 calcTypeStr = "Symmetric";
643 else if (calcType == CollateralExposureHelper::AsymmetricCVA)
644 calcTypeStr = "AsymmetricCVA";
645 else if (calcType == CollateralExposureHelper::AsymmetricDVA)
646 calcTypeStr = "AsymmetricDVA";
647 else if (calcType == CollateralExposureHelper::NoLag)
648 calcTypeStr = "NoLag";
649 else
650 QL_FAIL("Collateral calculation type not covered");
651 BOOST_TEST_MESSAGE("Calculation type: "<< calcTypeStr);
652
653 QuantLib::ext::shared_ptr<ExposureCalculator> exposureCalculator = QuantLib::ext::make_shared<ExposureCalculator>(portfolio, cube, cubeInterpreter,
654 initMarket, false, "EUR", "Market",
655 0.99, calcType, false, false);
656 exposureCalculator->build();
657 nettingSetDefaultValue = exposureCalculator->nettingSetDefaultValue();
658 nettingSetCloseOutValue = exposureCalculator->nettingSetCloseOutValue();
659 nettingSetMporPositiveFlow = exposureCalculator->nettingSetMporPositiveFlow();
660 nettingSetMporNegativeFlow = exposureCalculator->nettingSetMporNegativeFlow();
661 QuantLib::ext::shared_ptr<NettedExposureCalculator> nettedExposureCalculator =
662 QuantLib::ext::make_shared<NettedExposureCalculator>(
663 portfolio, initMarket, cube, "EUR", "Market", 0.99, calcType, false, nettingSetManager, collateralBalances,
664 nettingSetDefaultValue, nettingSetCloseOutValue, nettingSetMporPositiveFlow,
665 nettingSetMporNegativeFlow, *asd, cubeInterpreter, false, dimCalculator, false, false, 0.1,
666 exposureCalculator->exposureCube(), 0, 0, false, mporStickyDate, MporCashFlowMode::Unspecified);
667 nettedExposureCalculator->build();
668 nettingSetValue = (calcType == CollateralExposureHelper::CalculationType::NoLag
669 ? nettedExposureCalculator->nettingSetCloseOutValue()
670 : nettedExposureCalculator->nettingSetDefaultValue());
671 collateralBalance = nettedExposureCalculator->expectedCollateral(nettingSetId);
672 BOOST_TEST_MESSAGE("defaultDate, defaultValue, closeOutDate, collateralBalance");
673 auto key = make_tuple(dateGridStr, nettingSetMpor, closeOutGridStr, mporModeStr, calcTypeStr, compoundingStr);
674
675 vector<Date> cdd = cachedDefaultDates[key];
676 vector<Real> cdv = cachedDefaultValues[key];
677 vector<Date> ccd = cachedCloseOutDates[key];
678 vector<Real> ccv = cachedCloseOutValues[key];
679 BOOST_TEST_MESSAGE("cdd "<<cdd.size());
680 BOOST_TEST_MESSAGE("cdv "<<cdv.size());
681 BOOST_TEST_MESSAGE("ccd "<<ccd.size());
682 BOOST_TEST_MESSAGE("ccv "<<ccv.size());
683 Real tolerance = 1E-2;
684 for (auto n : nettingSetValue){
685 vector<vector<Real>> defaultValue = n.second;
686 for (Size j = 0; j < cube->dates().size(); j++){
687 BOOST_TEST_MESSAGE(io::iso_date(dateGrid->valuationDates()[j])<<", "<<defaultValue[j][0] <<", "<< collateralBalance[j+1]);
688
689 BOOST_CHECK_MESSAGE(dateGrid->valuationDates()[j] == cdd[j],
690 "default date "<< dateGrid->valuationDates()[j] << " does not match with cashed default date "<< cdd[j]);
691 BOOST_CHECK_MESSAGE(fabs(defaultValue[j][0] - cdv[j]) < tolerance,
692 "default value "<< defaultValue[j][0] << " does not match with cashed default value "<< cdv[j]);
693 BOOST_CHECK_MESSAGE(fabs(collateralBalance[j+1] - ccv[j]) < tolerance,
694 "collateral balance "<< collateralBalance[j+1] << " does not match with cashed collateral balance "<< ccv[j]);
695 }
696 }
697 }
698 }
699}
Date referenceDate
QuantLib::ext::shared_ptr< AggregationScenarioData > loadAggregationScenarioData(const std::string &filename)
Definition: cube_io.cpp:234
Size size(const ValueType &v)
+ Here is the call graph for this function: