Coverage Report

Created: 2025-10-14 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}