Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
imschedulecalculator.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2022 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/imschedulecalculator.hpp
20 \brief Class for calculating SIMM
21*/
22
23#pragma once
24
28
29namespace ore {
30namespace analytics {
31
32/*! A class to calculate Schedule IM given a set of aggregated CRIF results
33 for one or more portfolios.
34*/
36
37public:
42
43 // Container to hold trade-level data (and results)
45 // IM Schedule trades are expected in the CRIF record as two rows, with RiskType::Notional and RiskType::PV
47 const CrifRecord::ProductClass& pc, const QuantLib::Real& amount,
48 const std::string& amountCcy, const QuantLib::Real& amountUsd,
49 const QuantLib::Date& endDate, const std::string& calculationCcy,
50 const std::string& collectRegulations, const std::string& postRegulations)
53
54 if (rt == RiskType::PV) {
55 presentValue = amount;
56 presentValueUsd = amountUsd;
57 presentValueCcy = amountCcy;
58 } else {
59 notional = amount;
60 notionalUsd = amountUsd;
61 notionalCcy = amountCcy;
62 }
63 }
64
66 return presentValueCcy.empty()
67 || presentValue == QuantLib::Null<QuantLib::Real>()
68 || presentValueUsd == QuantLib::Null<QuantLib::Real>();
69 }
70
72 return notionalCcy.empty()
73 || notional == QuantLib::Null<QuantLib::Real>()
74 || notionalUsd == QuantLib::Null<QuantLib::Real>();
75 }
76
77 bool incomplete() {
79 }
80
81 std::string tradeId;
84 QuantLib::Real notional = QuantLib::Null<QuantLib::Real>();
85 std::string notionalCcy;
86 QuantLib::Real notionalUsd = QuantLib::Null<QuantLib::Real>();
87 QuantLib::Real notionalCalc = QuantLib::Null<QuantLib::Real>();
88 QuantLib::Real presentValue = QuantLib::Null<QuantLib::Real>();
89 std::string presentValueCcy;
90 QuantLib::Real presentValueUsd = QuantLib::Null<QuantLib::Real>();
91 QuantLib::Real presentValueCalc = QuantLib::Null<QuantLib::Real>();
92 QuantLib::Date endDate;
93 QuantLib::Real maturity;
94
96 std::string labelString;
97 QuantLib::Real multiplier;
98 QuantLib::Real grossMarginUsd;
99 QuantLib::Real grossMarginCalc;
100 std::string calculationCcy;
102 std::string postRegulations;
103
107 };
108
109 //! Construct the IMScheduleCalculator from a container of netted CRIF records.
110 IMScheduleCalculator(const Crif& crif, const std::string& calculationCcy = "USD",
111 const QuantLib::ext::shared_ptr<ore::data::Market> market = nullptr,
112 const bool determineWinningRegulations = true, const bool enforceIMRegulations = false,
113 const bool quiet = false,
114 const std::map<SimmSide, std::set<NettingSetDetails>>& hasSEC =
115 std::map<SimmSide, std::set<NettingSetDetails>>(),
116 const std::map<SimmSide, std::set<NettingSetDetails>>& hasCFTC =
117 std::map<SimmSide, std::set<NettingSetDetails>>());
118
119 //! Give back the set of portfolio IDs and trade IDs for which we have IM results
120 //const std::set<std::string>& tradeIds() const { return tradeIds_; }
121 const std::map<SimmSide, std::set<std::string>> finalTradeIds() const { return finalTradeIds_; }
122
123
124 //! Return the winning regulation for each portfolioId
125 const std::string& winningRegulations(const SimmSide& side,
126 const ore::data::NettingSetDetails& nettingSetDetails) const;
127 const std::map<ore::data::NettingSetDetails, string>& winningRegulations(const SimmSide& side) const;
128 const std::map<SimmSide, std::map<ore::data::NettingSetDetails, string>>& winningRegulations() const;
129
130 //! Give back the IM Schedule results container for the given portfolioId and IM side
131 const std::map<std::string, IMScheduleResults>& imScheduleSummaryResults(const SimmSide& side, const ore::data::NettingSetDetails& nsd) const;
132 const std::map<ore::data::NettingSetDetails, std::map<std::string, IMScheduleResults>>& imScheduleSummaryResults(const SimmSide& side) const;
133 const std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::map<std::string, IMScheduleResults>>>& imScheduleSummaryResults() const;
134
135 const std::pair<std::string, IMScheduleResults>& finalImScheduleSummaryResults(const SimmSide& side, const ore::data::NettingSetDetails& nsd) const;
136 const std::map<ore::data::NettingSetDetails, std::pair<std::string, IMScheduleResults>>& finalImScheduleSummaryResults(const SimmSide& side) const;
137 const std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::pair<std::string, IMScheduleResults>>>&
140 };
141
142 //! Give back the IM Schedule results container for the given tradeId and IM side
143 const std::vector<IMScheduleTradeData>& imScheduleTradeResults(const std::string& tradeId) const;
144 const std::map<std::string, std::vector<IMScheduleTradeData>>& imScheduleTradeResults() const;
145
146 const IMScheduleTradeData& finalImScheduleTradeResults(const std::string& tradeId) const;
147 const std::map<std::string, IMScheduleTradeData>& finalImScheduleTradeResults() const;
148
149 //! Return the calculator's calculation currency
150 const std::string& calculationCurrency() const { return calculationCcy_; }
151
152 static const IMScheduleLabel label(const ProductClass& productClass, const QuantLib::Real& maturity);
153 static const std::string labelString(const IMScheduleLabel& label);
154
155 // Populate the finalImScheduleResults_ container using the provided map of winning call/post regulations
156 void populateFinalResults(const std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::string>>& winningRegulations);
157
158private:
159 //! The net sensitivities used in the calculation
161
162 //! The SIMM calculation currency i.e. the currency of the SIMM results
163 std::string calculationCcy_;
164
165 //! Market data for FX rates to use for converting amounts to USD
166 QuantLib::ext::shared_ptr<ore::data::Market> market_;
167
168 //! If true, no logging is written out
169 bool quiet_;
170
171 std::map<SimmSide, std::set<NettingSetDetails>> hasSEC_, hasCFTC_;
172
173 //! For each netting set, whether all CRIF records' collect regulations are empty
174 std::map<ore::data::NettingSetDetails, bool> collectRegsIsEmpty_;
175
176 //! For each netting set, whether all CRIF records' post regulations are empty
177 std::map<ore::data::NettingSetDetails, bool> postRegsIsEmpty_;
178
179 //! Containers, one for call and post, with an IMScheduleResults object for each regulation under each portfolio ID
180 // side, netting set details, regulation
181 std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::map<std::string, IMScheduleResults>>> imScheduleResults_;
182
183 //! Containers, one for call and post, with an IMScheduleResults object for each portfolio ID
184 // side, netting set details, regulation
185 std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::pair<std::string, IMScheduleResults>>> finalImScheduleResults_;
186
187 //! Container for keeping track of what trade IDs belong to each regulation
188 // side, netting set details, regulation
189 std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::map<std::string, set<string>>>> tradeIds_;
190
191 std::map<SimmSide, set<string>> finalTradeIds_;
192
193 //! Regulation with highest IM for each given netting set
194 // side, netting set details, regulation
195 std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::string>> winningRegulations_;
196
197 //! Container for trade data collected from CRIF report
198 //! trade ID trade data
199 std::map<std::string, std::vector<IMScheduleTradeData>> finalTradeData_;
200
201 //! Container for trade data, taking into account regulations applicable to each netting set
202 // side, netting set details, regulation, trade ID
203 std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::map<std::string, std::map<std::string, IMScheduleTradeData>>>> nettingSetRegTradeData_;
204
205 std::map<IMScheduleLabel, QuantLib::Real> multiplierMap_ = std::map<IMScheduleLabel, QuantLib::Real>({
206 // clang-format off
212 {IMScheduleLabel::FX, 0.06},
217 // clang-format on
218 });
219
220 QuantLib::Real multiplier(const IMScheduleLabel& label) { return multiplierMap_[label]; }
221
222 //! Collect trade data as defined by the CRIF records
223 void collectTradeData(const CrifRecord& cr, const bool enforceIMRegulations);
224
225 /*! Populate the results structure with the higher level results after the IMs have been
226 calculated at the (product class, maturity) level for each portfolio
227 */
228 void populateResults(const ore::data::NettingSetDetails& nsd, const string& regulation, const SimmSide& side);
229
230 /*! Populate final (i.e. winning regulators') using own list of winning regulators, which were determined
231 solely by the IMSchedule results (i.e. not including any external SIMM results)
232 */
234
235 //! Add a margin result to either call or post results container depending on the SimmSide parameter
236 void add(const SimmSide& side, const ore::data::NettingSetDetails& nsd, const std::string& regulation,
237 const CrifRecord::ProductClass& pc, const std::string& ccy, const QuantLib::Real& grossIM,
238 const QuantLib::Real& grossRC = QuantLib::Null<QuantLib::Real>(),
239 const QuantLib::Real& netRC = QuantLib::Null<QuantLib::Real>(),
240 const QuantLib::Real& ngr = QuantLib::Null<QuantLib::Real>(),
241 const QuantLib::Real& scheduleIM = QuantLib::Null<QuantLib::Real>());
242
243};
244
245} // namespace analytics
246} // namespace ore
std::map< SimmSide, std::map< ore::data::NettingSetDetails, std::map< std::string, IMScheduleResults > > > imScheduleResults_
Containers, one for call and post, with an IMScheduleResults object for each regulation under each po...
const std::map< SimmSide, std::set< std::string > > finalTradeIds() const
Give back the set of portfolio IDs and trade IDs for which we have IM results.
const std::map< SimmSide, std::map< ore::data::NettingSetDetails, std::map< std::string, IMScheduleResults > > > & imScheduleSummaryResults() const
const IMScheduleTradeData & finalImScheduleTradeResults(const std::string &tradeId) const
const std::map< std::string, std::vector< IMScheduleTradeData > > & imScheduleTradeResults() const
std::map< SimmSide, std::set< NettingSetDetails > > hasCFTC_
std::map< SimmSide, std::set< NettingSetDetails > > hasSEC_
std::map< SimmSide, std::map< ore::data::NettingSetDetails, std::string > > winningRegulations_
Regulation with highest IM for each given netting set.
std::map< ore::data::NettingSetDetails, bool > collectRegsIsEmpty_
For each netting set, whether all CRIF records' collect regulations are empty.
const std::map< SimmSide, std::map< ore::data::NettingSetDetails, string > > & winningRegulations() const
std::map< SimmSide, std::map< ore::data::NettingSetDetails, std::pair< std::string, IMScheduleResults > > > finalImScheduleResults_
Containers, one for call and post, with an IMScheduleResults object for each portfolio ID.
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, std::pair< std::string, IMScheduleResults > > > & finalImScheduleSummaryResults() const
SimmConfiguration::Regulation Regulation
static const IMScheduleLabel label(const ProductClass &productClass, const QuantLib::Real &maturity)
std::map< SimmSide, std::map< ore::data::NettingSetDetails, std::map< std::string, std::map< std::string, IMScheduleTradeData > > > > nettingSetRegTradeData_
Container for trade data, taking into account regulations applicable to each netting set.
QuantLib::ext::shared_ptr< ore::data::Market > market_
Market data for FX rates to use for converting amounts to USD.
const std::string & calculationCurrency() const
Return the calculator's calculation currency.
bool quiet_
If true, no logging is written out.
std::map< std::string, std::vector< IMScheduleTradeData > > finalTradeData_
static const std::string labelString(const IMScheduleLabel &label)
void populateFinalResults(const std::map< SimmSide, std::map< ore::data::NettingSetDetails, std::string > > &winningRegulations)
std::string calculationCcy_
The SIMM calculation currency i.e. the currency of the SIMM results.
ore::analytics::Crif crif_
The net sensitivities used in the calculation.
std::map< SimmSide, set< string > > finalTradeIds_
void collectTradeData(const CrifRecord &cr, const bool enforceIMRegulations)
Collect trade data as defined by the CRIF records.
void add(const SimmSide &side, const ore::data::NettingSetDetails &nsd, const std::string &regulation, const CrifRecord::ProductClass &pc, const std::string &ccy, const QuantLib::Real &grossIM, const QuantLib::Real &grossRC=QuantLib::Null< QuantLib::Real >(), const QuantLib::Real &netRC=QuantLib::Null< QuantLib::Real >(), const QuantLib::Real &ngr=QuantLib::Null< QuantLib::Real >(), const QuantLib::Real &scheduleIM=QuantLib::Null< QuantLib::Real >())
Add a margin result to either call or post results container depending on the SimmSide parameter.
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.
QuantLib::Real multiplier(const IMScheduleLabel &label)
void populateResults(const ore::data::NettingSetDetails &nsd, const string &regulation, const SimmSide &side)
const std::map< std::string, IMScheduleTradeData > & finalImScheduleTradeResults() const
std::map< IMScheduleLabel, QuantLib::Real > multiplierMap_
SimmSide
Enum indicating the relevant side of the SIMM calculation.
Struct for holding a CRIF record.
Class for holding IMSchedule results.
data
IMScheduleTradeData(const std::string &tradeId, const ore::data::NettingSetDetails &nettingSetDetails, const RiskType &rt, const CrifRecord::ProductClass &pc, const QuantLib::Real &amount, const std::string &amountCcy, const QuantLib::Real &amountUsd, const QuantLib::Date &endDate, const std::string &calculationCcy, const std::string &collectRegulations, const std::string &postRegulations)