Skip to content

Commit d2adc86

Browse files
pcaspersjenkins
authored andcommitted
Merge remote-tracking branch 'origin/1.0.72' into 1072_into_master
1 parent 1b87b71 commit d2adc86

4 files changed

Lines changed: 61 additions & 25 deletions

File tree

OREAnalytics/orea/engine/parsensitivityanalysis.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,12 @@ void ParSensitivityAnalysis::computeParInstrumentSensitivities(const boost::shar
738738
boost::shared_ptr<ShiftScenarioGenerator> scenarioGenerator =
739739
boost::dynamic_pointer_cast<ShiftScenarioGenerator>(simMarketScenGen);
740740

741+
struct SimMarketResetter {
742+
SimMarketResetter(boost::shared_ptr<SimMarket> simMarket) : simMarket_(simMarket) {}
743+
~SimMarketResetter() { simMarket_->reset(); }
744+
boost::shared_ptr<SimMarket> simMarket_;
745+
} simMarketResetter(simMarket);
746+
741747
simMarket->reset();
742748
scenarioGenerator->reset();
743749
simMarket->update(asof_);

OREAnalytics/orea/engine/valuationengine.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ void ValuationEngine::buildCube(const boost::shared_ptr<data::Portfolio>& portfo
6868
boost::shared_ptr<analytics::NPVCube> outputCptyCube,
6969
vector<boost::shared_ptr<CounterpartyCalculator>> cptyCalculators, bool dryRun) {
7070

71+
struct SimMarketResetter {
72+
SimMarketResetter(boost::shared_ptr<SimMarket> simMarket) : simMarket_(simMarket) {}
73+
~SimMarketResetter() { simMarket_->reset(); }
74+
boost::shared_ptr<SimMarket> simMarket_;
75+
} simMarketResetter(simMarket_);
76+
7177
LOG("Build cube with mporStickyDate=" << mporStickyDate << ", dryRun=" << std::boolalpha << dryRun);
7278

7379
QL_REQUIRE(portfolio->size() > 0, "ValuationEngine: Error portfolio is empty");
@@ -265,7 +271,6 @@ void ValuationEngine::buildCube(const boost::shared_ptr<data::Portfolio>& portfo
265271
}
266272
}
267273

268-
simMarket_->reset();
269274
updateProgress(outputCube->samples(), outputCube->samples());
270275
loopTimer.stop();
271276
LOG("ValuationEngine completed: loop " << setprecision(2) << loopTimer.format(2, "%w") << " sec, "

OREAnalytics/orea/simm/simmcalculator.cpp

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,14 @@ typedef SimmConfiguration::SimmSide SimmSide;
6363

6464
SimmCalculator::SimmCalculator(const SimmNetSensitivities& simmNetSensitivities,
6565
const boost::shared_ptr<SimmConfiguration>& simmConfiguration,
66-
const string& calculationCcy, const string& resultCcy, const boost::shared_ptr<Market> market,
67-
const bool determineWinningRegulations,
68-
const bool enforceIMRegulations, const bool quiet)
66+
const string& calculationCcy, const string& resultCcy,
67+
const boost::shared_ptr<Market> market, const bool determineWinningRegulations,
68+
const bool enforceIMRegulations, const bool quiet,
69+
const map<SimmSide, set<NettingSetDetails>>& hasSEC,
70+
const map<SimmSide, set<NettingSetDetails>>& hasCFTC)
6971
: simmNetSensitivities_(simmNetSensitivities), simmConfiguration_(simmConfiguration),
7072
calculationCcy_(calculationCcy), resultCcy_(resultCcy.empty() ? calculationCcy_ : resultCcy), market_(market),
71-
quiet_(quiet) {
73+
quiet_(quiet), hasSEC_(hasSEC), hasCFTC_(hasCFTC) {
7274

7375
QL_REQUIRE(checkCurrency(calculationCcy_),
7476
"SIMM Calculator: The calculation currency (" << calculationCcy_ << ") must be a valid ISO currency code");
@@ -116,31 +118,50 @@ SimmCalculator::SimmCalculator(const SimmNetSensitivities& simmNetSensitivities,
116118

117119
// Some additional processing depending on the regulations applicable to each netting set
118120
for (auto& sv : regSensitivities_) {
121+
const SimmSide& side = sv.first;
119122

120123
for (auto& s : sv.second) {
124+
const NettingSetDetails& nettingDetails = s.first;
125+
121126
// Where there is SEC and CFTC in the portfolio, we add the CFTC trades to SEC,
122127
// but still continue with CFTC calculations
123-
const bool hasCFTC = s.second.find("CFTC") != s.second.end();
124-
const bool hasSEC = s.second.find("SEC") != s.second.end();
125-
if (hasCFTC && hasSEC) {
126-
const SimmNetSensitivities& netRecordsCFTC = s.second.at("CFTC")->netRecords(true);
127-
const SimmNetSensitivities& netRecordsSEC = s.second.at("SEC")->netRecords(true);
128-
for (const auto& cr : netRecordsCFTC) {
129-
// Only add CFTC records to SEC if the record was not already in SEC,
130-
// i.e. we skip over CRIF records with regulations specified as e.g. "..., CFTC, SEC, ..."
131-
if (netRecordsSEC.find(cr) == netRecordsSEC.end()) {
132-
if (!quiet_) {
133-
DLOG("SimmCalculator: Inserting CRIF record with CFTC "
134-
<< s.first << " regulation into SEC CRIF records: " << cr);
128+
const bool hasCFTCGlobal = hasCFTC_[side].find(nettingDetails) != hasCFTC_[side].end();
129+
const bool hasSECGlobal = hasSEC_[side].find(nettingDetails) != hasSEC_[side].end();
130+
const bool hasSECLocal = s.second.find("SEC") != s.second.end();
131+
const bool hasCFTCLocal = s.second.find("CFTC") != s.second.end();
132+
133+
if ((hasSECLocal && hasCFTCLocal) || (hasCFTCGlobal && hasSECGlobal)) {
134+
if (!hasSECLocal) {
135+
if (!hasCFTCLocal) {
136+
continue;
137+
} else {
138+
s.second["SEC"] = boost::make_shared<CrifLoader>(simmConfiguration_,
139+
CrifRecord::additionalHeaders, true, false);
140+
}
141+
}
142+
143+
if (hasCFTCLocal) {
144+
// At this point, we expect to have both SEC and CFTC sensitivities for the netting set
145+
const SimmNetSensitivities& netRecordsCFTC = s.second.at("CFTC")->netRecords(true);
146+
const SimmNetSensitivities& netRecordsSEC = s.second.at("SEC")->netRecords(true);
147+
for (const auto& cr : netRecordsCFTC) {
148+
// Only add CFTC records to SEC if the record was not already in SEC,
149+
// i.e. we skip over CRIF records with regulations specified as e.g. "..., CFTC, SEC, ..."
150+
if (netRecordsSEC.find(cr) == netRecordsSEC.end()) {
151+
if (!quiet_) {
152+
DLOG("SimmCalculator: Inserting CRIF record with CFTC "
153+
<< s.first << " regulation into SEC CRIF records: " << cr);
154+
}
155+
s.second.at("SEC")->add(cr);
135156
}
136-
s.second.at("SEC")->add(cr);
137157
}
138158
}
159+
139160
}
140161
// The CrifLoader was set initially without aggregation, so make sure to aggregate this now
141-
if (hasCFTC)
162+
if (hasCFTCLocal)
142163
s.second.at("CFTC")->aggregate();
143-
if (hasSEC)
164+
if (hasSECLocal)
144165
s.second.at("SEC")->aggregate();
145166

146167
// If netting set has "Unspecified" plus other regulations, the "Unspecified" sensis are to be excluded.

OREAnalytics/orea/simm/simmcalculator.hpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,14 @@ class SimmCalculator {
4747
*/
4848
SimmCalculator(const SimmNetSensitivities& simmNetSensitivities,
4949
const boost::shared_ptr<SimmConfiguration>& simmConfiguration,
50-
const std::string& calculationCcy = "USD",
51-
const std::string& resultCcy = "",
50+
const std::string& calculationCcy = "USD", const std::string& resultCcy = "",
5251
const boost::shared_ptr<ore::data::Market> market = nullptr,
53-
const bool determineWinningRegulations = true,
54-
const bool enforceIMRegulations = false,
55-
const bool quiet = false);
52+
const bool determineWinningRegulations = true, const bool enforceIMRegulations = false,
53+
const bool quiet = false,
54+
const std::map<SimmSide, std::set<NettingSetDetails>>& hasSEC =
55+
std::map<SimmSide, std::set<NettingSetDetails>>(),
56+
const std::map<SimmSide, std::set<NettingSetDetails>>& hasCFTC =
57+
std::map<SimmSide, std::set<NettingSetDetails>>());
5658

5759
//! Calculates SIMM for a given regulation under a given netting set
5860
const void calculateRegulationSimm(const SimmNetSensitivities& netRecords, const ore::data::NettingSetDetails& nsd,
@@ -121,6 +123,8 @@ class SimmCalculator {
121123
//! If true, no logging is written out
122124
bool quiet_;
123125

126+
std::map<SimmSide, std::set<NettingSetDetails>> hasSEC_, hasCFTC_;
127+
124128
//! For each netting set, whether all CRIF records' collect regulations are empty
125129
std::map<ore::data::NettingSetDetails, bool> collectRegsIsEmpty_;
126130

0 commit comments

Comments
 (0)