| 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 | <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 | /*! \file defaultevent.hpp |
| 22 | \brief Classes for default-event description. |
| 23 | */ |
| 24 | |
| 25 | #ifndef quantlib_default_event_hpp |
| 26 | #define quantlib_default_event_hpp |
| 27 | |
| 28 | #include <ql/event.hpp> |
| 29 | #include <ql/currency.hpp> |
| 30 | #include <ql/math/comparison.hpp> |
| 31 | #include <ql/experimental/credit/defaulttype.hpp> |
| 32 | #include <ql/experimental/credit/defaultprobabilitykey.hpp> |
| 33 | #include <map> |
| 34 | |
| 35 | namespace QuantLib { |
| 36 | |
| 37 | /** |
| 38 | @class DefaultEvent |
| 39 | @brief Credit event on a bond of a certain seniority(ies)/currency |
| 40 | |
| 41 | Represents a credit event affecting all bonds with a given \ |
| 42 | seniority and currency. It assumes that all such bonds suffer \ |
| 43 | the event simultaneously. |
| 44 | Some events affect all seniorities and this has to be encoded |
| 45 | through a different set of events of the same event type. |
| 46 | The event is an actual realization, not a contractual reference, |
| 47 | as such it contains only an atomic type. |
| 48 | */ |
| 49 | class DefaultEvent : public Event { |
| 50 | public: |
| 51 | class DefaultSettlement : public Event { |
| 52 | public: |
| 53 | friend class DefaultEvent; |
| 54 | protected: |
| 55 | /*! Default settlement events encode the settlement date |
| 56 | and the recovery rates for the affected |
| 57 | seniorities. Specific events might require different |
| 58 | sets of recoveries to be present. The way these |
| 59 | objects are constructed is a prerogative of the |
| 60 | particular event class. |
| 61 | */ |
| 62 | DefaultSettlement(const Date& date, |
| 63 | const std::map<Seniority, Real>& recoveryRates); |
| 64 | /*! When NoSeniority is passed all seniorities are assumed |
| 65 | to have settled to the recovery passed. |
| 66 | */ |
| 67 | DefaultSettlement(const Date& date = Date(), |
| 68 | Seniority seniority = NoSeniority, |
| 69 | Real recoveryRate = 0.4); |
| 70 | public: |
| 71 | Date date() const override; |
| 72 | /*! Returns the recovery rate of a default event which has already |
| 73 | settled. |
| 74 | */ |
| 75 | Real recoveryRate(Seniority sen) const; |
| 76 | void accept(AcyclicVisitor&) override; |
| 77 | |
| 78 | private: |
| 79 | Date settlementDate_; |
| 80 | //! Realized recovery rates |
| 81 | std::map<Seniority, Real> recoveryRates_; |
| 82 | }; |
| 83 | private: |
| 84 | // for some reason, gcc chokes on the default parameter below |
| 85 | // unless we use the typedef |
| 86 | typedef std::map<Seniority, Real> rate_map; |
| 87 | public: |
| 88 | /*! Credit event with optional settlement |
| 89 | information. Represents a credit event that has taken |
| 90 | place. Realized events are of an atomic type. If the |
| 91 | settlement information is given seniorities present are |
| 92 | the seniorities/bonds affected by the event. |
| 93 | */ |
| 94 | DefaultEvent(const Date& creditEventDate, |
| 95 | const DefaultType& atomicEvType, |
| 96 | Currency curr, |
| 97 | Seniority bondsSen, |
| 98 | // Settlement information: |
| 99 | const Date& settleDate = Null<Date>(), |
| 100 | const std::map<Seniority, Real>& recoveryRates = rate_map()); |
| 101 | /*! Use NoSeniority to settle to all seniorities with that |
| 102 | recovery. In that case the event is assumed to have |
| 103 | affected all seniorities. |
| 104 | */ |
| 105 | DefaultEvent(const Date& creditEventDate, |
| 106 | const DefaultType& atomicEvType, |
| 107 | Currency curr, |
| 108 | Seniority bondsSen, |
| 109 | // Settlement information: |
| 110 | const Date& settleDate = Null<Date>(), |
| 111 | Real recoveryRate = 0.4); |
| 112 | |
| 113 | Date date() const override; |
| 114 | bool isRestructuring() const { return eventType_.isRestructuring(); } |
| 115 | bool isDefault() const { return !isRestructuring();} |
| 116 | bool hasSettled() const { |
| 117 | return defSettlement_.date() != Null<Date>(); |
| 118 | } |
| 119 | const DefaultSettlement& settlement() const { |
| 120 | return defSettlement_; |
| 121 | } |
| 122 | const DefaultType& defaultType() const { |
| 123 | return eventType_; |
| 124 | } |
| 125 | //! returns the currency of the bond this event refers to. |
| 126 | const Currency& currency() const { |
| 127 | return bondsCurrency_; |
| 128 | } |
| 129 | //! returns the seniority of the bond that triggered the event. |
| 130 | Seniority eventSeniority() const { |
| 131 | return bondsSeniority_; |
| 132 | } |
| 133 | /*! returns a value if the event lead to a settlement for the |
| 134 | requested seniority. Specializations on the default |
| 135 | atomics and recoveries could change the default policy. |
| 136 | */ |
| 137 | virtual Real recoveryRate(Seniority seniority) const { |
| 138 | if(hasSettled()) { |
| 139 | return defSettlement_.recoveryRate(sen: seniority); |
| 140 | } |
| 141 | return Null<Real>(); |
| 142 | } |
| 143 | |
| 144 | /*! matches the event if this event would trigger a contract |
| 145 | related to the requested event type. Notice the |
| 146 | contractual event types are not neccesarily atomic. |
| 147 | Notice it does not check seniority or currency only event |
| 148 | type. typically used from Issuer |
| 149 | */ |
| 150 | virtual bool matchesEventType( |
| 151 | const ext::shared_ptr<DefaultType>& contractEvType) const { |
| 152 | // remember we are made of an atomic type. |
| 153 | // behaviour by default... |
| 154 | return |
| 155 | contractEvType->containsRestructuringType( |
| 156 | resType: eventType_.restructuringType()) && |
| 157 | contractEvType->containsDefaultType( |
| 158 | defType: eventType_.defaultType()); |
| 159 | } |
| 160 | /*! Returns true if this event would trigger a contract with |
| 161 | the arguments characteristics. |
| 162 | */ |
| 163 | virtual bool matchesDefaultKey(const DefaultProbKey& contractKey) const; |
| 164 | |
| 165 | void accept(AcyclicVisitor&) override; |
| 166 | |
| 167 | protected: |
| 168 | Currency bondsCurrency_; |
| 169 | Date defaultDate_; |
| 170 | DefaultType eventType_; |
| 171 | Seniority bondsSeniority_; |
| 172 | DefaultSettlement defSettlement_; |
| 173 | }; |
| 174 | |
| 175 | /*! Two credit events are the same independently of their |
| 176 | settlement member data. This has the side effect of |
| 177 | overwritting different settlements from the same credit event |
| 178 | when, say, inserting in a map. But on the other hand one given |
| 179 | event can only have one settlement. This means we can not have |
| 180 | two restructuring events on a bond on the same date. |
| 181 | */ |
| 182 | bool operator==(const DefaultEvent& lhs, const DefaultEvent& rhs); |
| 183 | |
| 184 | inline bool operator!=(const DefaultEvent& lhs, const DefaultEvent& rhs) { |
| 185 | return !(lhs == rhs); |
| 186 | } |
| 187 | |
| 188 | template<> |
| 189 | struct earlier_than<DefaultEvent> { |
| 190 | bool operator()(const DefaultEvent& e1, |
| 191 | const DefaultEvent& e2) const { |
| 192 | return e1.date() < e2.date(); |
| 193 | } |
| 194 | }; |
| 195 | |
| 196 | |
| 197 | // ------------------------------------------------------------------------ |
| 198 | |
| 199 | class FailureToPayEvent : public DefaultEvent { |
| 200 | public: |
| 201 | FailureToPayEvent(const Date& creditEventDate, |
| 202 | const Currency& curr, |
| 203 | Seniority bondsSen, |
| 204 | Real defaultedAmount, |
| 205 | // Settlement information: |
| 206 | const Date& settleDate, |
| 207 | const std::map<Seniority, Real>& recoveryRates); |
| 208 | FailureToPayEvent(const Date& creditEventDate, |
| 209 | const Currency& curr, |
| 210 | Seniority bondsSen, |
| 211 | Real defaultedAmount, |
| 212 | // Settlement information: |
| 213 | const Date& settleDate, |
| 214 | Real recoveryRates); |
| 215 | Real amountDefaulted() const {return defaultedAmount_;} |
| 216 | bool matchesEventType(const ext::shared_ptr<DefaultType>& contractEvType) const override; |
| 217 | |
| 218 | private: |
| 219 | Real defaultedAmount_; |
| 220 | }; |
| 221 | |
| 222 | |
| 223 | // ------------------------------------------------------------------------ |
| 224 | |
| 225 | class BankruptcyEvent : public DefaultEvent { |
| 226 | public: |
| 227 | BankruptcyEvent(const Date& creditEventDate, |
| 228 | const Currency& curr, |
| 229 | Seniority bondsSen, |
| 230 | // Settlement information: |
| 231 | const Date& settleDate, |
| 232 | const std::map<Seniority, Real>& recoveryRates); |
| 233 | BankruptcyEvent(const Date& creditEventDate, |
| 234 | const Currency& curr, |
| 235 | Seniority bondsSen, |
| 236 | // Settlement information: |
| 237 | const Date& settleDate, |
| 238 | // means same for all |
| 239 | Real recoveryRates); |
| 240 | //! This is a stronger than all event and will trigger all of them. |
| 241 | bool matchesEventType(const ext::shared_ptr<DefaultType>&) const override { return true; } |
| 242 | }; |
| 243 | |
| 244 | } |
| 245 | |
| 246 | #endif |
| 247 | |