QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
cdo.cpp
Go to the documentation of this file.
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#include <ql/event.hpp>
22#include <utility>
23
24using namespace std;
25
26namespace QuantLib {
27
28 CDO::CDO(Real attachment,
29 Real detachment,
30 vector<Real> nominals,
31 const vector<Handle<DefaultProbabilityTermStructure> >& basket,
33 bool protectionSeller,
34 Schedule premiumSchedule,
35 Rate premiumRate,
36 DayCounter dayCounter,
37 Rate recoveryRate,
38 Rate upfrontPremiumRate,
40 Size nBuckets,
41 const Period& integrationStep)
42 : attachment_(attachment), detachment_(detachment), nominals_(std::move(nominals)),
43 basket_(basket), copula_(std::move(copula)), protectionSeller_(protectionSeller),
44 premiumSchedule_(std::move(premiumSchedule)), premiumRate_(premiumRate),
45 dayCounter_(std::move(dayCounter)), recoveryRate_(recoveryRate),
46 upfrontPremiumRate_(upfrontPremiumRate), yieldTS_(std::move(yieldTS)), nBuckets_(nBuckets),
47 integrationStep_(integrationStep) {
48
49 QL_REQUIRE (!basket.empty(), "basket is empty");
51 && detachment_ <= 1,
52 "illegal attachment/detachment point");
53
56 for (auto& i : basket_)
57 registerWith(i);
58
59 QL_REQUIRE (nominals_.size() <= basket_.size(),
60 "nominal vector size too large");
61
62 if (nominals_.size() < basket_.size()) {
63 Size n = basket_.size() - nominals_.size();
64 Real back = nominals_.back();
65 for (Size i = 0; i < n; i++)
66 nominals_.push_back(back);
67 }
68
69 QL_REQUIRE (nominals_.size() == basket_.size(),
70 "nominal size " << nominals_.size()
71 << " != basket size " << basket_.size());
72
73 nominal_ = 0;
74 for (Size i = 0; i < nominals_.size(); i++) {
75 lgds_.push_back (nominals_[i] * (1.0 - recoveryRate_));
76 nominal_ += nominals_[i];
77 lgd_ += lgds_[i];
78 }
81 }
82
83
84 bool CDO::isExpired () const {
86 .hasOccurred(yieldTS_->referenceDate());
87 }
88
89
90 void CDO::setupExpired() const {
92 }
93
94
96 if (d <= basket_.front()->referenceDate())
97 return 0;
98
99 vector<Real> defProb (basket_.size());
100 for (Size j = 0; j < basket_.size(); j++)
101 defProb[j] = basket_[j]->defaultProbability (d);
102
104 Distribution dist = copula_->integral (op, lgds_, defProb);
105
106 return dist.trancheExpectedValue (xMin_, xMax_);
107
108 // The following causes two errors in test against literature values.
109 // FIXME: Investigate accuracy.
110 // return dist.cumulativeExcessProbability (xMin_, xMax_);
111
112 // TranchePayoff func (xMin_, xMax_);
113 // return (dist.expectedValue (func)
114 // + (xMax_ - xMin_) * (1.0 - dist.cumulatedProbability (xMax_)));
115 }
116
117
119
120 QL_REQUIRE(!yieldTS_.empty(), "no yield term structure set");
121
123
124 NPV_ = 0.0;
125 premiumValue_ = 0;
127 error_ = 0;
128
129 /* Expectations e1 and e2 are portfolio loss given default,
130 i.e. with recovery already "bult in". Multiplication by
131 (1-r) is therefore not necessary, neither in premium nor
132 protection value calculation.
133 */
134
135 Real e1 = 0;
136 Date today = yieldTS_->referenceDate();
137 if (premiumSchedule_[0] > today)
139
140 for (Size i = 1; i < premiumSchedule_.size(); i++) {
141 Date d2 = premiumSchedule_[i];
142 if (d2 < today)
143 continue;
144
145 Date d1 = premiumSchedule_[i-1];
146
147 Date d, d0 = d1;
148 do {
149 d = NullCalendar().advance (d0 > today ? d0 : today,
151 if (d > d2)
152 d = d2;
153
155
156 premiumValue_ += (xMax_ - xMin_ - e2)
158 * yieldTS_->discount (d);
159
160 if (e2 < e1) {
161 error_ ++;
162 }
163
164 protectionValue_ -= (e2 - e1) * yieldTS_->discount (d);
165
166 d0 = d;
167 e1 = e2;
168 }
169 while (d < d2);
170 }
171
172 if (premiumSchedule_[0] >= today)
174 yieldTS_->discount(premiumSchedule_[0]);
175 else
177
178 if (!protectionSeller_) {
179 premiumValue_ *= -1;
181 protectionValue_ *= -1;
182 }
183
185 }
186
187
189 calculate();
190 return premiumValue_;
191 }
192
194 calculate();
195 return protectionValue_;
196 }
197
198 Size CDO::error () const {
199 calculate();
200 return error_;
201 }
202
204 calculate();
206 }
207
208}
collateralized debt obligation
Real upfrontPremiumValue_
Definition: cdo.hpp:181
Real nominal_
Definition: cdo.hpp:172
Real protectionValue_
Definition: cdo.hpp:180
Size error() const
Definition: cdo.cpp:198
void performCalculations() const override
Definition: cdo.cpp:118
Real premiumValue_
Definition: cdo.hpp:179
bool isExpired() const override
returns whether the instrument might have value greater than zero.
Definition: cdo.cpp:84
Real lgd_
Definition: cdo.hpp:173
Real xMin_
Definition: cdo.hpp:175
CDO(Real attachment, Real detachment, std::vector< Real > nominals, const std::vector< Handle< DefaultProbabilityTermStructure > > &basket, Handle< OneFactorCopula > copula, bool protectionSeller, Schedule premiumSchedule, Rate premiumRate, DayCounter dayCounter, Rate recoveryRate, Rate upfrontPremiumRate, Handle< YieldTermStructure > yieldTS, Size nBuckets, const Period &integrationStep=Period(10, Years))
Definition: cdo.cpp:28
Rate upfrontPremiumRate_
Definition: cdo.hpp:165
Real attachment_
Definition: cdo.hpp:154
bool protectionSeller_
Definition: cdo.hpp:159
DayCounter dayCounter_
Definition: cdo.hpp:163
Handle< OneFactorCopula > copula_
Definition: cdo.hpp:158
Rate protectionValue() const
Definition: cdo.cpp:193
Rate premiumRate_
Definition: cdo.hpp:162
Rate recoveryRate_
Definition: cdo.hpp:164
Real xMax_
Definition: cdo.hpp:174
Real expectedTrancheLoss(Date d) const
Definition: cdo.cpp:95
Rate fairPremium() const
Definition: cdo.cpp:203
void setupExpired() const override
Definition: cdo.cpp:90
Schedule premiumSchedule_
Definition: cdo.hpp:161
std::vector< Real > lgds_
Definition: cdo.hpp:170
Real detachment_
Definition: cdo.hpp:155
Rate premiumValue() const
Definition: cdo.cpp:188
Size nBuckets_
Definition: cdo.hpp:167
Size error_
Definition: cdo.hpp:177
Period integrationStep_
Definition: cdo.hpp:168
std::vector< Real > nominals_
Definition: cdo.hpp:156
std::vector< Handle< DefaultProbabilityTermStructure > > basket_
Definition: cdo.hpp:157
Handle< YieldTermStructure > yieldTS_
Definition: cdo.hpp:166
Date advance(const Date &, Integer n, TimeUnit unit, BusinessDayConvention convention=Following, bool endOfMonth=false) const
Definition: calendar.cpp:130
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
Time yearFraction(const Date &, const Date &, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date()) const
Returns the period between two dates as a fraction of year.
Definition: daycounter.hpp:128
Real trancheExpectedValue(Real a, Real d)
virtual bool hasOccurred(const Date &refDate=Date(), ext::optional< bool > includeRefDate=ext::nullopt) const
returns true if an event has already occurred before a date
Definition: event.cpp:28
Shared handle to an observable.
Definition: handle.hpp:41
void calculate() const override
Definition: instrument.hpp:129
virtual void setupExpired() const
Definition: instrument.hpp:140
Loss distribution with Hull-White bucketing.
Calendar for reproducing theoretical calculations.
template class providing a null value for a given type.
Definition: null.hpp:76
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
Payment schedule.
Definition: schedule.hpp:40
const std::vector< Date > & dates() const
Definition: schedule.hpp:75
Size size() const
Definition: schedule.hpp:69
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
Base class for events associated with a given date.
Date d
QL_REAL Real
real number
Definition: types.hpp:50
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
STL namespace.