Skip to content

Commit 078e631

Browse files
damienbarkerjenkins
authored andcommitted
Merge remote-tracking branch 'origin/master' into 71_into_master
1 parent 047138c commit 078e631

8 files changed

Lines changed: 120 additions & 104 deletions

OREAnalytics/orea/simm/crifrecord.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ struct RiskTypeTag {};
159159
struct BucketTag {};
160160
struct BucketQualifierTag {};
161161
struct QualifierTag {};
162+
struct NoProductClassQualifierTag {};
162163

163164
/*! A structure that we can use to aggregate CrifRecords across trades in a portfolio
164165
to provide the net sensitivities that we need to perform a downstream SIMM calculation.
@@ -199,6 +200,13 @@ typedef boost::multi_index_container<
199200
boost::multi_index::member<CrifRecord, SimmConfiguration::ProductClass, &CrifRecord::productClass>,
200201
boost::multi_index::member<CrifRecord, SimmConfiguration::RiskType, &CrifRecord::riskType>,
201202
boost::multi_index::member<CrifRecord, std::string, &CrifRecord::qualifier>>>,
203+
boost::multi_index::ordered_non_unique<
204+
boost::multi_index::tag<NoProductClassQualifierTag>,
205+
boost::multi_index::composite_key<
206+
CrifRecord,
207+
boost::multi_index::member<CrifRecord, NettingSetDetails, &CrifRecord::nettingSetDetails>,
208+
boost::multi_index::member<CrifRecord, SimmConfiguration::RiskType, &CrifRecord::riskType>,
209+
boost::multi_index::member<CrifRecord, std::string, &CrifRecord::qualifier>>>,
202210
boost::multi_index::ordered_non_unique<
203211
boost::multi_index::tag<BucketQualifierTag>,
204212
boost::multi_index::composite_key<

OREAnalytics/orea/simm/simmcalculator.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,7 +1675,7 @@ void SimmCalculator::addCrifRecord(const CrifRecord& crifRecord, const bool enfo
16751675
auto newCrifRecord = crifRecord;
16761676
newCrifRecord.collectRegulations.clear();
16771677
newCrifRecord.postRegulations.clear();
1678-
for (const string& r : regs)
1678+
for (const string& r : regs) {
16791679
if (r == "Excluded" ||
16801680
(r == "Unspecified" && enforceIMRegulations && !(collectRegsIsEmpty && postRegsIsEmpty))) {
16811681
continue;
@@ -1684,19 +1684,22 @@ void SimmCalculator::addCrifRecord(const CrifRecord& crifRecord, const bool enfo
16841684
if (!newCrifRecord.isSimmParameter())
16851685
tradeIds_[side][nettingSetDetails][r].insert(newCrifRecord.tradeId);
16861686

1687-
// Add CRIF record to the appropriate regulations
1688-
if (regSensitivities_[side][nettingSetDetails][r] == nullptr) {
1689-
// We aggregate SEC/CFTC CRIF records later because we do not want to lose trade ID data until we have combined these later.
1690-
const bool aggregateTrades = r == "SEC" || r == "CFTC" ? false : true;
1691-
regSensitivities_[side][nettingSetDetails][r] = boost::make_shared<CrifLoader>(simmConfiguration_, CrifRecord::additionalHeaders, true, aggregateTrades);
1692-
}
1687+
// Add CRIF record to the appropriate regulations
1688+
if (regSensitivities_[side][nettingSetDetails][r] == nullptr) {
1689+
// We aggregate SEC/CFTC CRIF records later because we do not want to lose trade ID data until we
1690+
// have combined these later.
1691+
const bool aggregateTrades = r == "SEC" || r == "CFTC" ? false : true;
1692+
regSensitivities_[side][nettingSetDetails][r] = boost::make_shared<CrifLoader>(
1693+
simmConfiguration_, CrifRecord::additionalHeaders, true, aggregateTrades);
1694+
}
16931695

16941696
// We make sure to ignore amountCcy when aggregating the records, since we will only be using amountUsd,
16951697
// and we may have CRIF records that are equal everywhere except for the amountCcy, and this will fail
16961698
// in the case of Risk_XCcyBasis and Risk_Inflation.
16971699
const bool onDiffAmountCcy = true;
16981700
regSensitivities_[side][nettingSetDetails][r]->add(newCrifRecord, onDiffAmountCcy);
16991701
}
1702+
}
17001703
}
17011704
}
17021705

OREAnalytics/orea/simm/simmconcentrationisdav2_6.cpp

Lines changed: 69 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -31,31 +31,31 @@ SimmConcentration_ISDA_V2_6::SimmConcentration_ISDA_V2_6(const boost::shared_ptr
3131
// clang-format off
3232

3333
// Populate flat thresholds
34-
flatThresholds_[RiskType::CreditVol] = 260;
35-
flatThresholds_[RiskType::CreditVolNonQ] = 145;
34+
flatThresholds_[RiskType::CreditVol] = 360;
35+
flatThresholds_[RiskType::CreditVolNonQ] = 70;
3636

3737
// Populate bucketed thresholds
3838
bucketedThresholds_[RiskType::IRCurve] = {
39-
{ "1", 33 },
40-
{ "2", 230 },
41-
{ "3", 44 },
42-
{ "4", 70 }
39+
{ "1", 30 },
40+
{ "2", 330 },
41+
{ "3", 130 },
42+
{ "4", 61 }
4343
};
4444

4545
bucketedThresholds_[RiskType::CreditQ] = {
46-
{ "1", 0.91 },
47-
{ "2", 0.19 },
48-
{ "3", 0.19 },
49-
{ "4", 0.19 },
50-
{ "5", 0.19 },
51-
{ "6", 0.19 },
52-
{ "7", 0.91 },
53-
{ "8", 0.19 },
54-
{ "9", 0.19 },
55-
{ "10", 0.19 },
56-
{ "11", 0.19 },
57-
{ "12", 0.19 },
58-
{ "Residual", 0.19 }
46+
{ "1", 1 },
47+
{ "2", 0.17 },
48+
{ "3", 0.17 },
49+
{ "4", 0.17 },
50+
{ "5", 0.17 },
51+
{ "6", 0.17 },
52+
{ "7", 1 },
53+
{ "8", 0.17 },
54+
{ "9", 0.17 },
55+
{ "10", 0.17 },
56+
{ "11", 0.17 },
57+
{ "12", 0.17 },
58+
{ "Residual", 0.17 }
5959
};
6060

6161
bucketedThresholds_[RiskType::CreditNonQ] = {
@@ -65,19 +65,19 @@ SimmConcentration_ISDA_V2_6::SimmConcentration_ISDA_V2_6(const boost::shared_ptr
6565
};
6666

6767
bucketedThresholds_[RiskType::Equity] = {
68-
{ "1", 10 },
69-
{ "2", 10 },
70-
{ "3", 10 },
71-
{ "4", 10 },
72-
{ "5", 21 },
73-
{ "6", 21 },
74-
{ "7", 21 },
75-
{ "8", 21 },
76-
{ "9", 1.4 },
77-
{ "10", 0.6 },
78-
{ "11", 2100 },
79-
{ "12", 2100 },
80-
{ "Residual", 0.6 }
68+
{ "1", 3 },
69+
{ "2", 3 },
70+
{ "3", 3 },
71+
{ "4", 3 },
72+
{ "5", 12 },
73+
{ "6", 12 },
74+
{ "7", 12 },
75+
{ "8", 12 },
76+
{ "9", 0.64 },
77+
{ "10", 0.37 },
78+
{ "11", 810 },
79+
{ "12", 810 },
80+
{ "Residual", 0.37 }
8181
};
8282

8383
bucketedThresholds_[RiskType::Commodity] = {
@@ -86,13 +86,13 @@ SimmConcentration_ISDA_V2_6::SimmConcentration_ISDA_V2_6(const boost::shared_ptr
8686
{ "3", 1700 },
8787
{ "4", 1700 },
8888
{ "5", 1700 },
89-
{ "6", 3200 },
90-
{ "7", 3200 },
89+
{ "6", 2800 },
90+
{ "7", 2800 },
9191
{ "8", 2700 },
9292
{ "9", 2700 },
9393
{ "10", 52 },
9494
{ "11", 530 },
95-
{ "12", 1600 },
95+
{ "12", 1300 },
9696
{ "13", 100 },
9797
{ "14", 100 },
9898
{ "15", 100 },
@@ -101,16 +101,16 @@ SimmConcentration_ISDA_V2_6::SimmConcentration_ISDA_V2_6(const boost::shared_ptr
101101
};
102102

103103
bucketedThresholds_[RiskType::FX] = {
104-
{ "1", 5100 },
105-
{ "2", 1200 },
106-
{ "3", 190 }
104+
{ "1", 3300 },
105+
{ "2", 880 },
106+
{ "3", 170 }
107107
};
108108

109109
bucketedThresholds_[RiskType::IRVol] = {
110-
{ "1", 120 },
111-
{ "2", 3300 },
112-
{ "3", 470 },
113-
{ "4", 570 }
110+
{ "1", 74 },
111+
{ "2", 4900 },
112+
{ "3", 520 },
113+
{ "4", 970 }
114114
};
115115

116116
bucketedThresholds_[RiskType::EquityVol] = {
@@ -122,40 +122,40 @@ SimmConcentration_ISDA_V2_6::SimmConcentration_ISDA_V2_6(const boost::shared_ptr
122122
{ "6", 1300 },
123123
{ "7", 1300 },
124124
{ "8", 1300 },
125-
{ "9", 40 },
126-
{ "10", 200 },
127-
{ "11", 5900 },
128-
{ "12", 5900 },
129-
{ "Residual", 40 }
125+
{ "9", 39 },
126+
{ "10", 190 },
127+
{ "11", 6400 },
128+
{ "12", 6400 },
129+
{ "Residual", 39 }
130130
};
131131

132132
bucketedThresholds_[RiskType::CommodityVol] = {
133-
{ "1", 210 },
134-
{ "2", 2700 },
135-
{ "3", 290 },
136-
{ "4", 290 },
137-
{ "5", 290 },
138-
{ "6", 5000 },
139-
{ "7", 5000 },
140-
{ "8", 920 },
141-
{ "9", 920 },
142-
{ "10", 100 },
143-
{ "11", 350 },
144-
{ "12", 720 },
145-
{ "13", 500 },
146-
{ "14", 500 },
147-
{ "15", 500 },
148-
{ "16", 65 },
149-
{ "17", 65 }
133+
{ "1", 390 },
134+
{ "2", 2900 },
135+
{ "3", 310 },
136+
{ "4", 310 },
137+
{ "5", 310 },
138+
{ "6", 6300 },
139+
{ "7", 6300 },
140+
{ "8", 1200 },
141+
{ "9", 1200 },
142+
{ "10", 120 },
143+
{ "11", 390 },
144+
{ "12", 1300 },
145+
{ "13", 590 },
146+
{ "14", 590 },
147+
{ "15", 590 },
148+
{ "16", 69 },
149+
{ "17", 69 }
150150
};
151151

152152
bucketedThresholds_[RiskType::FXVol] = {
153153
{ "1", 2800 },
154-
{ "2", 1300 },
155-
{ "3", 550 },
156-
{ "4", 490 },
157-
{ "5", 310 },
158-
{ "6", 200 }
154+
{ "2", 1400 },
155+
{ "3", 590 },
156+
{ "4", 520 },
157+
{ "5", 340 },
158+
{ "6", 210 }
159159
};
160160

161161
// clang-format on

OREAnalytics/orea/simm/simmconcentrationisdav2_6.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Copyright (C) 2023 Quaternion Risk Management Ltd
33
All rights reserved.
44
*/
5-
/*! \file orea/simm/simmconcentrationisdav2_6.hpp
5+
/*! \file orepsimm/orea/simmconcentrationisdav2_6.hpp
66
\brief SIMM concentration thresholds for SIMM version 2.6
77
*/
88

@@ -15,12 +15,12 @@
1515
#include <set>
1616
#include <string>
1717

18-
namespace ore {
18+
namespace ore{
1919
namespace analytics {
2020

2121
/*! Class giving the SIMM concentration thresholds as outlined in the document
22-
<em>ISDA SIMM Methodology, version 2.6.
23-
Effective Date: December 3, 2022.</em>
22+
<em>ISDA SIMM Methodology, version 2.6 .
23+
Effective Date: December 2, 2023.</em>
2424
*/
2525
class SimmConcentration_ISDA_V2_6 : public SimmConcentrationBase {
2626
public:

OREAnalytics/orea/simm/simmconfigurationisdav2_6.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ QuantLib::Size SimmConfiguration_ISDA_V2_6::group(const string& qualifier,
3838
}
3939

4040
QuantLib::Real SimmConfiguration_ISDA_V2_6::weight(const RiskType& rt, boost::optional<string> qualifier,
41-
boost::optional<std::string> label_1,
42-
const std::string& calculationCurrency) const {
41+
boost::optional<std::string> label_1,
42+
const std::string& calculationCurrency) const {
4343

4444
if (rt == RiskType::FX) {
4545
QL_REQUIRE(calculationCurrency != "", "no calculation currency provided weight");
@@ -80,7 +80,7 @@ QuantLib::Real SimmConfiguration_ISDA_V2_6::correlation(const RiskType& firstRt,
8080
SimmConfiguration_ISDA_V2_6::SimmConfiguration_ISDA_V2_6(const boost::shared_ptr<SimmBucketMapper>& simmBucketMapper,
8181
const QuantLib::Size& mporDays, const std::string& name,
8282
const std::string version)
83-
: SimmConfigurationBase(simmBucketMapper, name, version, mporDays) {
83+
: SimmConfigurationBase(simmBucketMapper, name, version, mporDays) {
8484

8585
// The differences in methodology for 1 Day horizon is described in
8686
// Standard Initial Margin Model: Technical Paper, ISDA SIMM Governance Forum, Version 10:
@@ -162,7 +162,7 @@ SimmConfiguration_ISDA_V2_6::SimmConfiguration_ISDA_V2_6(const boost::shared_ptr
162162
rwBucket_ = {
163163
{ RiskType::CreditQ, { 75, 90, 84, 54, 62, 48, 185, 343, 255, 250, 214, 173, 343 } },
164164
{ RiskType::CreditNonQ, { 280, 1300, 1300 } },
165-
{ RiskType::Equity, { 26, 28, 33, 27, 23, 25, 31, 27, 30, 29, 18, 18, 33 } },
165+
{ RiskType::Equity, { 30, 33, 36, 29, 26, 25, 34, 28, 36, 50, 19, 19, 50 } },
166166
{ RiskType::Commodity, { 48, 29, 33, 25, 35, 30, 60, 52, 68, 63, 21, 21, 15, 16, 13, 68, 17 } },
167167
{ RiskType::EquityVol, { 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.96, 0.45 } },
168168
};
@@ -233,7 +233,7 @@ SimmConfiguration_ISDA_V2_6::SimmConfiguration_ISDA_V2_6(const boost::shared_ptr
233233
rwBucket_ = {
234234
{ RiskType::CreditQ, { 20, 27, 17, 12, 13, 12, 50, 93, 51, 57, 43, 37, 93 } },
235235
{ RiskType::CreditNonQ, { 66, 280, 280 } },
236-
{ RiskType::Equity, { 9.1, 9.8, 10.0, 9.0, 7.7, 8.5, 9.9, 9.8, 9.9, 10, 6.1, 6.1, 10.0 } },
236+
{ RiskType::Equity, { 8.8, 9.6, 10, 9.0, 8.6, 8.6, 11, 10, 9.8, 14, 6.1, 6.1, 14 } },
237237
{ RiskType::Commodity, { 11, 9.1, 8.3, 7.4, 10, 9.3, 17, 12, 14, 18, 6.6, 6.7, 5.0, 4.8, 3.8, 18, 5.2 } },
238238
{ RiskType::EquityVol, { 0.093, 0.093, 0.093, 0.093, 0.093, 0.093, 0.093, 0.093, 0.093, 0.093, 0.093, 0.23, 0.093 } },
239239
};
@@ -367,17 +367,17 @@ SimmConfiguration_ISDA_V2_6::SimmConfiguration_ISDA_V2_6(const boost::shared_ptr
367367
// Equity inter-bucket correlations
368368
temp = {
369369
1.0, 0.18, 0.19, 0.19, 0.14, 0.16, 0.15, 0.16, 0.18, 0.12, 0.19, 0.19,
370-
0.18, 1.0, 0.22, 0.21, 0.15, 0.18, 0.18, 0.19, 0.2, 0.14, 0.21, 0.21,
371-
0.19, 0.22, 1.0, 0.22, 0.13, 0.17, 0.19, 0.17, 0.22, 0.13, 0.19, 0.19,
372-
0.19, 0.21, 0.22, 1.0, 0.18, 0.22, 0.22, 0.23, 0.22, 0.17, 0.25, 0.25,
373-
0.14, 0.15, 0.13, 0.18, 1.0, 0.29, 0.26, 0.29, 0.14, 0.24, 0.31, 0.31,
374-
0.16, 0.18, 0.17, 0.22, 0.29, 1.0, 0.33, 0.36, 0.17, 0.29, 0.38, 0.38,
375-
0.15, 0.18, 0.19, 0.22, 0.26, 0.33, 1.0, 0.33, 0.17, 0.28, 0.36, 0.36,
376-
0.16, 0.19, 0.17, 0.23, 0.29, 0.36, 0.33, 1.0, 0.18, 0.29, 0.39, 0.39,
377-
0.18, 0.2, 0.22, 0.22, 0.14, 0.17, 0.17, 0.18, 1.0, 0.13, 0.21, 0.21,
378-
0.12, 0.14, 0.13, 0.17, 0.24, 0.29, 0.28, 0.29, 0.13, 1.0, 0.3, 0.3,
379-
0.19, 0.21, 0.19, 0.25, 0.31, 0.38, 0.36, 0.39, 0.21, 0.3, 1.0, 0.44,
380-
0.19, 0.21, 0.19, 0.25, 0.31, 0.38, 0.36, 0.39, 0.21, 0.3, 0.44, 1.0
370+
0.18, 1.0, 0.22, 0.21, 0.15, 0.18, 0.17, 0.19, 0.2, 0.14, 0.21, 0.21,
371+
0.19, 0.22, 1.0, 0.22, 0.13, 0.16, 0.18, 0.17, 0.22, 0.13, 0.2, 0.2,
372+
0.19, 0.21, 0.22, 1.0, 0.17, 0.22, 0.22, 0.23, 0.22, 0.17, 0.26, 0.26,
373+
0.14, 0.15, 0.13, 0.17, 1.0, 0.29, 0.26, 0.29, 0.14, 0.24, 0.32, 0.32,
374+
0.16, 0.18, 0.16, 0.22, 0.29, 1.0, 0.34, 0.36, 0.17, 0.3, 0.39, 0.39,
375+
0.15, 0.17, 0.18, 0.22, 0.26, 0.34, 1.0, 0.33, 0.16, 0.28, 0.36, 0.36,
376+
0.16, 0.19, 0.17, 0.23, 0.29, 0.36, 0.33, 1.0, 0.17, 0.29, 0.4, 0.4,
377+
0.18, 0.2, 0.22, 0.22, 0.14, 0.17, 0.16, 0.17, 1.0, 0.13, 0.21, 0.21,
378+
0.12, 0.14, 0.13, 0.17, 0.24, 0.3, 0.28, 0.29, 0.13, 1.0, 0.3, 0.3,
379+
0.19, 0.21, 0.2, 0.26, 0.32, 0.39, 0.36, 0.4, 0.21, 0.3, 1.0, 0.45,
380+
0.19, 0.21, 0.2, 0.26, 0.32, 0.39, 0.36, 0.4, 0.21, 0.3, 0.45, 1.0
381381
};
382382
interBucketCorrelation_[RiskType::Equity] = Matrix(12, 12, temp.begin(), temp.end());
383383

@@ -404,7 +404,7 @@ SimmConfiguration_ISDA_V2_6::SimmConfiguration_ISDA_V2_6(const boost::shared_ptr
404404
interBucketCorrelation_[RiskType::Commodity] = Matrix(17, 17, temp.begin(), temp.end());
405405

406406
// Equity intra-bucket correlations (exclude Residual and deal with it in the method - it is 0%) - changed
407-
intraBucketCorrelation_[RiskType::Equity] = { 0.18, 0.2, 0.28, 0.24, 0.25, 0.35, 0.35, 0.37, 0.23, 0.26, 0.44, 0.44 };
407+
intraBucketCorrelation_[RiskType::Equity] = { 0.18, 0.2, 0.28, 0.24, 0.25, 0.36, 0.35, 0.37, 0.23, 0.27, 0.45, 0.45 };
408408

409409
// Commodity intra-bucket correlations
410410
intraBucketCorrelation_[RiskType::Commodity] = { 0.83, 0.97, 0.93, 0.97, 0.98, 0.9, 0.98, 0.49, 0.8, 0.46, 0.58, 0.53, 0.62, 0.16, 0.18, 0, 0.38 };

OREAnalytics/orea/simm/simmconfigurationisdav2_6.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
All rights reserved.
44
*/
55

6-
/*! \file orea/simm/simmconfigurationisdav2_6.hpp
6+
/*! \file orepsimm/orea/simmconfigurationisdav2_6.hpp
77
\brief SIMM configuration for SIMM version 2.6
88
*/
99

@@ -16,13 +16,13 @@ namespace analytics {
1616

1717
/*! Class giving the SIMM configuration as outlined in the document
1818
<em>ISDA SIMM Methodology, version 2.6.
19-
Effective Date: 3 December 2023.</em>
19+
Effective Date: December 2, 2023.</em>
2020
*/
21-
class SimmConfiguration_ISDA_V2_6: public SimmConfigurationBase {
21+
class SimmConfiguration_ISDA_V2_6 : public SimmConfigurationBase {
2222
public:
2323
SimmConfiguration_ISDA_V2_6(const boost::shared_ptr<SimmBucketMapper>& simmBucketMapper,
2424
const QuantLib::Size& mporDays = 10,
25-
const std::string& name = "SIMM ISDA 2.6 (3 December 2023)",
25+
const std::string& name = "SIMM ISDA 2.6 (<INSERT PUBLISHING DATE HERE>)",
2626
const std::string version = "2.6");
2727

2828
//! Return the SIMM <em>Label2</em> value for the given interest rate index

OREAnalytics/orea/simm/utilities.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ SimmVersion parseSimmVersion(const string& version) {
171171
{"2.3.8", SimmVersion::V2_3_8},
172172
{"2.5", SimmVersion::V2_5},
173173
{"2.5A", SimmVersion::V2_5A},
174-
{"2.5.3", SimmVersion::V2_6},
174+
{"2.5.6", SimmVersion::V2_6},
175175
// alias
176176
{"2.4", SimmVersion::V2_3_8},
177177
{"2.6", SimmVersion::V2_6},

0 commit comments

Comments
 (0)