Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
simmcalculator.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2018 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19/*! \file orea/simm/simmcalculator.hpp
20 \brief Class for calculating SIMM
21*/
22
23#pragma once
24
25#include <orea/simm/crif.hpp>
29
30#include <map>
31
32namespace ore {
33namespace analytics {
34
35//! A class to calculate SIMM given a set of aggregated CRIF results for one or more portfolios.
37public:
39
40 /*! Construct the SimmCalculator from a container of netted CRIF
41 records and a SIMM configuration. The SIMM number is initially calculated in
42 USD using the AmountUSD column. It can optionally be converted to a calculation
43 currency other than USD by using the \p calculationCcy parameter. If the
44 \p calculationCcy is not USD then the \p usdSpot parameter must be used to
45 give the FX spot rate between USD and the \p calculationCcy. This spot rate is
46 interpreted as the number of USD per unit of \p calculationCcy.
47 */
49 const QuantLib::ext::shared_ptr<SimmConfiguration>& simmConfiguration,
50 const std::string& calculationCcyCall = "USD",
51 const std::string& calculationCcyPost = "USD",
52 const std::string& resultCcy = "",
53 const QuantLib::ext::shared_ptr<ore::data::Market> market = nullptr,
54 const bool determineWinningRegulations = true, const bool enforceIMRegulations = false,
55 const bool quiet = false,
56 const std::map<SimmSide, std::set<NettingSetDetails>>& hasSEC =
57 std::map<SimmSide, std::set<NettingSetDetails>>(),
58 const std::map<SimmSide, std::set<NettingSetDetails>>& hasCFTC =
59 std::map<SimmSide, std::set<NettingSetDetails>>());
60
61 //! Calculates SIMM for a given regulation under a given netting set
63 const string& regulation, const SimmSide& side);
64
65 //! Return the winning regulation for each netting set
66 const std::string& winningRegulations(const SimmSide& side,
67 const ore::data::NettingSetDetails& nettingSetDetails) const;
68 const std::map<ore::data::NettingSetDetails, string>& winningRegulations(const SimmSide& side) const;
69 const std::map<SimmSide, std::map<ore::data::NettingSetDetails, string>>& winningRegulations() const;
70
71 //! Give back the SIMM results container for the given portfolioId and SIMM side
72 const SimmResults& simmResults(const SimmSide& side, const ore::data::NettingSetDetails& nettingSetDetails,
73 const std::string& regulation) const;
74 const std::map<std::string, SimmResults>& simmResults(const SimmSide& side, const ore::data::NettingSetDetails& nettingSetDetails) const;
75
76 /*! Give back a map containing the SIMM results containers for every portfolio for the
77 given SIMM \p side. The key is the portfolio ID and the value is the SIMM results
78 container for that portfolio.
79 */
80 const std::map<ore::data::NettingSetDetails, std::map<std::string, SimmResults>>& simmResults(const SimmSide& side) const;
81 const std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::map<std::string, SimmResults>>>& simmResults() const;
82
83 //! Give back the SIMM results container for the given netting set and SIMM side
84 const std::pair<std::string, SimmResults>& finalSimmResults(const SimmSide& side, const ore::data::NettingSetDetails& nettingSetDetails) const;
85
86 /*! Give back a map containing the SIMM results containers for every portfolio for the given
87 SIMM \p side. The key is the portfolio ID and the value is a map, with regulation as the
88 key, and the value is the SIMM results container for that portfolioId-regulation combination.
89 */
90 const std::map<ore::data::NettingSetDetails, std::pair<std::string, SimmResults>>& finalSimmResults(const SimmSide& side) const;
91 const std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::pair<std::string, SimmResults>>>& finalSimmResults() const;
92
93 const std::map<SimmSide, std::set<std::string>>& finalTradeIds() const { return finalTradeIds_; }
94
95 const Crif& simmParameters() const { return simmParameters_; }
96
97 //! Return the calculator's calculation currency
98 const std::string& calculationCurrency(const SimmSide& side) const {
99 return side == SimmSide::Call ? calculationCcyCall_ : calculationCcyPost_;
100 }
101
102 //! Return the calculator's result currency
103 const std::string& resultCurrency() const { return resultCcy_; }
104
105 /*! Populate the finalSimmResults_ and finalAddMargins_ containers
106 using the provided map of winning call/post regulations.
107 */
108 void populateFinalResults(const std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::string>>& winningRegulations);
109
110private:
111 //! All the net sensitivities passed in for the calculation
113
114 //! Net sentivities at the regulation level within each netting set
115 std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::map<std::string, Crif>>> regSensitivities_;
116
117 //! Record of SIMM parameters that were used in the calculation
119
120 //! The SIMM configuration governing the calculation
121 QuantLib::ext::shared_ptr<SimmConfiguration> simmConfiguration_;
122
123 //! The SIMM exposure calculation currency i.e. the currency for which FX delta risk is ignored
125
126 //! The SIMM result currency i.e. the currency in which the main SIMM results are denominated
127 std::string resultCcy_;
128
129 //! Market data for FX rates to use for converting amounts to USD
130 QuantLib::ext::shared_ptr<ore::data::Market> market_;
131
132 //! If true, no logging is written out
133 bool quiet_;
134
135 std::map<SimmSide, std::set<NettingSetDetails>> hasSEC_, hasCFTC_;
136
137 //! For each netting set, whether all CRIF records' collect regulations are empty
138 std::map<ore::data::NettingSetDetails, bool> collectRegsIsEmpty_;
139
140 //! For each netting set, whether all CRIF records' post regulations are empty
141 std::map<ore::data::NettingSetDetails, bool> postRegsIsEmpty_;
142
143 //! Regulation with highest initial margin for each given netting set
144 // side, netting set details, regulation
145 std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::string>> winningRegulations_;
146
147 /*! Containers, one for call and post, with a map containing a SimmResults object
148 for each regulation under each portfolio ID
149 */
150 // side, netting set details, regulation
151 std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::map<std::string, SimmResults>>> simmResults_;
152
153 /*! Containers, one for call and post, with a SimmResults object for each portfolio ID,
154 and each margin amount is that of the winning regulation applicable to the portfolio ID
155 */
156 // side, netting set details, regulation
157 std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::pair<std::string, SimmResults>>> finalSimmResults_;
158
159 //! Container for keeping track of what trade IDs belong to each regulation
160 // side, netting set details, regulation
161 std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::map<std::string, set<string>>>> tradeIds_;
162
163 std::map<SimmSide, set<string>> finalTradeIds_;
164
165 //! Calculate the Interest Rate delta margin component for the given portfolio and product class
166 std::pair<std::map<std::string, QuantLib::Real>, bool>
167 irDeltaMargin(const ore::data::NettingSetDetails& nettingSetDetails, const CrifRecord::ProductClass& pc,
168 const ore::analytics::Crif& netRecords, const SimmSide& side) const;
169
170 //! Calculate the Interest Rate vega margin component for the given portfolio and product class
171 std::pair<std::map<std::string, QuantLib::Real>, bool>
172 irVegaMargin(const ore::data::NettingSetDetails& nettingSetDetails, const CrifRecord::ProductClass& pc,
173 const ore::analytics::Crif& netRecords, const SimmSide& side) const;
174
175 //! Calculate the Interest Rate curvature margin component for the given portfolio and product class
176 std::pair<std::map<std::string, QuantLib::Real>, bool>
178 const SimmSide& side, const ore::analytics::Crif& crif) const;
179
180 /*! Calculate the (delta or vega) margin component for the given portfolio, product class and risk type
181 Used to calculate delta or vega or base correlation margin for all risk types except IR, IRVol
182 (and by association, Inflation, XccyBasis and InflationVol)
183 */
184 std::pair<std::map<std::string, QuantLib::Real>, bool> margin(const ore::data::NettingSetDetails& nettingSetDetails,
185 const CrifRecord::ProductClass& pc,
186 const CrifRecord::RiskType& rt,
187 const ore::analytics::Crif& netRecords,
188 const SimmSide& side) const;
189
190 /*! Calculate the curvature margin component for the given portfolio, product class and risk type
191 Used to calculate curvature margin for all risk types except IR
192 */
193 std::pair<std::map<std::string, QuantLib::Real>, bool>
195 const CrifRecord::RiskType& rt, const SimmSide& side, const ore::analytics::Crif& netRecords,
196 bool rfLabels = true) const;
197
198 //! Calculate the additional initial margin for the portfolio ID and regulation
199 void calcAddMargin(const SimmSide& side, const ore::data::NettingSetDetails& nsd, const string& regulation, const ore::analytics::Crif& netRecords);
200
201 /*! Populate the results structure with the higher level results after the IMs have been
202 calculated at the (product class, risk class, margin type) level for the given
203 regulation under the given portfolio
204 */
205 void populateResults(const SimmSide& side, const ore::data::NettingSetDetails& nsd, const string& regulation);
206
207 /*! Populate final (i.e. winning regulators') using own list of winning regulators, which were determined
208 solely by the SIMM results (i.e. not including any external IMSchedule results)
209 */
211
212 /*! Add a margin result to either call or post results container depending on the
213 \p side parameter.
214
215 \remark all additions to the results containers should happen in this method
216 */
217 void add(const ore::data::NettingSetDetails& nettingSetDetails, const string& regulation,
219 const SimmConfiguration::MarginType& mt, const std::string& b, QuantLib::Real margin, SimmSide side,
220 const bool overwrite = true);
221
222 void add(const ore::data::NettingSetDetails& nettingSetDetails, const string& regulation,
224 const SimmConfiguration::MarginType& mt, const std::map<std::string, QuantLib::Real>& margins, SimmSide side,
225 const bool overwrite = true);
226
227 //! Add CRIF record to the CRIF records container that correspondsd to the given regulation/s and portfolio ID
228 void splitCrifByRegulationsAndPortfolios(const Crif& crif, const bool enforceIMRegulations);
229
230 //! Give the \f$\lambda\f$ used in the curvature margin calculation
231 QuantLib::Real lambda(QuantLib::Real theta) const;
232
233 std::set<std::string> getQualifiers(const Crif& crif, const ore::data::NettingSetDetails& nettingSetDetails,
234 const CrifRecord::ProductClass& pc,
235 const std::vector<CrifRecord::RiskType>& riskTypes) const;
236
237};
238
239} // namespace analytics
240} // namespace ore
A class to calculate SIMM given a set of aggregated CRIF results for one or more portfolios.
const std::map< SimmSide, std::map< ore::data::NettingSetDetails, std::map< std::string, SimmResults > > > & simmResults() const
const Crif & simmParameters() const
std::pair< std::map< std::string, QuantLib::Real >, bool > margin(const ore::data::NettingSetDetails &nettingSetDetails, const CrifRecord::ProductClass &pc, const CrifRecord::RiskType &rt, const ore::analytics::Crif &netRecords, const SimmSide &side) const
std::set< std::string > getQualifiers(const Crif &crif, const ore::data::NettingSetDetails &nettingSetDetails, const CrifRecord::ProductClass &pc, const std::vector< CrifRecord::RiskType > &riskTypes) const
void add(const ore::data::NettingSetDetails &nettingSetDetails, const string &regulation, const CrifRecord::ProductClass &pc, const SimmConfiguration::RiskClass &rc, const SimmConfiguration::MarginType &mt, const std::map< std::string, QuantLib::Real > &margins, SimmSide side, const bool overwrite=true)
std::map< SimmSide, std::set< NettingSetDetails > > hasCFTC_
std::map< SimmSide, std::set< NettingSetDetails > > hasSEC_
std::pair< std::map< std::string, QuantLib::Real >, bool > irDeltaMargin(const ore::data::NettingSetDetails &nettingSetDetails, const CrifRecord::ProductClass &pc, const ore::analytics::Crif &netRecords, const SimmSide &side) const
Calculate the Interest Rate delta margin component for the given portfolio and product class.
std::string calculationCcyCall_
The SIMM exposure calculation currency i.e. the currency for which FX delta risk is ignored.
QuantLib::Real lambda(QuantLib::Real theta) const
Give the used in the curvature margin calculation.
std::pair< std::map< std::string, QuantLib::Real >, bool > irVegaMargin(const ore::data::NettingSetDetails &nettingSetDetails, const CrifRecord::ProductClass &pc, const ore::analytics::Crif &netRecords, const SimmSide &side) const
Calculate the Interest Rate vega margin component for the given portfolio and product class.
void calcAddMargin(const SimmSide &side, const ore::data::NettingSetDetails &nsd, const string &regulation, const ore::analytics::Crif &netRecords)
Calculate the additional initial margin for the portfolio ID and regulation.
std::map< SimmSide, std::map< ore::data::NettingSetDetails, std::string > > winningRegulations_
Regulation with highest initial margin for each given netting set.
std::pair< std::map< std::string, QuantLib::Real >, bool > irCurvatureMargin(const ore::data::NettingSetDetails &nettingSetDetails, const CrifRecord::ProductClass &pc, const SimmSide &side, const ore::analytics::Crif &crif) const
Calculate the Interest Rate curvature margin component for the given portfolio and product class.
std::map< ore::data::NettingSetDetails, bool > collectRegsIsEmpty_
For each netting set, whether all CRIF records' collect regulations are empty.
std::map< SimmSide, std::map< ore::data::NettingSetDetails, std::map< std::string, SimmResults > > > simmResults_
std::map< ore::data::NettingSetDetails, bool > postRegsIsEmpty_
For each netting set, whether all CRIF records' post regulations are empty.
const std::map< SimmSide, std::map< ore::data::NettingSetDetails, string > > & winningRegulations() const
QuantLib::ext::shared_ptr< SimmConfiguration > simmConfiguration_
The SIMM configuration governing the calculation.
ore::analytics::Crif simmParameters_
Record of SIMM parameters that were used in the calculation.
std::pair< std::map< std::string, QuantLib::Real >, bool > curvatureMargin(const ore::data::NettingSetDetails &nettingSetDetails, const CrifRecord::ProductClass &pc, const CrifRecord::RiskType &rt, const SimmSide &side, const ore::analytics::Crif &netRecords, bool rfLabels=true) const
const std::map< SimmSide, std::map< ore::data::NettingSetDetails, std::pair< std::string, SimmResults > > > & finalSimmResults() const
const std::string & resultCurrency() const
Return the calculator's result currency.
QuantLib::ext::shared_ptr< ore::data::Market > market_
Market data for FX rates to use for converting amounts to USD.
bool quiet_
If true, no logging is written out.
std::map< SimmSide, std::map< ore::data::NettingSetDetails, std::pair< std::string, SimmResults > > > finalSimmResults_
void populateFinalResults(const std::map< SimmSide, std::map< ore::data::NettingSetDetails, std::string > > &winningRegulations)
std::map< SimmSide, std::map< ore::data::NettingSetDetails, std::map< std::string, Crif > > > regSensitivities_
Net sentivities at the regulation level within each netting set.
void add(const ore::data::NettingSetDetails &nettingSetDetails, const string &regulation, const CrifRecord::ProductClass &pc, const SimmConfiguration::RiskClass &rc, const SimmConfiguration::MarginType &mt, const std::string &b, QuantLib::Real margin, SimmSide side, const bool overwrite=true)
ore::analytics::Crif crif_
All the net sensitivities passed in for the calculation.
void populateResults(const SimmSide &side, const ore::data::NettingSetDetails &nsd, const string &regulation)
const std::string & calculationCurrency(const SimmSide &side) const
Return the calculator's calculation currency.
std::map< SimmSide, set< string > > finalTradeIds_
void splitCrifByRegulationsAndPortfolios(const Crif &crif, const bool enforceIMRegulations)
Add CRIF record to the CRIF records container that correspondsd to the given regulation/s and portfol...
std::map< SimmSide, std::map< ore::data::NettingSetDetails, std::map< std::string, set< string > > > > tradeIds_
Container for keeping track of what trade IDs belong to each regulation.
const std::map< SimmSide, std::set< std::string > > & finalTradeIds() const
std::string resultCcy_
The SIMM result currency i.e. the currency in which the main SIMM results are denominated.
const void calculateRegulationSimm(const ore::analytics::Crif &crif, const ore::data::NettingSetDetails &nsd, const string &regulation, const SimmSide &side)
Calculates SIMM for a given regulation under a given netting set.
SimmConfiguration::SimmSide SimmSide
SimmSide
Enum indicating the relevant side of the SIMM calculation.
Struct for holding CRIF records.
Class for loading CRIF records.
Class for holding SIMM results.