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 cdo.hpp
21 \brief collateralized debt obligation
22*/
23
24#ifndef quantlib_cdo_hpp
25#define quantlib_cdo_hpp
26
27#include <ql/instrument.hpp>
28#include <ql/termstructures/yieldtermstructure.hpp>
29#include <ql/termstructures/defaulttermstructure.hpp>
30#include <ql/experimental/credit/lossdistribution.hpp>
31#include <ql/experimental/credit/onefactorcopula.hpp>
32#include <ql/time/schedule.hpp>
33
34namespace QuantLib {
35
36 //! collateralized debt obligation
37 /*! The instrument prices a mezzanine CDO tranche with loss given
38 default between attachment point \f$ D_1\f$ and detachment
39 point \f$ D_2 > D_1 \f$.
40
41 For purchased protection, the instrument value is given by the
42 difference of the protection value \f$ V_1 \f$ and premium
43 value \f$ V_2 \f$,
44
45 \f[ V = V_1 - V_2. \f]
46
47 The protection leg is priced as follows:
48
49 - Build the probability distribution for volume of defaults
50 \f$ L \f$ (before recovery) or Loss Given Default \f$ LGD =
51 (1-r)\,L \f$ at times/dates \f$ t_i, i=1, ..., N\f$ (premium
52 schedule times with intermediate steps)
53 - Determine the expected value
54 \f$ E_i = E_{t_i}\,\left[Pay(LGD)\right] \f$
55 of the protection payoff \f$ Pay(LGD) \f$ at each time
56 \f$ t_i\f$ where
57 \f[
58 Pay(L) = min (D_1, LGD) - min (D_2, LGD) = \left\{
59 \begin{array}{lcl}
60 \displaystyle 0 &;& LGD < D_1 \\
61 \displaystyle LGD - D_1 &;& D_1 \leq LGD \leq D_2 \\
62 \displaystyle D_2 - D_1 &;& LGD > D_2
63 \end{array}
64 \right.
65 \f]
66 - The protection value is then calculated as
67 \f[ V_1 \:=\: \sum_{i=1}^N (E_i - E_{i-1}) \cdot d_i \f]
68 where \f$ d_i\f$ is the discount factor at time/date \f$ t_i \f$
69
70 The premium is paid on the protected notional amount,
71 initially \f$ D_2 - D_1. \f$ This notional amount is reduced
72 by the expected protection payments \f$ E_i \f$ at times
73 \f$ t_i, \f$ so that the premium value is calculated as
74
75 \f[
76 V_2 = m \, \cdot \sum_{i=1}^N \,(D_2 - D_1 - E_i)
77 \cdot \Delta_{i-1,i}\,d_i
78 \f]
79
80 where \f$ m \f$ is the premium rate, \f$ \Delta_{i-1, i}\f$ is
81 the day count fraction between date/time \f$ t_{i-1}\f$ and
82 \f$ t_i.\f$
83
84 The construction of the portfolio loss distribution \f$ E_i
85 \f$ is based on the probability bucketing algorithm described
86 in
87
88 <strong>
89 John Hull and Alan White, "Valuation of a CDO and nth to default CDS
90 without Monte Carlo simulation", Journal of Derivatives 12, 2, 2004
91 </strong>
92
93 The pricing algorithm allows for varying notional amounts and
94 default termstructures of the underlyings.
95
96 \todo Investigate and fix cases \f$ E_{i+1} < E_i. \f$
97 */
98 class CDO : public Instrument {
99 public:
100 /*! \param attachment fraction of the LGD where protection starts
101 \param detachment fraction of the LGD where protection ends
102 \param nominals vector of basket nominal amounts
103 \param basket default basket represented by a vector of
104 default term structures that allow
105 computing single name default
106 probabilities depending on time
107 \param copula one-factor copula
108 \param protectionSeller sold protection if set to true, purchased
109 otherwise
110 \param premiumSchedule schedule for premium payments
111 \param premiumRate annual premium rate, e.g. 0.05 for 5% p.a.
112 \param dayCounter day count convention for the premium rate
113 \param recoveryRate recovery rate as a fraction
114 \param upfrontPremiumRate premium as a tranche notional fraction
115 \param yieldTS yield term structure handle
116 \param nBuckets number of distribution buckets
117 \param integrationStep time step for integrating over one
118 premium period; if larger than premium
119 period length, a single step is taken
120 */
121 CDO(Real attachment,
122 Real detachment,
123 std::vector<Real> nominals,
124 const std::vector<Handle<DefaultProbabilityTermStructure> >& basket,
125 Handle<OneFactorCopula> copula,
126 bool protectionSeller,
127 Schedule premiumSchedule,
128 Rate premiumRate,
129 DayCounter dayCounter,
130 Rate recoveryRate,
131 Rate upfrontPremiumRate,
132 Handle<YieldTermStructure> yieldTS,
133 Size nBuckets,
134 const Period& integrationStep = Period(10, Years));
135
136 Real nominal() const { return nominal_; }
137 Real lgd() const { return lgd_; }
138 Real attachment() const { return attachment_; }
139 Real detachment() const { return detachment_; }
140 std::vector<Real> nominals() { return nominals_; }
141 Size size() { return basket_.size(); }
142
143 bool isExpired() const override;
144 Rate fairPremium() const;
145 Rate premiumValue () const;
146 Rate protectionValue () const;
147 Size error () const;
148
149 private:
150 void setupExpired() const override;
151 void performCalculations() const override;
152 Real expectedTrancheLoss (Date d) const;
153
154 Real attachment_;
155 Real detachment_;
156 std::vector<Real> nominals_;
157 std::vector<Handle<DefaultProbabilityTermStructure> > basket_;
158 Handle<OneFactorCopula> copula_;
159 bool protectionSeller_;
160
161 Schedule premiumSchedule_;
162 Rate premiumRate_;
163 DayCounter dayCounter_;
164 Rate recoveryRate_;
165 Rate upfrontPremiumRate_;
166 Handle<YieldTermStructure> yieldTS_;
167 Size nBuckets_; // number of buckets up to detachment point
168 Period integrationStep_;
169
170 std::vector<Real> lgds_;
171
172 Real nominal_; // total basket volume (sum of nominals_)
173 Real lgd_; // maximum loss given default (sum of lgds_)
174 Real xMax_; // tranche detachment point (tranche_ * nominal_)
175 Real xMin_; // tranche attachment point (tranche_ * nominal_)
176
177 mutable Size error_;
178
179 mutable Real premiumValue_;
180 mutable Real protectionValue_;
181 mutable Real upfrontPremiumValue_;
182 };
183
184}
185
186#endif
187

source code of quantlib/ql/experimental/credit/cdo.hpp