/src/quantlib/ql/experimental/credit/defaultevent.cpp
Line | Count | Source |
1 | | /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | |
3 | | /* |
4 | | Copyright (C) 2009 StatPro Italia srl |
5 | | Copyright (C) 2009 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 | | <https://www.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 | | #include <ql/experimental/credit/defaultevent.hpp> |
22 | | #include <ql/experimental/credit/recoveryratequote.hpp> |
23 | | #include <ql/patterns/visitor.hpp> |
24 | | #include <ql/settings.hpp> |
25 | | #include <utility> |
26 | | |
27 | | namespace QuantLib { |
28 | | |
29 | 0 | Date DefaultEvent::date() const { |
30 | 0 | return defaultDate_; |
31 | 0 | } |
32 | | |
33 | 0 | void DefaultEvent::accept(AcyclicVisitor& v) { |
34 | 0 | auto* v1 = dynamic_cast<Visitor<DefaultEvent>*>(&v); |
35 | 0 | if (v1 != nullptr) |
36 | 0 | v1->visit(*this); |
37 | 0 | else |
38 | 0 | Event::accept(v); |
39 | 0 | } |
40 | | |
41 | | // They will be sorted by settlement date |
42 | 0 | Date DefaultEvent::DefaultSettlement::date() const { |
43 | 0 | return settlementDate_; |
44 | 0 | } |
45 | | |
46 | 0 | void DefaultEvent::DefaultSettlement::accept(AcyclicVisitor& v) { |
47 | 0 | auto* v1 = dynamic_cast<Visitor<DefaultEvent::DefaultSettlement>*>(&v); |
48 | 0 | if (v1 != nullptr) |
49 | 0 | v1->visit(*this); |
50 | 0 | else |
51 | 0 | Event::accept(v); |
52 | 0 | } |
53 | | |
54 | | DefaultEvent::DefaultSettlement::DefaultSettlement( |
55 | | const Date& date, |
56 | | const std::map<Seniority, Real>& recoveryRates ) |
57 | 0 | : settlementDate_(date), recoveryRates_(recoveryRates) { |
58 | 0 | QL_REQUIRE(recoveryRates.find(NoSeniority) == |
59 | 0 | recoveryRates.end(), |
60 | 0 | "NoSeniority is not a valid realized seniority."); |
61 | 0 | } Unexecuted instantiation: QuantLib::DefaultEvent::DefaultSettlement::DefaultSettlement(QuantLib::Date const&, std::__1::map<QuantLib::Seniority, double, std::__1::less<QuantLib::Seniority>, std::__1::allocator<std::__1::pair<QuantLib::Seniority const, double> > > const&) Unexecuted instantiation: QuantLib::DefaultEvent::DefaultSettlement::DefaultSettlement(QuantLib::Date const&, std::__1::map<QuantLib::Seniority, double, std::__1::less<QuantLib::Seniority>, std::__1::allocator<std::__1::pair<QuantLib::Seniority const, double> > > const&) |
62 | | |
63 | | DefaultEvent::DefaultSettlement::DefaultSettlement( |
64 | | const Date& date, |
65 | | Seniority seniority, |
66 | | const Real recoveryRate) |
67 | 0 | : settlementDate_(date), recoveryRates_(makeIsdaConvMap()) { |
68 | 0 | if (seniority == NoSeniority) { |
69 | 0 | for (auto& i : recoveryRates_) { |
70 | 0 | i.second = recoveryRate; |
71 | 0 | } |
72 | 0 | } else { |
73 | 0 | recoveryRates_[seniority] = recoveryRate; |
74 | 0 | } |
75 | 0 | } Unexecuted instantiation: QuantLib::DefaultEvent::DefaultSettlement::DefaultSettlement(QuantLib::Date const&, QuantLib::Seniority, double) Unexecuted instantiation: QuantLib::DefaultEvent::DefaultSettlement::DefaultSettlement(QuantLib::Date const&, QuantLib::Seniority, double) |
76 | | |
77 | | Real DefaultEvent::DefaultSettlement::recoveryRate( |
78 | 0 | Seniority sen) const { |
79 | | // expensive require cause called often...... fix me |
80 | 0 | QL_REQUIRE(sen != NoSeniority, |
81 | 0 | "NoSeniority is not valid for recovery rate request."); |
82 | 0 | auto itmatch = recoveryRates_.find(sen); |
83 | 0 | if(itmatch != recoveryRates_.end()) { |
84 | 0 | return itmatch->second; |
85 | 0 | }else{ |
86 | 0 | return Null<Real>(); |
87 | 0 | } |
88 | 0 | } |
89 | | |
90 | | DefaultEvent::DefaultEvent(const Date& creditEventDate, |
91 | | const DefaultType& atomicEvType, |
92 | | Currency curr, |
93 | | Seniority bondsSen, |
94 | | // Settlement information: |
95 | | const Date& settleDate, |
96 | | const std::map<Seniority, Real>& recoveryRates) |
97 | 0 | : bondsCurrency_(std::move(curr)), defaultDate_(creditEventDate), eventType_(atomicEvType), |
98 | 0 | bondsSeniority_(bondsSen), |
99 | 0 | defSettlement_(settleDate, recoveryRates.empty() ? makeIsdaConvMap() : recoveryRates) { |
100 | 0 | if (settleDate != Date()) {// has settled |
101 | 0 | QL_REQUIRE(settleDate >= creditEventDate, |
102 | 0 | "Settlement date should be after default date."); |
103 | 0 | QL_REQUIRE(recoveryRates.find(bondsSen) != recoveryRates.end(), |
104 | 0 | "Settled events must contain the seniority of the default"); |
105 | 0 | } |
106 | 0 | } Unexecuted instantiation: QuantLib::DefaultEvent::DefaultEvent(QuantLib::Date const&, QuantLib::DefaultType const&, QuantLib::Currency, QuantLib::Seniority, QuantLib::Date const&, std::__1::map<QuantLib::Seniority, double, std::__1::less<QuantLib::Seniority>, std::__1::allocator<std::__1::pair<QuantLib::Seniority const, double> > > const&) Unexecuted instantiation: QuantLib::DefaultEvent::DefaultEvent(QuantLib::Date const&, QuantLib::DefaultType const&, QuantLib::Currency, QuantLib::Seniority, QuantLib::Date const&, std::__1::map<QuantLib::Seniority, double, std::__1::less<QuantLib::Seniority>, std::__1::allocator<std::__1::pair<QuantLib::Seniority const, double> > > const&) |
107 | | |
108 | | DefaultEvent::DefaultEvent(const Date& creditEventDate, |
109 | | const DefaultType& atomicEvType, |
110 | | Currency curr, |
111 | | Seniority bondsSen, |
112 | | // Settlement information: |
113 | | const Date& settleDate, |
114 | | Real recoveryRate) |
115 | 0 | : bondsCurrency_(std::move(curr)), defaultDate_(creditEventDate), eventType_(atomicEvType), |
116 | 0 | bondsSeniority_(bondsSen), defSettlement_(settleDate, bondsSen, recoveryRate) { |
117 | 0 | if (settleDate != Date()) { |
118 | 0 | QL_REQUIRE(settleDate >= creditEventDate, |
119 | 0 | "Settlement date should be after default date."); |
120 | 0 | } |
121 | 0 | } Unexecuted instantiation: QuantLib::DefaultEvent::DefaultEvent(QuantLib::Date const&, QuantLib::DefaultType const&, QuantLib::Currency, QuantLib::Seniority, QuantLib::Date const&, double) Unexecuted instantiation: QuantLib::DefaultEvent::DefaultEvent(QuantLib::Date const&, QuantLib::DefaultType const&, QuantLib::Currency, QuantLib::Seniority, QuantLib::Date const&, double) |
122 | | |
123 | | bool DefaultEvent::matchesDefaultKey( |
124 | 0 | const DefaultProbKey& contractKey) const { |
125 | 0 | if(bondsCurrency_ != contractKey.currency()) return false; |
126 | | // a contract with NoSeniority matches all events |
127 | 0 | if((bondsSeniority_ != contractKey.seniority()) |
128 | 0 | && (contractKey.seniority() != NoSeniority)) |
129 | 0 | return false; |
130 | | // loop on all event types in the contract and chek if we match any, |
131 | | // calls derived types |
132 | 0 | for(Size i=0; i<contractKey.size(); i++) { |
133 | 0 | if(this->matchesEventType(contractKey.eventTypes()[i])) return true; |
134 | 0 | } |
135 | 0 | return false; |
136 | 0 | } |
137 | | |
138 | | |
139 | | |
140 | 0 | bool operator==(const DefaultEvent& lhs, const DefaultEvent& rhs) { |
141 | 0 | return (lhs.currency() == rhs.currency()) && |
142 | 0 | (lhs.defaultType() == rhs.defaultType()) && |
143 | 0 | (lhs.date() == rhs.date()) && |
144 | 0 | (lhs.eventSeniority() == rhs.eventSeniority()); |
145 | 0 | } |
146 | | |
147 | | |
148 | | bool FailureToPayEvent::matchesEventType( |
149 | 0 | const ext::shared_ptr<DefaultType>& contractEvType) const { |
150 | 0 | ext::shared_ptr<FailureToPay> eveType = |
151 | 0 | ext::dynamic_pointer_cast<FailureToPay>(contractEvType); |
152 | | // this chekcs the atomic types, no need to call parents method |
153 | 0 | if(!eveType) return false; |
154 | 0 | if(defaultedAmount_ < eveType->amountRequired()) return false; |
155 | 0 | Date today = Settings::instance().evaluationDate(); |
156 | 0 | return this->hasOccurred(today - eveType->gracePeriod(), true); |
157 | 0 | } |
158 | | |
159 | | |
160 | | |
161 | | FailureToPayEvent::FailureToPayEvent(const Date& creditEventDate, |
162 | | const Currency& curr, |
163 | | Seniority bondsSen, |
164 | | Real defaultedAmount, |
165 | | // Settlement information: |
166 | | const Date& settleDate, |
167 | | const std::map<Seniority, Real>& |
168 | | recoveryRates) |
169 | 0 | : DefaultEvent(creditEventDate, |
170 | 0 | DefaultType(AtomicDefault::FailureToPay, |
171 | 0 | Restructuring::XR), |
172 | 0 | curr, |
173 | 0 | bondsSen, |
174 | 0 | settleDate, |
175 | 0 | recoveryRates), |
176 | 0 | defaultedAmount_(defaultedAmount) { }Unexecuted instantiation: QuantLib::FailureToPayEvent::FailureToPayEvent(QuantLib::Date const&, QuantLib::Currency const&, QuantLib::Seniority, double, QuantLib::Date const&, std::__1::map<QuantLib::Seniority, double, std::__1::less<QuantLib::Seniority>, std::__1::allocator<std::__1::pair<QuantLib::Seniority const, double> > > const&) Unexecuted instantiation: QuantLib::FailureToPayEvent::FailureToPayEvent(QuantLib::Date const&, QuantLib::Currency const&, QuantLib::Seniority, double, QuantLib::Date const&, std::__1::map<QuantLib::Seniority, double, std::__1::less<QuantLib::Seniority>, std::__1::allocator<std::__1::pair<QuantLib::Seniority const, double> > > const&) |
177 | | |
178 | | FailureToPayEvent::FailureToPayEvent(const Date& creditEventDate, |
179 | | const Currency& curr, |
180 | | Seniority bondsSen, |
181 | | Real defaultedAmount, |
182 | | // Settlement information: |
183 | | const Date& settleDate, |
184 | | Real recoveryRates) |
185 | 0 | : DefaultEvent(creditEventDate, |
186 | 0 | DefaultType(AtomicDefault::FailureToPay, |
187 | 0 | Restructuring::XR), |
188 | 0 | curr, |
189 | 0 | bondsSen, |
190 | 0 | settleDate, |
191 | 0 | recoveryRates), |
192 | 0 | defaultedAmount_(defaultedAmount) { }Unexecuted instantiation: QuantLib::FailureToPayEvent::FailureToPayEvent(QuantLib::Date const&, QuantLib::Currency const&, QuantLib::Seniority, double, QuantLib::Date const&, double) Unexecuted instantiation: QuantLib::FailureToPayEvent::FailureToPayEvent(QuantLib::Date const&, QuantLib::Currency const&, QuantLib::Seniority, double, QuantLib::Date const&, double) |
193 | | |
194 | | |
195 | | |
196 | | BankruptcyEvent::BankruptcyEvent(const Date& creditEventDate, |
197 | | const Currency& curr, |
198 | | Seniority bondsSen, |
199 | | // Settlement information: |
200 | | const Date& settleDate, |
201 | | const std::map<Seniority, Real>& |
202 | | recoveryRates) |
203 | 0 | : DefaultEvent(creditEventDate, |
204 | 0 | DefaultType(AtomicDefault::Bankruptcy, |
205 | 0 | Restructuring::XR), |
206 | 0 | curr, |
207 | 0 | bondsSen, |
208 | 0 | settleDate, |
209 | 0 | recoveryRates) { |
210 | 0 | if(hasSettled()) { |
211 | 0 | QL_REQUIRE(recoveryRates.size() == makeIsdaConvMap().size(), |
212 | 0 | "Bankruptcy event should have settled for all seniorities."); |
213 | 0 | } |
214 | 0 | } Unexecuted instantiation: QuantLib::BankruptcyEvent::BankruptcyEvent(QuantLib::Date const&, QuantLib::Currency const&, QuantLib::Seniority, QuantLib::Date const&, std::__1::map<QuantLib::Seniority, double, std::__1::less<QuantLib::Seniority>, std::__1::allocator<std::__1::pair<QuantLib::Seniority const, double> > > const&) Unexecuted instantiation: QuantLib::BankruptcyEvent::BankruptcyEvent(QuantLib::Date const&, QuantLib::Currency const&, QuantLib::Seniority, QuantLib::Date const&, std::__1::map<QuantLib::Seniority, double, std::__1::less<QuantLib::Seniority>, std::__1::allocator<std::__1::pair<QuantLib::Seniority const, double> > > const&) |
215 | | |
216 | | BankruptcyEvent::BankruptcyEvent(const Date& creditEventDate, |
217 | | const Currency& curr, |
218 | | Seniority bondsSen, |
219 | | // Settlement information: |
220 | | const Date& settleDate, |
221 | | // means same for all |
222 | | Real recoveryRates) |
223 | 0 | : DefaultEvent(creditEventDate, |
224 | 0 | DefaultType(AtomicDefault::Bankruptcy, |
225 | 0 | Restructuring::XR), |
226 | 0 | curr, |
227 | 0 | bondsSen, |
228 | 0 | settleDate, |
229 | 0 | recoveryRates) { }Unexecuted instantiation: QuantLib::BankruptcyEvent::BankruptcyEvent(QuantLib::Date const&, QuantLib::Currency const&, QuantLib::Seniority, QuantLib::Date const&, double) Unexecuted instantiation: QuantLib::BankruptcyEvent::BankruptcyEvent(QuantLib::Date const&, QuantLib::Currency const&, QuantLib::Seniority, QuantLib::Date const&, double) |
230 | | |
231 | | } |