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  <http://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                 const Schedule& premiumSchedule,
82                 Rate upfrontRate,
83                 Rate premiumRate,
84                 const DayCounter& dayCounter,
85                 Real nominal,
86                 bool settlePremiumAccrual);
87 
88         bool isExpired() const;
89 
90         // inspectors
premium() const91         Rate premium() const { return premiumRate_; }
nominal() const92         Real nominal() const { return nominal_; }
dayCounter() const93         DayCounter dayCounter() const { return dayCounter_; }
side() const94         Protection::Side side() const { return side_; }
rank() const95         Size rank() const { return n_; }
96         Size basketSize() const;
97 
maturity() const98         const Date& maturity() const {return premiumSchedule_.endDate();}//???
99 
basket() const100         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;
109         void fetchResults(const PricingEngine::results*) const;
110       private:
111 
112         void setupExpired() const;
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:
arguments()138         arguments() : side(Protection::Side(-1)),
139                       premiumRate(Null<Real>()),
140                       upfrontRate(Null<Real>()) {}
141         void validate() const;
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();
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
172