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