Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
simmconfiguration.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 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/simmconfiguration.hpp
20 \brief SIMM configuration interface
21*/
22
23#pragma once
24
25#include <set>
26#include <string>
27#include <vector>
28
29#include <boost/optional.hpp>
32#include <ql/indexes/interestrateindex.hpp>
33#include <ql/types.hpp>
34
35namespace ore {
36namespace analytics {
37
38//! Abstract base class defining the interface for a SIMM configuration
40public:
41 virtual ~SimmConfiguration() {}
42
43 //! Enum indicating the relevant side of the SIMM calculation
44 enum class SimmSide { Call, Post };
45
46 /*! Risk class types in SIMM plus an All type for convenience
47
48 \warning The ordering here matters. It is used in indexing in to
49 correlation matrices for the correlation between risk classes.
50
51 \warning Internal methods rely on the last element being 'All'
52 */
54
55
56
57 //! Margin types in SIMM plus an All type for convenience
58 //! Internal methods rely on the last element being 'All'
60
61 enum class IMModel {
63 SIMM,
64 SIMM_R, // Equivalent to SIMM
65 SIMM_P // Equivalent to SIMM
66 };
67
68 //! SIMM regulators
92 };
93
94 //! Give back a set containing the RiskClass values optionally excluding 'All'
95 static std::set<RiskClass> riskClasses(bool includeAll = false);
96
97 //! Give back a set containing the RiskType values optionally excluding 'All'
98 static std::set<CrifRecord::RiskType> riskTypes(bool includeAll = false);
99
100 //! Give back a set containing the MarginType values optionally excluding 'All'
101 static std::set<MarginType> marginTypes(bool includeAll = false);
102
103 //! Give back a set containing the ProductClass values optionally excluding 'All'
104 static std::set<CrifRecord::ProductClass> productClasses(bool includeAll = false);
105
106 //! For a given risk class, return the corresponding risk types
107 static std::pair<CrifRecord::RiskType, CrifRecord::RiskType> riskClassToRiskType(const RiskClass& rc);
108
109 //! For a given rirsk type, return the corresponding risk class
111
112 //! Define ordering for ProductClass according to a waterfall:
113 // Empty < RatesFX < Equity < Commodity < Credit
114 // All is unhandled
115 // Would use operator< but there is a bug in the visual studio compiler.
116 static bool less_than(const CrifRecord::ProductClass& lhs, const CrifRecord::ProductClass& rhs);
117 static bool greater_than(const CrifRecord::ProductClass& lhs, const CrifRecord::ProductClass& rhs);
120
121 //! Return the "worse" ProductClass using a waterfall logic:
122 // RatesFX <
124 QL_REQUIRE(pc1 != CrifRecord::ProductClass::All && pc2 != CrifRecord::ProductClass::All,
125 "Cannot define worse product type if even one of the product classes is indeterminate.");
126 return (less_than(pc1, pc2) ? pc2 : pc1);
127 }
128
129 //! Return the SIMM <em>bucket</em> names for the given risk type \p rt
130 //! An empty vector is returned if the risk type has no buckets
131 virtual std::vector<std::string> buckets(const CrifRecord::RiskType& rt) const = 0;
132
133 //! Return true if the SIMM risk type \p rt has buckets
134 virtual bool hasBuckets(const CrifRecord::RiskType& rt) const = 0;
135
136 //! Return true if the SIMM risk type \p rt has buckets
137 bool hasBucketMapping(const CrifRecord::RiskType& rt, const std::string& qualifier) const override {
138 return bucketMapper()->has(rt, qualifier);
139 }
140
141
142 //! Return the list of SIMM <em>Label1</em> values for risk type \p rt
143 //! An empty vector is returned if the risk type does not use <em>Label1</em>
144 virtual std::vector<std::string> labels1(const CrifRecord::RiskType& rt) const = 0;
145
146 //! Return the list of SIMM <em>Label2</em> values for risk type \p rt
147 //! An empty vector is returned if the risk type does not use <em>Label2</em>
148 virtual std::vector<std::string> labels2(const CrifRecord::RiskType& rt) const = 0;
149
150 /*! Add SIMM <em>Label2</em> values under certain circumstances.
151
152 For example, in v338 and later, CreditQ label2 should have the payment
153 currency if sensitivty is not the result of a securitisation and
154 "payment currency,Sec" if sensitivty is the result of a securitisation.
155 Adding to label2 in the configuration means you do not have to have an
156 exhaustive list up front.
157 */
158 virtual void addLabels2(const CrifRecord::RiskType& rt, const std::string& label_2) = 0;
159
160 /*! Return the SIMM <em>risk weight</em> for the given risk type \p rt with
161 the given \p qualifier and the given \p label_1. Three possibilities:
162 -# there is a flat risk weight for the risk factor's RiskType so only need \p rt
163 -# there is a qualifier-dependent risk weight for the risk factor's RiskType
164 so need \p rt and \p qualifier
165 -# there is a qualifier-dependent and label1-dependent risk weight for the risk
166 factor's RiskType so need all three parameters
167 */
168 virtual QuantLib::Real weight(const CrifRecord::RiskType& rt, boost::optional<std::string> qualifier = boost::none,
169 boost::optional<std::string> label_1 = boost::none,
170 const std::string& calculationCurrency = "") const = 0;
171
172 /*! Gives back the value of the scaling function used in the calculation of curvature risk
173 for the risk type \p rt with SIMM <em>Label1</em> value \p label_1. The scaling function is:
174 \f[
175 SF(t) = 0.5 \times \min \left(1, \frac{14}{t} \right)
176 \f]
177 where \f$t\f$ is given in days.
178 */
179 virtual QuantLib::Real curvatureWeight(const CrifRecord::RiskType& rt, const std::string& label_1) const = 0;
180
181 /*! Give back the SIMM <em>historical volatility ratio</em> for the risk type \p rt
182 */
183 virtual QuantLib::Real historicalVolatilityRatio(const CrifRecord::RiskType& rt) const = 0;
184
185 /*! Give back the value of \f$\sigma_{kj}\f$ from the SIMM docs for risk type \p rt.
186 In general, \p rt is a volatility risk type and the method returns:
187 \f[
188 \sigma_{kj} = \frac{RW_k \sqrt{\frac{365}{14}}}{\Phi^{-1}(0.99)}
189 \f]
190 where \f$RW_k\f$ is the corresponding delta risk weight and \f$\Phi(z)\f$ is
191 the cumulative standard normal distribution.
192
193 \remark For convenience, returns 1.0 if not applicable for risk type \p rt
194 */
195 virtual QuantLib::Real sigma(const CrifRecord::RiskType& rt, boost::optional<std::string> qualifier = boost::none,
196 boost::optional<std::string> label_1 = boost::none,
197 const std::string& calculationCurrency = "") const = 0;
198
199 /*! Give back the scaling factor for the Interest Rate curvature margin
200 */
201 virtual QuantLib::Real curvatureMarginScaling() const = 0;
202
203 /*! Give back the SIMM <em>concentration threshold</em> for the risk type \p rt and the
204 SIMM \p qualifier
205 */
206 virtual QuantLib::Real concentrationThreshold(const CrifRecord::RiskType& rt, const std::string& qualifier) const = 0;
207
208 /*! Return true if \p rt is a valid SIMM <em>RiskType</em> under the current configuration.
209 Otherwise, return false.
210 */
211 virtual bool isValidRiskType(const CrifRecord::RiskType& rt) const = 0;
212
213 //! Return the correlation between SIMM risk classes \p rc_1 and \p rc_2
214 virtual QuantLib::Real correlationRiskClasses(const RiskClass& rc_1, const RiskClass& rc_2) const = 0;
215
216 /*! Return the correlation between the \p firstQualifier with risk type \p firstRt,
217 Label1 value of \p firstLabel_1 and Label2 value of \p firstLabel_2 *and* the
218 \p secondQualifier with risk type \p secondRt, Label1 value of \p secondLabel_1
219 and Label2 value of \p secondLabel_2
220
221 \warning Returns 0 if no correlation found
222
223 \todo test if the default return value of 0 makes sense
224 */
225 virtual QuantLib::Real correlation(const CrifRecord::RiskType& firstRt, const std::string& firstQualifier,
226 const std::string& firstLabel_1, const std::string& firstLabel_2,
227 const CrifRecord::RiskType& secondRt, const std::string& secondQualifier,
228 const std::string& secondLabel_1, const std::string& secondLabel_2,
229 const std::string& calculationCurrency = "") const = 0;
230
231 virtual bool isSimmConfigCalibration() const { return false; }
232
233protected:
234 //! Number of risk classes including RiskClass::All
235 static const QuantLib::Size numberOfRiskClasses;
236 //! Number of margin types including MarginType::All
237 static const QuantLib::Size numberOfMarginTypes;
238 //! Number of regulations
239 static const QuantLib::Size numberOfRegulations;
240};
241
242std::ostream& operator<<(std::ostream& out, const SimmConfiguration::SimmSide& side);
243
244std::ostream& operator<<(std::ostream& out, const SimmConfiguration::RiskClass& rc);
245
246std::ostream& operator<<(std::ostream& out, const SimmConfiguration::MarginType& mt);
247
248std::ostream& operator<<(std::ostream& out, const SimmConfiguration::IMModel& model);
249
250std::ostream& operator<<(std::ostream& out, const SimmConfiguration::Regulation& regulation);
251
252SimmConfiguration::SimmSide parseSimmSide(const std::string& side);
253
255
257
258SimmConfiguration::IMModel parseIMModel(const std::string& pc);
259
260SimmConfiguration::Regulation parseRegulation(const std::string& regulation);
261
262std::string combineRegulations(const std::string&, const std::string&);
263
264//! Reads a string containing regulations applicable for a given CRIF record
265std::set<std::string> parseRegulationString(const std::string& regsString,
266 const std::set<std::string>& valueIfEmpty = {"Unspecified"});
267
268//! Cleans a string defining regulations so that different permutations of the same set will
269//! be seen as the same string, e.g. "APRA,SEC,ESA" and "SEC,ESA,APRA" should be equivalent.
270std::string sortRegulationString(const std::string& regsString);
271
272//! Removes a given vector of regulations from a string of regulations and returns a string with the regulations removed
273std::string removeRegulations(const std::string& regsString, const std::vector<std::string>& regsToRemove);
274
275//! Filters a string of regulations on a given vector of regulations and returns a string containing only those filtered
276//! regulations
277std::string filterRegulations(const std::string& regsString, const std::vector<std::string>& regsToFilter);
278
279//! From a vector of regulations, determine the winning regulation based on order of priority
280SimmConfiguration::Regulation getWinningRegulation(const std::vector<std::string>& winningRegulations);
281
282} // namespace analytics
283} // namespace ore
virtual const QuantLib::ext::shared_ptr< SimmBucketMapper > & bucketMapper() const =0
Returns the SIMM bucket mapper used by the configuration.
Abstract base class defining the interface for a SIMM configuration.
virtual QuantLib::Real correlationRiskClasses(const RiskClass &rc_1, const RiskClass &rc_2) const =0
Return the correlation between SIMM risk classes rc_1 and rc_2.
static std::set< CrifRecord::RiskType > riskTypes(bool includeAll=false)
Give back a set containing the RiskType values optionally excluding 'All'.
static bool greater_than_or_equal_to(const CrifRecord::ProductClass &lhs, const CrifRecord::ProductClass &rhs)
static const QuantLib::Size numberOfRiskClasses
Number of risk classes including RiskClass::All.
static std::set< CrifRecord::ProductClass > productClasses(bool includeAll=false)
Give back a set containing the ProductClass values optionally excluding 'All'.
virtual bool isValidRiskType(const CrifRecord::RiskType &rt) const =0
virtual QuantLib::Real curvatureMarginScaling() const =0
static std::set< MarginType > marginTypes(bool includeAll=false)
Give back a set containing the MarginType values optionally excluding 'All'.
SimmSide
Enum indicating the relevant side of the SIMM calculation.
bool hasBucketMapping(const CrifRecord::RiskType &rt, const std::string &qualifier) const override
Return true if the SIMM risk type rt has buckets.
virtual bool isSimmConfigCalibration() const
static const QuantLib::Size numberOfMarginTypes
Number of margin types including MarginType::All.
static bool less_than(const CrifRecord::ProductClass &lhs, const CrifRecord::ProductClass &rhs)
Define ordering for ProductClass according to a waterfall:
virtual QuantLib::Real concentrationThreshold(const CrifRecord::RiskType &rt, const std::string &qualifier) const =0
static bool less_than_or_equal_to(const CrifRecord::ProductClass &lhs, const CrifRecord::ProductClass &rhs)
static std::set< RiskClass > riskClasses(bool includeAll=false)
Give back a set containing the RiskClass values optionally excluding 'All'.
virtual std::vector< std::string > labels2(const CrifRecord::RiskType &rt) const =0
virtual bool hasBuckets(const CrifRecord::RiskType &rt) const =0
Return true if the SIMM risk type rt has buckets.
static RiskClass riskTypeToRiskClass(const CrifRecord::RiskType &rt)
For a given rirsk type, return the corresponding risk class.
virtual QuantLib::Real curvatureWeight(const CrifRecord::RiskType &rt, const std::string &label_1) const =0
virtual QuantLib::Real sigma(const CrifRecord::RiskType &rt, boost::optional< std::string > qualifier=boost::none, boost::optional< std::string > label_1=boost::none, const std::string &calculationCurrency="") const =0
virtual std::vector< std::string > labels1(const CrifRecord::RiskType &rt) const =0
static const QuantLib::Size numberOfRegulations
Number of regulations.
virtual void addLabels2(const CrifRecord::RiskType &rt, const std::string &label_2)=0
virtual QuantLib::Real correlation(const CrifRecord::RiskType &firstRt, const std::string &firstQualifier, const std::string &firstLabel_1, const std::string &firstLabel_2, const CrifRecord::RiskType &secondRt, const std::string &secondQualifier, const std::string &secondLabel_1, const std::string &secondLabel_2, const std::string &calculationCurrency="") const =0
virtual QuantLib::Real weight(const CrifRecord::RiskType &rt, boost::optional< std::string > qualifier=boost::none, boost::optional< std::string > label_1=boost::none, const std::string &calculationCurrency="") const =0
static std::pair< CrifRecord::RiskType, CrifRecord::RiskType > riskClassToRiskType(const RiskClass &rc)
For a given risk class, return the corresponding risk types.
virtual QuantLib::Real historicalVolatilityRatio(const CrifRecord::RiskType &rt) const =0
static bool greater_than(const CrifRecord::ProductClass &lhs, const CrifRecord::ProductClass &rhs)
static CrifRecord::ProductClass maxProductClass(CrifRecord::ProductClass pc1, CrifRecord::ProductClass pc2)
Return the "worse" ProductClass using a waterfall logic:
virtual std::vector< std::string > buckets(const CrifRecord::RiskType &rt) const =0
CRIF configuration interface.
Struct for holding a CRIF record.
std::ostream & operator<<(std::ostream &out, EquityReturnType t)
string combineRegulations(const string &regs1, const string &regs2)
SimmConfiguration::Regulation parseRegulation(const string &regulation)
SimmConfiguration::SimmSide parseSimmSide(const string &side)
SimmConfiguration::Regulation getWinningRegulation(const std::vector< string > &winningRegulations)
From a vector of regulations, determine the winning regulation based on order of priority.
set< string > parseRegulationString(const string &regsString, const set< string > &valueIfEmpty)
Reads a string containing regulations applicable for a given CRIF record.
SimmConfiguration::IMModel parseIMModel(const string &model)
SimmConfiguration::RiskClass parseSimmRiskClass(const string &rc)
string filterRegulations(const string &regsString, const vector< string > &regsToFilter)
string removeRegulations(const string &regsString, const vector< string > &regsToRemove)
Removes a given vector of regulations from a string of regulations and returns a string with the regu...
SimmConfiguration::MarginType parseSimmMarginType(const string &mt)
string sortRegulationString(const string &regsString)