Skip to content

Commit 6679dce

Browse files
author
jenkins
committed
git subrepo pull (merge) ore
subrepo: subdir: "ore" merged: "f24014c33c" upstream: origin: "git@gitlab.acadiasoft.net:qs/ore.git" branch: "master" commit: "1c3ee62b15" git-subrepo: version: "0.4.6" origin: "https://github.com/ingydotnet/git-subrepo" commit: "73a0129"
2 parents 0aa45d9 + 1c3ee62 commit 6679dce

15 files changed

Lines changed: 371 additions & 322 deletions

Examples/Example_2/ExpectedOutput/npv_payer.csv

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#TradeId,TradeType,Maturity,MaturityTime,NPV,NpvCurrency,NPV(Base),BaseCurrency,Notional,NotionalCurrency,Notional(Base),NettingSet,CounterParty
2-
Swaption_1_19,Swaption,2036-03-03,20.073770,780375.764209,EUR,780375.764209,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
3-
Swaption_2_18,Swaption,2036-03-03,20.073770,1001153.601683,EUR,1001153.601683,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
4-
Swaption_3_17,Swaption,2036-03-03,20.073770,1160727.483027,EUR,1160727.483027,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
5-
Swaption_4_16,Swaption,2036-03-03,20.073770,1254046.409145,EUR,1254046.409145,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
6-
Swaption_5_15,Swaption,2036-03-03,20.073770,1310853.645369,EUR,1310853.645369,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
7-
Swaption_6_14,Swaption,2036-03-03,20.073770,1328783.620035,EUR,1328783.620035,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
8-
Swaption_7_13,Swaption,2036-03-03,20.073770,1327178.118065,EUR,1327178.118065,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
9-
Swaption_8_12,Swaption,2036-03-03,20.073770,1279268.352242,EUR,1279268.352242,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
10-
Swaption_9_11,Swaption,2036-03-03,20.073770,1221728.923294,EUR,1221728.923294,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
2+
Swaption_01_19,Swaption,2036-03-03,20.073770,780375.764209,EUR,780375.764209,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
3+
Swaption_02_18,Swaption,2036-03-03,20.073770,1001153.601683,EUR,1001153.601683,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
4+
Swaption_03_17,Swaption,2036-03-03,20.073770,1160727.483027,EUR,1160727.483027,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
5+
Swaption_04_16,Swaption,2036-03-03,20.073770,1254046.409145,EUR,1254046.409145,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
6+
Swaption_05_15,Swaption,2036-03-03,20.073770,1310853.645369,EUR,1310853.645369,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
7+
Swaption_06_14,Swaption,2036-03-03,20.073770,1328783.620035,EUR,1328783.620035,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
8+
Swaption_07_13,Swaption,2036-03-03,20.073770,1327178.118065,EUR,1327178.118065,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
9+
Swaption_08_12,Swaption,2036-03-03,20.073770,1279268.352242,EUR,1279268.352242,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
10+
Swaption_09_11,Swaption,2036-03-03,20.073770,1221728.923294,EUR,1221728.923294,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
1111
Swaption_10_10,Swaption,2036-03-03,20.073770,1156594.462136,EUR,1156594.462136,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
1212
Swaption_11_9,Swaption,2036-03-03,20.073770,1072866.080225,EUR,1072866.080225,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
1313
Swaption_12_8,Swaption,2036-03-03,20.073770,981232.539406,EUR,981232.539406,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A

Examples/Example_2/ExpectedOutput/npv_receiver.csv

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#TradeId,TradeType,Maturity,MaturityTime,NPV,NpvCurrency,NPV(Base),BaseCurrency,Notional,NotionalCurrency,Notional(Base),NettingSet,CounterParty
2-
Swaption_1_19,Swaption,2036-03-03,20.073770,409213.522933,EUR,409213.522933,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
3-
Swaption_2_18,Swaption,2036-03-03,20.073770,524344.944312,EUR,524344.944312,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
4-
Swaption_3_17,Swaption,2036-03-03,20.073770,590351.499090,EUR,590351.499090,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
5-
Swaption_4_16,Swaption,2036-03-03,20.073770,615477.474118,EUR,615477.474118,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
6-
Swaption_5_15,Swaption,2036-03-03,20.073770,626569.675882,EUR,626569.675882,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
7-
Swaption_6_14,Swaption,2036-03-03,20.073770,637411.758750,EUR,637411.758750,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
8-
Swaption_7_13,Swaption,2036-03-03,20.073770,631893.882086,EUR,631893.882086,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
9-
Swaption_8_12,Swaption,2036-03-03,20.073770,632969.167411,EUR,632969.167411,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
10-
Swaption_9_11,Swaption,2036-03-03,20.073770,623756.005194,EUR,623756.005194,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
2+
Swaption_01_19,Swaption,2036-03-03,20.073770,409213.522933,EUR,409213.522933,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
3+
Swaption_02_18,Swaption,2036-03-03,20.073770,524344.944312,EUR,524344.944312,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
4+
Swaption_03_17,Swaption,2036-03-03,20.073770,590351.499090,EUR,590351.499090,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
5+
Swaption_04_16,Swaption,2036-03-03,20.073770,615477.474118,EUR,615477.474118,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
6+
Swaption_05_15,Swaption,2036-03-03,20.073770,626569.675882,EUR,626569.675882,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
7+
Swaption_06_14,Swaption,2036-03-03,20.073770,637411.758750,EUR,637411.758750,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
8+
Swaption_07_13,Swaption,2036-03-03,20.073770,631893.882086,EUR,631893.882086,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
9+
Swaption_08_12,Swaption,2036-03-03,20.073770,632969.167411,EUR,632969.167411,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
10+
Swaption_09_11,Swaption,2036-03-03,20.073770,623756.005194,EUR,623756.005194,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
1111
Swaption_10_10,Swaption,2036-03-03,20.073770,606396.429657,EUR,606396.429657,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
1212
Swaption_11_9,Swaption,2036-03-03,20.073770,577039.831014,EUR,577039.831014,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A
1313
Swaption_12_8,Swaption,2036-03-03,20.073770,540324.712582,EUR,540324.712582,EUR,10000000.00,EUR,10000000.00,CPTY_A,CPTY_A

Examples/Example_2/Input/portfolio_swaption_payer.xml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0"?>
22
<Portfolio>
3-
<Trade id="Swaption_1_19">
3+
<Trade id="Swaption_01_19">
44
<TradeType>Swaption</TradeType>
55
<Envelope>
66
<CounterParty>CPTY_A</CounterParty>
@@ -81,7 +81,7 @@
8181
</LegData>
8282
</SwaptionData>
8383
</Trade>
84-
<Trade id="Swaption_2_18">
84+
<Trade id="Swaption_02_18">
8585
<TradeType>Swaption</TradeType>
8686
<Envelope>
8787
<CounterParty>CPTY_A</CounterParty>
@@ -162,7 +162,7 @@
162162
</LegData>
163163
</SwaptionData>
164164
</Trade>
165-
<Trade id="Swaption_3_17">
165+
<Trade id="Swaption_03_17">
166166
<TradeType>Swaption</TradeType>
167167
<Envelope>
168168
<CounterParty>CPTY_A</CounterParty>
@@ -243,7 +243,7 @@
243243
</LegData>
244244
</SwaptionData>
245245
</Trade>
246-
<Trade id="Swaption_4_16">
246+
<Trade id="Swaption_04_16">
247247
<TradeType>Swaption</TradeType>
248248
<Envelope>
249249
<CounterParty>CPTY_A</CounterParty>
@@ -324,7 +324,7 @@
324324
</LegData>
325325
</SwaptionData>
326326
</Trade>
327-
<Trade id="Swaption_5_15">
327+
<Trade id="Swaption_05_15">
328328
<TradeType>Swaption</TradeType>
329329
<Envelope>
330330
<CounterParty>CPTY_A</CounterParty>
@@ -405,7 +405,7 @@
405405
</LegData>
406406
</SwaptionData>
407407
</Trade>
408-
<Trade id="Swaption_6_14">
408+
<Trade id="Swaption_06_14">
409409
<TradeType>Swaption</TradeType>
410410
<Envelope>
411411
<CounterParty>CPTY_A</CounterParty>
@@ -486,7 +486,7 @@
486486
</LegData>
487487
</SwaptionData>
488488
</Trade>
489-
<Trade id="Swaption_7_13">
489+
<Trade id="Swaption_07_13">
490490
<TradeType>Swaption</TradeType>
491491
<Envelope>
492492
<CounterParty>CPTY_A</CounterParty>
@@ -567,7 +567,7 @@
567567
</LegData>
568568
</SwaptionData>
569569
</Trade>
570-
<Trade id="Swaption_8_12">
570+
<Trade id="Swaption_08_12">
571571
<TradeType>Swaption</TradeType>
572572
<Envelope>
573573
<CounterParty>CPTY_A</CounterParty>
@@ -648,7 +648,7 @@
648648
</LegData>
649649
</SwaptionData>
650650
</Trade>
651-
<Trade id="Swaption_9_11">
651+
<Trade id="Swaption_09_11">
652652
<TradeType>Swaption</TradeType>
653653
<Envelope>
654654
<CounterParty>CPTY_A</CounterParty>

Examples/Example_2/Input/portfolio_swaption_receiver.xml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0"?>
22
<Portfolio>
3-
<Trade id="Swaption_1_19">
3+
<Trade id="Swaption_01_19">
44
<TradeType>Swaption</TradeType>
55
<Envelope>
66
<CounterParty>CPTY_A</CounterParty>
@@ -81,7 +81,7 @@
8181
</LegData>
8282
</SwaptionData>
8383
</Trade>
84-
<Trade id="Swaption_2_18">
84+
<Trade id="Swaption_02_18">
8585
<TradeType>Swaption</TradeType>
8686
<Envelope>
8787
<CounterParty>CPTY_A</CounterParty>
@@ -162,7 +162,7 @@
162162
</LegData>
163163
</SwaptionData>
164164
</Trade>
165-
<Trade id="Swaption_3_17">
165+
<Trade id="Swaption_03_17">
166166
<TradeType>Swaption</TradeType>
167167
<Envelope>
168168
<CounterParty>CPTY_A</CounterParty>
@@ -243,7 +243,7 @@
243243
</LegData>
244244
</SwaptionData>
245245
</Trade>
246-
<Trade id="Swaption_4_16">
246+
<Trade id="Swaption_04_16">
247247
<TradeType>Swaption</TradeType>
248248
<Envelope>
249249
<CounterParty>CPTY_A</CounterParty>
@@ -324,7 +324,7 @@
324324
</LegData>
325325
</SwaptionData>
326326
</Trade>
327-
<Trade id="Swaption_5_15">
327+
<Trade id="Swaption_05_15">
328328
<TradeType>Swaption</TradeType>
329329
<Envelope>
330330
<CounterParty>CPTY_A</CounterParty>
@@ -405,7 +405,7 @@
405405
</LegData>
406406
</SwaptionData>
407407
</Trade>
408-
<Trade id="Swaption_6_14">
408+
<Trade id="Swaption_06_14">
409409
<TradeType>Swaption</TradeType>
410410
<Envelope>
411411
<CounterParty>CPTY_A</CounterParty>
@@ -486,7 +486,7 @@
486486
</LegData>
487487
</SwaptionData>
488488
</Trade>
489-
<Trade id="Swaption_7_13">
489+
<Trade id="Swaption_07_13">
490490
<TradeType>Swaption</TradeType>
491491
<Envelope>
492492
<CounterParty>CPTY_A</CounterParty>
@@ -567,7 +567,7 @@
567567
</LegData>
568568
</SwaptionData>
569569
</Trade>
570-
<Trade id="Swaption_8_12">
570+
<Trade id="Swaption_08_12">
571571
<TradeType>Swaption</TradeType>
572572
<Envelope>
573573
<CounterParty>CPTY_A</CounterParty>
@@ -648,7 +648,7 @@
648648
</LegData>
649649
</SwaptionData>
650650
</Trade>
651-
<Trade id="Swaption_9_11">
651+
<Trade id="Swaption_09_11">
652652
<TradeType>Swaption</TradeType>
653653
<Envelope>
654654
<CounterParty>CPTY_A</CounterParty>

OREAnalytics/orea/app/inputparameters.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,10 @@ void InputParameters::setCubeFromFile(const std::string& file) {
323323
storeCreditStateNPVs_ = *r.storeCreditStateNPVs;
324324
}
325325

326+
void InputParameters::setCube(const ext::shared_ptr<NPVCube>& cube) {
327+
cube_ = cube;
328+
}
329+
326330
void InputParameters::setNettingSetCubeFromFile(const std::string& file) {
327331
nettingSetCube_ = ore::analytics::loadCube(file).cube;
328332
}
@@ -333,6 +337,8 @@ void InputParameters::setCptyCubeFromFile(const std::string& file) {
333337

334338
void InputParameters::setMarketCubeFromFile(const std::string& file) { mktCube_ = loadAggregationScenarioData(file); }
335339

340+
void InputParameters::setMarketCube(const QuantLib::ext::shared_ptr<AggregationScenarioData>& cube) { mktCube_ = cube; }
341+
336342
void InputParameters::setVarQuantiles(const std::string& s) {
337343
// parse to vector<Real>
338344
varQuantiles_ = parseListOfValues<Real>(s, &parseReal);

OREAnalytics/orea/app/inputparameters.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,11 @@ class InputParameters {
226226
cube. Therefore this method should be called after setScenarioGeneratorData(), setStoreFlows(),
227227
setStoreCreditStateNPVs() to ensure that the overwrite takes place. */
228228
void setCubeFromFile(const std::string& file);
229+
void setCube(const QuantLib::ext::shared_ptr<NPVCube>& cube);
229230
void setNettingSetCubeFromFile(const std::string& file);
230231
void setCptyCubeFromFile(const std::string& file);
231232
void setMarketCubeFromFile(const std::string& file);
233+
void setMarketCube(const QuantLib::ext::shared_ptr<AggregationScenarioData>& cube);
232234
// boost::shared_ptr<AggregationScenarioData> mktCube();
233235
void setFlipViewXVA(bool b) { flipViewXVA_ = b; }
234236
void setMporCashFlowMode(const MporCashFlowMode m) { mporCashFlowMode_ = m; }

OREAnalytics/orea/simm/simmbucketmapperbase.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ QuantLib::Date BucketMapping::validFromDate() const {
103103

104104
string SimmBucketMapperBase::bucket(const RiskType& riskType, const string& qualifier) const {
105105

106+
auto key = std::make_pair(riskType, qualifier);
107+
if (auto b = cache_.find(key); b != cache_.end())
108+
return b->second;
109+
106110
QL_REQUIRE(hasBuckets(riskType), "The risk type " << riskType << " does not have buckets");
107111

108112
// Vol risk type bucket mappings are stored in their non-vol counterparts
@@ -114,7 +118,9 @@ string SimmBucketMapperBase::bucket(const RiskType& riskType, const string& qual
114118

115119
// Deal with RiskType::IRCurve
116120
if (lookupRiskType == RiskType::IRCurve || lookupRiskType == RiskType::GIRR_DELTA) {
117-
return irBucket(qualifier);
121+
auto tmp = irBucket(qualifier);
122+
cache_[key] = tmp;
123+
return tmp;
118124
}
119125

120126
string bucket;
@@ -186,13 +192,15 @@ string SimmBucketMapperBase::bucket(const RiskType& riskType, const string& qual
186192
for (auto m : bucketMapping_.at(lookupRiskType).at(lookupName)) {
187193
if (m.validToDate() >= today && m.validFromDate() <= today && m.fallback() == !haveMapping) {
188194
bucket = m.bucket();
195+
cache_[key] = bucket;
189196
return bucket;
190197
}
191198
}
192199
TLOG("bucket mapping for risk type " << riskType << " and qualifier " << qualifier << " inactive, return Residual");
193200
bucket = "Residual";
194201
}
195202

203+
cache_[key] = bucket;
196204
return bucket;
197205
}
198206

@@ -332,6 +340,8 @@ XMLNode* SimmBucketMapperBase::toXML(ore::data::XMLDocument& doc) const {
332340
void SimmBucketMapperBase::addMapping(const RiskType& riskType, const string& qualifier, const string& bucket,
333341
const string& validFrom, const string& validTo, bool fallback) {
334342

343+
cache_.clear();
344+
335345
// Possibly map to non-vol counterpart for lookup
336346
RiskType rt = riskType;
337347
if (nonVolRiskTypeMap.count(riskType) > 0) {
@@ -393,6 +403,7 @@ void SimmBucketMapperBase::checkRiskType(const RiskType& riskType) const {
393403
}
394404

395405
void SimmBucketMapperBase::reset() {
406+
cache_.clear();
396407
// Clear the bucket mapper and add back the commodity mappings
397408
bucketMapping_.clear();
398409
failedMappings_.clear();

OREAnalytics/orea/simm/simmbucketmapperbase.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ class SimmBucketMapperBase : public SimmBucketMapper, public ore::data::XMLSeria
115115
std::set<CrifRecord::RiskType> rtWithBuckets_;
116116

117117
private:
118+
mutable std::map<std::pair<CrifRecord::RiskType, std::string>, std::string> cache_;
119+
118120
//! Reset the SIMM bucket mapper i.e. clears all mappings and adds the initial hard-coded commodity mappings
119121
void reset();
120122

OREAnalytics/orea/simm/simmcalculator.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -897,10 +897,16 @@ pair<map<string, Real>, bool> SimmCalculator::margin(const NettingSetDetails& ne
897897

898898
bool riskClassIsFX = rt == RiskType::FX || rt == RiskType::FXVol;
899899

900+
// precomputed
901+
map<std::pair<std::string,std::string>, std::vector<CrifRecord>> crifByQualifierAndBucket;
902+
map<std::string, std::vector<CrifRecord>> crifByBucket;
903+
900904
// Find the set of buckets and associated qualifiers for the netting set details, product class and risk type
901905
map<string, set<string>> buckets;
902906
for(const auto& it : crif.filterBy(nettingSetDetails, pc, rt)) {
903907
buckets[it.bucket].insert(it.qualifier);
908+
crifByQualifierAndBucket[std::make_pair(it.qualifier,it.bucket)].push_back(it);
909+
crifByBucket[it.bucket].push_back(it);
904910
}
905911

906912
// If there are no buckets, return early and set bool to false to indicate margin does not apply
@@ -925,7 +931,8 @@ pair<map<string, Real>, bool> SimmCalculator::margin(const NettingSetDetails& ne
925931

926932
// Get the concentration risk for each qualifier in current bucket i.e. $CR_k$ from SIMM docs
927933
map<string, Real> concentrationRisk;
928-
for (const auto& qualifier : buckets.at(bucket)) {
934+
935+
for (const auto& qualifier : kv.second) {
929936

930937
// Do not include Risk_FX components in the calculation currency in the SIMM calculation
931938
if (rt == RiskType::FX && qualifier == calcCcy) {
@@ -938,7 +945,7 @@ pair<map<string, Real>, bool> SimmCalculator::margin(const NettingSetDetails& ne
938945
}
939946

940947
// Pair of iterators to start and end of sensitivities with current qualifier
941-
auto pQualifier = crif.filterByQualifierAndBucket(nettingSetDetails, pc, rt, qualifier, bucket);
948+
auto pQualifier = crifByQualifierAndBucket[std::make_pair(qualifier,bucket)];
942949

943950
// One pass to get the concentration risk for this qualifier
944951
for (auto it = pQualifier.begin(); it != pQualifier.end(); ++it) {
@@ -955,9 +962,10 @@ pair<map<string, Real>, bool> SimmCalculator::margin(const NettingSetDetails& ne
955962
concentrationRisk[qualifier] = max(1.0, sqrt(std::abs(concentrationRisk[qualifier])));
956963
}
957964

965+
958966
// Calculate the margin component for the current bucket
959967
// Pair of iterators to start and end of sensitivities within current bucket
960-
auto pBucket = crif.filterByBucket(nettingSetDetails, pc, rt, bucket);
968+
auto pBucket = crifByBucket[bucket];
961969
for (auto itOuter = pBucket.begin(); itOuter != pBucket.end(); ++itOuter) {
962970
// Do not include Risk_FX components in the calculation currency in the SIMM calculation
963971
if (rt == RiskType::FX && itOuter->qualifier == calcCcy) {
@@ -975,6 +983,8 @@ pair<map<string, Real>, bool> SimmCalculator::margin(const NettingSetDetails& ne
975983
// Weighted sensitivity i.e. $WS_{k}$ from SIMM docs
976984
Real wsOuter =
977985
rwOuter * (itOuter->amountResultCcy * sigmaOuter * hvr) * concentrationRisk[itOuter->qualifier];
986+
// Get concentration risk for outer qualifier
987+
Real outerConcentrationRisk = concentrationRisk.at(itOuter->qualifier);
978988
// Update weighted sensitivity sum
979989
sumWeightedSensis[bucket] += wsOuter;
980990
// Add diagonal element to bucket margin
@@ -991,12 +1001,12 @@ pair<map<string, Real>, bool> SimmCalculator::margin(const NettingSetDetails& ne
9911001
continue;
9921002
}
9931003
// Correlation, $\rho_{k,l}$ in the SIMM docs
994-
Real corr = simmConfiguration_->correlation(rt, itOuter->qualifier, itOuter->label1, itOuter->label2,
995-
rt, itInner->qualifier, itInner->label1, itInner->label2,
996-
calcCcy);
1004+
Real corr =
1005+
simmConfiguration_->correlation(rt, itOuter->qualifier, itOuter->label1, itOuter->label2, rt,
1006+
itInner->qualifier, itInner->label1, itInner->label2, calcCcy);
9971007
// $f_{k,l}$ from the SIMM docs
998-
Real f = min(concentrationRisk.at(itOuter->qualifier), concentrationRisk.at(itInner->qualifier)) /
999-
max(concentrationRisk.at(itOuter->qualifier), concentrationRisk.at(itInner->qualifier));
1008+
Real f = min(outerConcentrationRisk, concentrationRisk.at(itInner->qualifier)) /
1009+
max(outerConcentrationRisk, concentrationRisk.at(itInner->qualifier));
10001010
// Add cross element to delta margin
10011011
Real sigmaInner = simmConfiguration_->sigma(rt, itInner->qualifier, itInner->label1, calcCcy);
10021012
Real rwInner = simmConfiguration_->weight(rt, itInner->qualifier, itInner->label1, calcCcy);

0 commit comments

Comments
 (0)