Coverage Report

Created: 2025-12-08 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/experimental/credit/nthtodefault.hpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2008 Roland Lichters
5
6
 This file is part of QuantLib, a free-software/open-source library
7
 for financial quantitative analysts and developers - http://quantlib.org/
8
9
 QuantLib is free software: you can redistribute it and/or modify it
10
 under the terms of the QuantLib license.  You should have received a
11
 copy of the license along with this program; if not, please email
12
 <quantlib-dev@lists.sf.net>. The license is also available online at
13
 <https://www.quantlib.org/license.shtml>.
14
15
 This program is distributed in the hope that it will be useful, but WITHOUT
16
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
 FOR A PARTICULAR PURPOSE.  See the license for more details.
18
*/
19
20
/*! \file nthtodefault.hpp
21
    \brief N-th to default swap
22
*/
23
24
#ifndef quantlib_nth_to_default_hpp
25
#define quantlib_nth_to_default_hpp
26
27
#include <ql/instrument.hpp>
28
#include <ql/cashflow.hpp>
29
#include <ql/default.hpp>
30
#include <ql/termstructures/defaulttermstructure.hpp>
31
#include <ql/experimental/credit/onefactorcopula.hpp>
32
#include <ql/time/schedule.hpp>
33
34
namespace QuantLib {
35
36
    class YieldTermStructure;
37
    class Claim;
38
    class Basket;
39
40
    //--------------------------------------------------------------------------
41
    //! N-th to default swap
42
    /*! A NTD instrument exchanges protection against the nth default
43
        in a basket of underlying credits for premium payments based
44
        on the protected notional amount.
45
46
        The pricing is analogous to the pricing of a CDS instrument
47
        which represents protection against default of a single
48
        underlying credit.  The only difference is the calculation of
49
        the probability of default.  In the CDS case, it is the
50
        probabilty of single name default; in the NTD case the
51
        probability of at least N defaults in the portfolio of
52
        underlying credits.
53
54
        This probability is computed using the algorithm in
55
        John Hull and Alan White, "Valuation of a CDO and nth to
56
        default CDS without Monte Carlo simulation", Journal of
57
        Derivatives 12, 2, 2004.
58
59
        The algorithm allows for varying probability of default across
60
        the basket. Otherwise, for identical probabilities of default,
61
        the probability of n defaults is given by the binomial
62
        distribution.
63
64
        Default correlation is modeled using a one-factor Gaussian copula
65
        approach.
66
67
        The class is tested against data in Hull-White (see reference
68
        above.)
69
    */
70
    class NthToDefault : public Instrument {
71
      public:
72
        class arguments;
73
        class results;
74
        class engine;
75
76
        //! This product is 'digital'; the basket might be tranched but this is
77
        //  not relevant to it.
78
        NthToDefault(const ext::shared_ptr<Basket>& basket,
79
                Size n,
80
                Protection::Side side,
81
                Schedule premiumSchedule,
82
                Rate upfrontRate,
83
                Rate premiumRate,
84
                const DayCounter& dayCounter,
85
                Real nominal,
86
                bool settlePremiumAccrual);
87
88
        bool isExpired() const override;
89
90
        // inspectors
91
0
        Rate premium() const { return premiumRate_; }
92
0
        Real nominal() const { return nominal_; }
93
0
        DayCounter dayCounter() const { return dayCounter_; }
94
0
        Protection::Side side() const { return side_; }
95
0
        Size rank() const { return n_; }
96
        Size basketSize() const;
97
98
0
        const Date& maturity() const {return premiumSchedule_.endDate();}//???
99
100
0
        const ext::shared_ptr<Basket>& basket() const {return basket_;}
101
102
        // results
103
        Rate fairPremium() const;
104
        Real premiumLegNPV() const;
105
        Real protectionLegNPV() const;
106
        Real errorEstimate() const;
107
108
        void setupArguments(PricingEngine::arguments*) const override;
109
        void fetchResults(const PricingEngine::results*) const override;
110
111
      private:
112
        void setupExpired() const override;
113
114
        ext::shared_ptr<Basket> basket_;
115
        Size n_;
116
        Protection::Side side_;
117
        Real nominal_;
118
        Schedule premiumSchedule_;
119
        Rate premiumRate_;
120
        Rate upfrontRate_;
121
        DayCounter dayCounter_;
122
        bool settlePremiumAccrual_;
123
124
        Leg premiumLeg_;/////////////////// LEG AND SCHEDULE BOTH MEMBERS..... REVISE THIS!
125
126
        // results
127
        mutable Rate premiumValue_;
128
        mutable Real protectionValue_;
129
        mutable Real upfrontPremiumValue_;
130
        mutable Real fairPremium_;
131
        mutable Real errorEstimate_;
132
    };
133
134
135
136
    class NthToDefault::arguments : public virtual PricingEngine::arguments {
137
    public:
138
        arguments() : side(Protection::Side(-1)),
139
                      premiumRate(Null<Real>()),
140
0
                      upfrontRate(Null<Real>()) {}
141
        void validate() const override;
142
143
        ext::shared_ptr<Basket> basket;
144
        Protection::Side side;
145
        Leg premiumLeg;
146
147
        Size ntdOrder;
148
        bool settlePremiumAccrual;
149
        Real notional;// ALL NAMES WITH THE SAME WEIGHT, NOTIONAL IS NOT MAPPED TO THE BASKET HERE, this does not have to be that way, its perfectly possible to have irreg notionals...
150
        Real premiumRate;
151
        Rate upfrontRate;
152
    };
153
154
    class NthToDefault::results : public Instrument::results {
155
    public:
156
      void reset() override;
157
      Real premiumValue;
158
      Real protectionValue;
159
      Real upfrontPremiumValue;
160
      Real fairPremium;
161
      Real errorEstimate;
162
    };
163
164
    //! NTD base engine
165
    class NthToDefault::engine :
166
        public GenericEngine<NthToDefault::arguments,
167
                             NthToDefault::results> { };
168
169
}
170
171
#endif