/src/quantlib/ql/experimental/credit/defaultlossmodel.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | |
3 | | /* |
4 | | Copyright (C) 2008 Roland Lichters |
5 | | Copyright (C) 2014 Jose Aparicio |
6 | | |
7 | | This file is part of QuantLib, a free-software/open-source library |
8 | | for financial quantitative analysts and developers - http://quantlib.org/ |
9 | | |
10 | | QuantLib is free software: you can redistribute it and/or modify it |
11 | | under the terms of the QuantLib license. You should have received a |
12 | | copy of the license along with this program; if not, please email |
13 | | <quantlib-dev@lists.sf.net>. The license is also available online at |
14 | | <http://quantlib.org/license.shtml>. |
15 | | |
16 | | This program is distributed in the hope that it will be useful, but WITHOUT |
17 | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
18 | | FOR A PARTICULAR PURPOSE. See the license for more details. |
19 | | */ |
20 | | |
21 | | #ifndef quantlib_defaultlossmodel_hpp |
22 | | #define quantlib_defaultlossmodel_hpp |
23 | | |
24 | | #include <ql/instruments/claim.hpp> |
25 | | #include <ql/experimental/credit/defaultprobabilitykey.hpp> |
26 | | #include <ql/experimental/credit/basket.hpp> |
27 | | |
28 | | #include <ql/utilities/null_deleter.hpp> |
29 | | |
30 | | /* Intended to replace LossDistribution in |
31 | | ql/experimental/credit/lossdistribution, not sure its covering all the |
32 | | functionality (see mthod below) |
33 | | */ |
34 | | |
35 | | namespace QuantLib { |
36 | | |
37 | | /*! Default loss model interface definition. |
38 | | Allows communication between the basket and specific algorithms. Intended to |
39 | | hold any kind of portfolio joint loss, latent models, top-down,.... |
40 | | |
41 | | An inconvenience of this design as opposed to the full arguments/results |
42 | | is that when pricing several derivatives instruments on the same basket |
43 | | not all the pricing engines would point to the same loss model; thus when |
44 | | pricing a set of such instruments there might be some switching on the |
45 | | basket loss models, which might require recalculations (of the basket) or |
46 | | not depending on the pricing order. |
47 | | */ |
48 | | class DefaultLossModel : public Observable {// joint-? basket?-defaultLoss |
49 | | /* Protection together with frienship to avoid the need of checking the |
50 | | basket-argument pointer integrity. It is the responsibility of the basket |
51 | | now; our only caller. |
52 | | */ |
53 | | friend class Basket; |
54 | | protected: |
55 | | // argument basket: |
56 | | mutable RelinkableHandle<Basket> basket_; |
57 | | |
58 | 0 | DefaultLossModel() = default; |
59 | | //! \name Statistics |
60 | | //@{ |
61 | | /* Non mandatory implementations, fails if client is not providing what |
62 | | requested. */ |
63 | | |
64 | | /* Default implementation using the expectedLoss(Date) method. |
65 | | Typically this method is called repeatedly with the same |
66 | | date parameter which makes it innefficient. */ |
67 | 0 | virtual Real expectedTrancheLoss(const Date& d) const { |
68 | 0 | QL_FAIL("expectedTrancheLoss Not implemented for this model."); |
69 | 0 | } |
70 | | /*! Probability of the tranche losing the same or more than the |
71 | | fractional amount given. |
72 | | |
73 | | The passed lossFraction is a fraction of losses over the |
74 | | tranche notional (not the portfolio). |
75 | | */ |
76 | | virtual Probability probOverLoss( |
77 | 0 | const Date& d, Real lossFraction) const { |
78 | 0 | QL_FAIL("probOverLoss Not implemented for this model."); |
79 | 0 | } |
80 | | //! Value at Risk given a default loss percentile. |
81 | 0 | virtual Real percentile(const Date& d, Real percentile) const { |
82 | 0 | QL_FAIL("percentile Not implemented for this model."); |
83 | 0 | } |
84 | | //! Expected shortfall given a default loss percentile. |
85 | 0 | virtual Real expectedShortfall(const Date& d, Real percentile) const { |
86 | 0 | QL_FAIL("eSF Not implemented for this model."); |
87 | 0 | } |
88 | | //! Associated VaR fraction to each counterparty. |
89 | 0 | virtual std::vector<Real> splitVaRLevel(const Date& d, Real loss) const { |
90 | 0 | QL_FAIL("splitVaRLevel Not implemented for this model."); |
91 | 0 | } |
92 | | //! Associated ESF fraction to each counterparty. |
93 | 0 | virtual std::vector<Real> splitESFLevel(const Date& d, Real loss) const { |
94 | 0 | QL_FAIL("splitESFLevel Not implemented for this model."); |
95 | 0 | } |
96 | | |
97 | | // \todo Add splits by instrument position. |
98 | | |
99 | | //! Full loss distribution. |
100 | 0 | virtual std::map<Real, Probability> lossDistribution(const Date&) const { |
101 | 0 | QL_FAIL("lossDistribution Not implemented for this model."); |
102 | 0 | } |
103 | | //! Probability density of a given loss fraction of the basket notional. |
104 | | virtual Real densityTrancheLoss( |
105 | 0 | const Date& d, Real lossFraction) const { |
106 | 0 | QL_FAIL("densityTrancheLoss Not implemented for this model."); |
107 | 0 | } |
108 | | /*! Probabilities for each of the (remaining) basket elements in the |
109 | | pool to have defaulted by time d and at the same time be the Nth |
110 | | defaulting name to default in the basket. This method is oriented to |
111 | | default order dependent portfolio pricing (e.g. NTDs) |
112 | | The the probabilities ordering in the vector coincides with the |
113 | | pool order. |
114 | | */ |
115 | 0 | virtual std::vector<Probability> probsBeingNthEvent(Size n, const Date& d) const { |
116 | 0 | QL_FAIL("probsBeingNthEvent Not implemented for this model."); |
117 | 0 | } |
118 | | //! Pearsons' default probability correlation. |
119 | | virtual Real defaultCorrelation(const Date& d, Size iName, |
120 | 0 | Size jName) const { |
121 | 0 | QL_FAIL("defaultCorrelation Not implemented for this model."); |
122 | 0 | } |
123 | | /*! Returns the probaility of having a given or larger number of |
124 | | defaults in the basket portfolio at a given time. |
125 | | */ |
126 | 0 | virtual Probability probAtLeastNEvents(Size n, const Date& d) const { |
127 | 0 | QL_FAIL("probAtLeastNEvents Not implemented for this model."); |
128 | 0 | } |
129 | | /*! Expected RR for name conditinal to default by that date. |
130 | | */ |
131 | | virtual Real expectedRecovery(const Date&, Size iName, |
132 | 0 | const DefaultProbKey&) const { |
133 | 0 | QL_FAIL("expected recovery Not implemented for this model."); |
134 | 0 | } |
135 | | //@} |
136 | | |
137 | | /*! Send a reference to the basket to allow the model to read the |
138 | | problem arguments (contained in the basket) |
139 | | */ |
140 | | private: //can only be called from Basket |
141 | 0 | void setBasket(Basket* bskt) { |
142 | | /* After this; if the model modifies its internal status/caches (if |
143 | | any) it should notify the prior basket to recognise that basket is |
144 | | not in a calculated=true state. Since we dont know at this level if |
145 | | the model keeps caches it is the children responsibility. Typically |
146 | | this is done at the first call to calculate to the loss model, there |
147 | | it notifies the basket. The old basket is still registered with us |
148 | | until the basket takes in a new model.... |
149 | | ..alternatively both old basket and model could be forced reset here |
150 | | */ |
151 | 0 | basket_.linkTo(ext::shared_ptr<Basket>(bskt, null_deleter()), |
152 | 0 | false); |
153 | 0 | resetModel();// or rename to setBasketImpl(...) |
154 | 0 | } |
155 | | // the call order matters, which is the reason for the parent to be the |
156 | | // sole caller. |
157 | | //! Concrete models do now any updates/inits they need on basket reset |
158 | | virtual void resetModel() = 0; |
159 | | }; |
160 | | |
161 | | } |
162 | | |
163 | | #endif |