Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
simmconfigurationbase.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/simmconfigurationbase.hpp
20 \brief Base SIMM configuration class
21*/
22
23#pragma once
24
29
30#include <ql/math/matrix.hpp>
31
32#include <map>
33
34namespace ore {
35namespace analytics {
36
38public:
39 typedef std::map<std::tuple<std::string, std::string, std::string>, QuantLib::Real> Amounts;
40
41 //! Returns the SIMM configuration name
42 const std::string& name() const override { return name_; }
43
44 //! Returns the SIMM configuration version
45 const std::string& version() const override { return version_; }
46
47 //! Returns the SIMM bucket mapper used by the configuration
48 const QuantLib::ext::shared_ptr<SimmBucketMapper>& bucketMapper() const override { return simmBucketMapper_; }
49
50 //! Return true if the SIMM risk type \p rt has buckets
51 bool hasBuckets(const CrifRecord::RiskType& rt) const override;
52
53 /*! Return the SIMM <em>bucket</em> name for the given risk type \p rt
54 and \p qualifier
55 */
56 std::string bucket(const CrifRecord::RiskType& rt, const std::string& qualifier) const override;
57
58 const bool checkValue(const std::string&, const std::vector<std::string>&) const;
59
60 //! Return the SIMM <em>bucket</em> names for the given risk type \p rt
61 //! An empty vector is returned if the risk type has no buckets
62 std::vector<std::string> buckets(const CrifRecord::RiskType& rt) const override;
63
64 //! Return the list of SIMM <em>Label1</em> values for risk type \p rt
65 //! An empty vector is returned if the risk type does not use <em>Label1</em>
66 std::vector<std::string> labels1(const CrifRecord::RiskType& rt) const override;
67
68 //! Return the list of SIMM <em>Label2</em> values for risk type \p rt
69 //! An empty vector is returned if the risk type does not use <em>Label2</em>
70 std::vector<std::string> labels2(const CrifRecord::RiskType& rt) const override;
71
72 //! Add SIMM <em>Label2</em> values under certain circumstances.
73 void addLabels2(const CrifRecord::RiskType& rt, const std::string& label_2) override {}
74
75 /*! Return the SIMM <em>risk weight</em> for the given risk type \p rt with
76 the given \p qualifier and the given \p label_1. Three possibilities:
77 -# there is a flat risk weight for the risk factor's RiskType so only need \p rt
78 -# there is a qualifier-dependent risk weight for the risk factor's RiskType
79 so need \p rt and \p qualifier
80 -# there is a qualifier-dependent and label1-dependent risk weight for the risk
81 factor's RiskType so need all three parameters
82 */
83 QuantLib::Real weight(const CrifRecord::RiskType& rt, boost::optional<std::string> qualifier = boost::none,
84 boost::optional<std::string> label_1 = boost::none,
85 const std::string& calculationCurrency = "") const override;
86
87 /*! Gives back the value of the scaling function used in the calculation of curvature risk
88 for the risk type \p rt with SIMM <em>Label1</em> value \p label_1. The scaling function is:
89 \f[
90 SF(t) = 0.5 \times \min \left(1, \frac{14}{t} \right)
91 \f]
92 where \f$t\f$ is given in days.
93
94 \warning An error is thrown if there is no curvature from the risk type \p rt
95 */
96 QuantLib::Real curvatureWeight(const CrifRecord::RiskType& rt, const std::string& label_1) const override;
97
98 /*! Give back the SIMM <em>historical volatility ratio</em> for the risk type \p rt
99
100 \remark 1.0 is returned if there is no historical volatility ratio for \p rt
101 */
102 QuantLib::Real historicalVolatilityRatio(const CrifRecord::RiskType& rt) const override;
103
104 /*! Give back the value of \f$\sigma_{kj}\f$ from the SIMM docs for risk type \p rt.
105 In general, \p rt is a volatility risk type and the method returns:
106 \f[
107 \sigma_{kj} = \frac{RW_k \sqrt{\frac{365}{14}}}{\Phi^{-1}(0.99)}
108 \f]
109 where \f$RW_k\f$ is the corresponding delta risk weight and \f$\Phi(z)\f$ is
110 the cumulative standard normal distribution.
111
112 \remark For convenience, returns 1.0 if not applicable for risk type \p rt
113 */
114 QuantLib::Real sigma(const CrifRecord::RiskType& rt, boost::optional<std::string> qualifier = boost::none,
115 boost::optional<std::string> label_1 = boost::none,
116 const std::string& calculationCurrency = "") const override;
117
118 /*! Give back the scaling factor for the Interest Rate curvature margin
119 */
120 QuantLib::Real curvatureMarginScaling() const override { return 2.3; }
121
122 /*! Give back the SIMM <em>concentration threshold</em> for the risk type \p rt and the
123 SIMM \p qualifier
124 */
125 QuantLib::Real concentrationThreshold(const CrifRecord::RiskType& rt, const std::string& qualifier) const override {
126 return simmConcentration_->threshold(rt, qualifier);
127 }
128
129 /*! Return true if \p rt is a valid SIMM <em>RiskType</em> under the current configuration.
130 Otherwise, return false.
131 */
132 bool isValidRiskType(const CrifRecord::RiskType& rt) const override { return validRiskTypes_.count(rt) > 0; }
133
134 //! Return the correlation between SIMM risk classes \p rc_1 and \p rc_2
135 QuantLib::Real correlationRiskClasses(const RiskClass& rc_1, const RiskClass& rc_2) const override;
136
137 /*! Return the correlation between the \p firstQualifier with risk type \p firstRt,
138 Label1 value of \p firstLabel_1 and Label2 value of \p firstLabel_2 *and* the
139 \p secondQualifier with risk type \p secondRt, Label1 value of \p secondLabel_1
140 and Label2 value of \p secondLabel_2
141
142 \remark if not using \p firstLabel_1 and \p secondLabel_1, just enter an empty
143 string for both. Similarly for \p firstLabel_2 and \p secondLabel_2.
144
145 \warning Returns 0 if no correlation found
146
147 \todo test if the default return value of 0 makes sense
148 */
149 QuantLib::Real correlation(const CrifRecord::RiskType& firstRt, const std::string& firstQualifier,
150 const std::string& firstLabel_1, const std::string& firstLabel_2,
151 const CrifRecord::RiskType& secondRt, const std::string& secondQualifier,
152 const std::string& secondLabel_1, const std::string& secondLabel_2,
153 const std::string& calculationCurrency = "") const override;
154
155 //! MPOR in days
156 QuantLib::Size mporDays() const { return mporDays_; }
157
158private:
159 //! Name of the SIMM configuration
160 std::string name_;
161 //! Calculate variable for use in sigma method
162 QuantLib::Real sigmaMultiplier() const;
163
164protected:
165 //! Constructor taking the SIMM configuration \p name and \p version
166 SimmConfigurationBase(const QuantLib::ext::shared_ptr<SimmBucketMapper>& simmBucketMapper, const std::string& name,
167 const std::string version, QuantLib::Size mporDays = 10);
168
169 //! SIMM configuration version
170 std::string version_;
171
172 //! Used to map SIMM <em>Qualifier</em> names to SIMM <em>bucket</em> values
173 QuantLib::ext::shared_ptr<SimmBucketMapper> simmBucketMapper_;
174
175 //! Used to get the concentration thresholds for a given risk type and qualifier
176 QuantLib::ext::shared_ptr<SimmConcentration> simmConcentration_;
177
178 const std::tuple<std::string, std::string, std::string> makeKey(const std::string&, const std::string&,
179 const std::string&) const;
180
181 //! Helper method to find the index of the \p label in \p labels
182 QuantLib::Size labelIndex(const std::string& label, const std::vector<std::string>& labels) const;
183
184 //! A base implementation of addLabels2 that can be shared by derived classes
185 void addLabels2Impl(const CrifRecord::RiskType& rt, const std::string& label_2);
186
187 /*! Map giving the SIMM <em>bucket</em> names for each risk type. If risk type is
188 not present in the map keys => there are no buckets for that risk type
189 */
190 std::map<CrifRecord::RiskType, std::vector<std::string>> mapBuckets_;
191
192 /*! Map giving the possible SIMM <em>Label1</em> values for each risk type. If
193 risk type is not present in the map keys then the <em>Label1</em> value is
194 not used for that risk type
195 */
196 std::map<CrifRecord::RiskType, std::vector<std::string>> mapLabels_1_;
197
198 /*! Map giving the possible SIMM <em>Label2</em> values for each risk type. If
199 risk type is not present in the map keys then the <em>Label2</em> value is
200 not used for that risk type
201 */
202 std::map<CrifRecord::RiskType, std::vector<std::string>> mapLabels_2_;
203
204 /*! Risk weights, there are three types:
205 -# risk type dependent only
206 -# risk type and bucket dependent
207 -# risk type, bucket and label1 dependent
208 */
209 std::map<CrifRecord::RiskType, QuantLib::Real> rwRiskType_;
210 std::map<CrifRecord::RiskType, Amounts> rwBucket_;
211 std::map<CrifRecord::RiskType, Amounts> rwLabel_1_;
212
213 /*! Map from risk type to a vector of curvature weights. The size of the vector of
214 weights for a given risk type must equal the size of the vector of Label1 values
215 for that risk type in the map <code>mapLabels_1_</code>
216 */
217 std::map<CrifRecord::RiskType, std::vector<QuantLib::Real>> curvatureWeights_;
218
219 //! Map from risk type to a historical volatility ratio.
220 std::map<CrifRecord::RiskType, QuantLib::Real> historicalVolatilityRatios_;
221
222 //! Set of valid risk types for the current configuration
223 std::set<CrifRecord::RiskType> validRiskTypes_;
224
225 //! Risk class correlation matrix
227
228 /*! Map from risk type to a matrix of inter-bucket correlations for that
229 risk type i.e. correlation between qualifiers of the risk type that fall
230 in different buckets
231 */
232 std::map<CrifRecord::RiskType, Amounts> interBucketCorrelation_;
233
234 /*! Map from risk type to an intra-bucket correlation for that
235 risk type i.e. correlation between qualifiers of the risk type that fall
236 in the same bucket
237 */
238 std::map<CrifRecord::RiskType, Amounts> intraBucketCorrelation_;
239
240 /*! @name Single Correlations
241 Single correlation numbers that don't fit in to a structure. They can be
242 populated in derived classes and are requested in the base implementation
243 of the correlation method.
244 */
245 //!@{
246 //! Correlation between xccy basis and any yield or inflation in same currency
247 QuantLib::Real xccyCorr_;
248 //! Correlation between any yield and inflation in same currency
249 QuantLib::Real infCorr_;
250 //! Correlation between any yield volatility and inflation volatility in same currency
251 QuantLib::Real infVolCorr_;
252 //! IR Label2 level i.e. sub-curve correlation
253 QuantLib::Real irSubCurveCorr_;
254 //! IR correlation across currencies
255 QuantLib::Real irInterCurrencyCorr_;
256 //! Credit-Q residual intra correlation
257 QuantLib::Real crqResidualIntraCorr_;
258 //! Credit-Q non-residual intra correlation when same qualifier but different vertex/source
259 QuantLib::Real crqSameIntraCorr_;
260 //! Credit-Q non-residual intra correlation when different qualifier
261 QuantLib::Real crqDiffIntraCorr_;
262 //! Credit-NonQ residual intra correlation
264 //! Credit-NonQ non-residual intra correlation when same underlying names
265 QuantLib::Real crnqSameIntraCorr_;
266 //! Credit-NonQ non-residual intra correlation when different underlying names
267 QuantLib::Real crnqDiffIntraCorr_;
268 //! Credit-NonQ non-residual inter bucket correlation
269 QuantLib::Real crnqInterCorr_;
270 //! FX correlation
271 QuantLib::Real fxCorr_;
272 //! Base correlation risk factor correlation
273 QuantLib::Real basecorrCorr_;
274 //!@}
275 //! Margin Period of risk in days
276 QuantLib::Size mporDays_;
277};
278
279} // namespace analytics
280} // namespace ore
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 override
const std::tuple< std::string, std::string, std::string > makeKey(const std::string &, const std::string &, const std::string &) const
QuantLib::Real crqResidualIntraCorr_
Credit-Q residual intra correlation.
QuantLib::Real basecorrCorr_
Base correlation risk factor correlation.
std::vector< std::string > buckets(const CrifRecord::RiskType &rt) const override
QuantLib::Real correlationRiskClasses(const RiskClass &rc_1, const RiskClass &rc_2) const override
Return the correlation between SIMM risk classes rc_1 and rc_2.
std::map< CrifRecord::RiskType, QuantLib::Real > rwRiskType_
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 override
QuantLib::Size labelIndex(const std::string &label, const std::vector< std::string > &labels) const
Helper method to find the index of the label in labels.
std::string name_
Name of the SIMM configuration.
std::map< std::tuple< std::string, std::string, std::string >, QuantLib::Real > Amounts
QuantLib::Real crnqResidualIntraCorr_
Credit-NonQ residual intra correlation.
std::string version_
SIMM configuration version.
bool hasBuckets(const CrifRecord::RiskType &rt) const override
Return true if the SIMM risk type rt has buckets.
QuantLib::Size mporDays() const
MPOR in days.
std::map< CrifRecord::RiskType, std::vector< std::string > > mapLabels_2_
bool isValidRiskType(const CrifRecord::RiskType &rt) const override
QuantLib::Real curvatureMarginScaling() const override
QuantLib::Real irInterCurrencyCorr_
IR correlation across currencies.
std::vector< std::string > labels2(const CrifRecord::RiskType &rt) const override
std::map< CrifRecord::RiskType, Amounts > rwLabel_1_
std::map< CrifRecord::RiskType, Amounts > intraBucketCorrelation_
std::map< CrifRecord::RiskType, std::vector< std::string > > mapBuckets_
QuantLib::Real crnqDiffIntraCorr_
Credit-NonQ non-residual intra correlation when different underlying names.
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 override
QuantLib::Real crqSameIntraCorr_
Credit-Q non-residual intra correlation when same qualifier but different vertex/source.
const std::string & name() const override
Returns the SIMM configuration name.
QuantLib::Real crnqSameIntraCorr_
Credit-NonQ non-residual intra correlation when same underlying names.
std::vector< std::string > labels1(const CrifRecord::RiskType &rt) const override
const bool checkValue(const std::string &, const std::vector< std::string > &) const
void addLabels2(const CrifRecord::RiskType &rt, const std::string &label_2) override
Add SIMM Label2 values under certain circumstances.
std::set< CrifRecord::RiskType > validRiskTypes_
Set of valid risk types for the current configuration.
QuantLib::ext::shared_ptr< SimmConcentration > simmConcentration_
Used to get the concentration thresholds for a given risk type and qualifier.
QuantLib::Real sigmaMultiplier() const
Calculate variable for use in sigma method.
QuantLib::Real curvatureWeight(const CrifRecord::RiskType &rt, const std::string &label_1) const override
const QuantLib::ext::shared_ptr< SimmBucketMapper > & bucketMapper() const override
Returns the SIMM bucket mapper used by the configuration.
QuantLib::Real infCorr_
Correlation between any yield and inflation in same currency.
Amounts riskClassCorrelation_
Risk class correlation matrix.
QuantLib::Real crnqInterCorr_
Credit-NonQ non-residual inter bucket correlation.
const std::string & version() const override
Returns the SIMM configuration version.
std::map< CrifRecord::RiskType, QuantLib::Real > historicalVolatilityRatios_
Map from risk type to a historical volatility ratio.
std::map< CrifRecord::RiskType, Amounts > interBucketCorrelation_
std::map< CrifRecord::RiskType, std::vector< std::string > > mapLabels_1_
QuantLib::Real infVolCorr_
Correlation between any yield volatility and inflation volatility in same currency.
QuantLib::Real crqDiffIntraCorr_
Credit-Q non-residual intra correlation when different qualifier.
QuantLib::Real irSubCurveCorr_
IR Label2 level i.e. sub-curve correlation.
QuantLib::Real historicalVolatilityRatio(const CrifRecord::RiskType &rt) const override
void addLabels2Impl(const CrifRecord::RiskType &rt, const std::string &label_2)
A base implementation of addLabels2 that can be shared by derived classes.
QuantLib::Real concentrationThreshold(const CrifRecord::RiskType &rt, const std::string &qualifier) const override
std::map< CrifRecord::RiskType, std::vector< QuantLib::Real > > curvatureWeights_
QuantLib::ext::shared_ptr< SimmBucketMapper > simmBucketMapper_
Used to map SIMM Qualifier names to SIMM bucket values.
std::string bucket(const CrifRecord::RiskType &rt, const std::string &qualifier) const override
std::map< CrifRecord::RiskType, Amounts > rwBucket_
Abstract base class defining the interface for a SIMM configuration.
Abstract base class for classes that map SIMM qualifiers to buckets.
SIMM class for defining SIMM risk weights, thresholds, buckets, and labels. Currently only supports t...
Abstract base class for retrieving SIMM concentration thresholds.
SIMM configuration interface.