Coverage Report

Created: 2025-08-05 06:45

/src/quantlib/ql/experimental/credit/defaultevent.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) 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 = 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,
111
                     Real recoveryRate);
112
113
        Date date() const override;
114
0
        bool isRestructuring() const { return eventType_.isRestructuring(); }
115
0
        bool isDefault() const { return !isRestructuring();}
116
0
        bool hasSettled() const {
117
0
            return defSettlement_.date() != Date();
118
0
        }
119
0
        const DefaultSettlement& settlement() const {
120
0
            return defSettlement_;
121
0
        }
122
0
        const DefaultType& defaultType() const {
123
0
            return eventType_;
124
0
        }
125
        //! returns the currency of the bond this event refers to.
126
0
        const Currency& currency() const {
127
0
            return bondsCurrency_;
128
0
        }
129
        //! returns the seniority of the bond that triggered the event.
130
0
        Seniority eventSeniority() const {
131
0
            return bondsSeniority_;
132
0
        }
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
0
        virtual Real recoveryRate(Seniority seniority) const {
138
0
            if(hasSettled()) {
139
0
                return defSettlement_.recoveryRate(seniority);
140
0
            }
141
0
            return Null<Real>();
142
0
        }
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
0
                 const ext::shared_ptr<DefaultType>& contractEvType) const {
152
            // remember we are made of an atomic type.
153
            // behaviour by default...
154
0
            return
155
0
                contractEvType->containsRestructuringType(
156
0
                    eventType_.restructuringType()) &&
157
0
                contractEvType->containsDefaultType(
158
0
                    eventType_.defaultType());
159
0
        }
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
0
    inline bool operator!=(const DefaultEvent& lhs, const DefaultEvent& rhs) {
185
0
        return !(lhs == rhs);
186
0
    }
187
188
    template<>
189
    struct earlier_than<DefaultEvent> {
190
        bool operator()(const DefaultEvent& e1,
191
0
                        const DefaultEvent& e2) const {
192
0
            return e1.date() < e2.date();
193
0
        }
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
0
        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
0
        bool matchesEventType(const ext::shared_ptr<DefaultType>&) const override { return true; }
242
    };
243
244
}
245
246
#endif