1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2012, 2013 Grzegorz Andruszkiewicz 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/experimental/catbonds/catbond.hpp> 21 #include <ql/settings.hpp> 22 #include <ql/experimental/credit/loss.hpp> 23 #include <ql/time/daycounters/actualactual.hpp> 24 #include <ql/cashflows/cashflowvectors.hpp> 25 #include <ql/cashflows/iborcoupon.hpp> 26 #include <ql/cashflows/couponpricer.hpp> 27 #include <ql/cashflows/simplecashflow.hpp> 28 #include <ql/time/daycounters/actualactual.hpp> 29 30 using namespace std; 31 32 namespace QuantLib { 33 validate() const34 void CatBond::arguments::validate() const { 35 Bond::arguments::validate(); 36 QL_REQUIRE(notionalRisk, "null notionalRisk"); 37 } 38 setupArguments(PricingEngine::arguments * args) const39 void CatBond::setupArguments(PricingEngine::arguments* args) const { 40 41 CatBond::arguments* arguments = 42 dynamic_cast<CatBond::arguments*>(args); 43 QL_REQUIRE(arguments != 0, "wrong arguments type"); 44 45 Bond::setupArguments(args); 46 47 arguments->notionalRisk = notionalRisk_; 48 arguments->startDate = issueDate(); 49 } 50 fetchResults(const PricingEngine::results * r) const51 void CatBond::fetchResults(const PricingEngine::results* r) const { 52 Bond::fetchResults(r); 53 54 const CatBond::results* results = 55 dynamic_cast<const CatBond::results*>(r); 56 QL_ENSURE(results != 0, "wrong result type"); 57 58 lossProbability_ = results->lossProbability; 59 expectedLoss_ = results->expectedLoss; 60 exhaustionProbability_ = results->exhaustionProbability; 61 } 62 FloatingCatBond(Natural settlementDays,Real faceAmount,const Schedule & schedule,const ext::shared_ptr<IborIndex> & iborIndex,const DayCounter & paymentDayCounter,const ext::shared_ptr<NotionalRisk> & notionalRisk,BusinessDayConvention paymentConvention,Natural fixingDays,const std::vector<Real> & gearings,const std::vector<Spread> & spreads,const std::vector<Rate> & caps,const std::vector<Rate> & floors,bool inArrears,Real redemption,const Date & issueDate)63 FloatingCatBond::FloatingCatBond(Natural settlementDays, 64 Real faceAmount, 65 const Schedule& schedule, 66 const ext::shared_ptr<IborIndex>& iborIndex, 67 const DayCounter& paymentDayCounter, 68 const ext::shared_ptr<NotionalRisk>& notionalRisk, 69 BusinessDayConvention paymentConvention, 70 Natural fixingDays, 71 const std::vector<Real>& gearings, 72 const std::vector<Spread>& spreads, 73 const std::vector<Rate>& caps, 74 const std::vector<Rate>& floors, 75 bool inArrears, 76 Real redemption, 77 const Date& issueDate) 78 : CatBond(settlementDays, schedule.calendar(), issueDate, notionalRisk) { 79 80 maturityDate_ = schedule.endDate(); 81 82 cashflows_ = IborLeg(schedule, iborIndex) 83 .withNotionals(faceAmount) 84 .withPaymentDayCounter(paymentDayCounter) 85 .withPaymentAdjustment(paymentConvention) 86 .withFixingDays(fixingDays) 87 .withGearings(gearings) 88 .withSpreads(spreads) 89 .withCaps(caps) 90 .withFloors(floors) 91 .inArrears(inArrears); 92 93 addRedemptionsToCashflows(std::vector<Real>(1, redemption)); 94 95 QL_ENSURE(!cashflows().empty(), "bond with no cashflows!"); 96 QL_ENSURE(redemptions_.size() == 1, "multiple redemptions created"); 97 98 registerWith(iborIndex); 99 } 100 FloatingCatBond(Natural settlementDays,Real faceAmount,const Date & startDate,const Date & maturityDate,Frequency couponFrequency,const Calendar & calendar,const ext::shared_ptr<IborIndex> & iborIndex,const DayCounter & accrualDayCounter,const ext::shared_ptr<NotionalRisk> & notionalRisk,BusinessDayConvention accrualConvention,BusinessDayConvention paymentConvention,Natural fixingDays,const std::vector<Real> & gearings,const std::vector<Spread> & spreads,const std::vector<Rate> & caps,const std::vector<Rate> & floors,bool inArrears,Real redemption,const Date & issueDate,const Date & stubDate,DateGeneration::Rule rule,bool endOfMonth)101 FloatingCatBond::FloatingCatBond(Natural settlementDays, 102 Real faceAmount, 103 const Date& startDate, 104 const Date& maturityDate, 105 Frequency couponFrequency, 106 const Calendar& calendar, 107 const ext::shared_ptr<IborIndex>& iborIndex, 108 const DayCounter& accrualDayCounter, 109 const ext::shared_ptr<NotionalRisk>& notionalRisk, 110 BusinessDayConvention accrualConvention, 111 BusinessDayConvention paymentConvention, 112 Natural fixingDays, 113 const std::vector<Real>& gearings, 114 const std::vector<Spread>& spreads, 115 const std::vector<Rate>& caps, 116 const std::vector<Rate>& floors, 117 bool inArrears, 118 Real redemption, 119 const Date& issueDate, 120 const Date& stubDate, 121 DateGeneration::Rule rule, 122 bool endOfMonth) 123 : CatBond(settlementDays, calendar, issueDate, notionalRisk) { 124 125 maturityDate_ = maturityDate; 126 127 Date firstDate, nextToLastDate; 128 switch (rule) { 129 case DateGeneration::Backward: 130 firstDate = Date(); 131 nextToLastDate = stubDate; 132 break; 133 case DateGeneration::Forward: 134 firstDate = stubDate; 135 nextToLastDate = Date(); 136 break; 137 case DateGeneration::Zero: 138 case DateGeneration::ThirdWednesday: 139 case DateGeneration::Twentieth: 140 case DateGeneration::TwentiethIMM: 141 QL_FAIL("stub date (" << stubDate << ") not allowed with " << 142 rule << " DateGeneration::Rule"); 143 default: 144 QL_FAIL("unknown DateGeneration::Rule (" << Integer(rule) << ")"); 145 } 146 147 Schedule schedule(startDate, maturityDate_, Period(couponFrequency), 148 calendar_, accrualConvention, accrualConvention, 149 rule, endOfMonth, 150 firstDate, nextToLastDate); 151 152 cashflows_ = IborLeg(schedule, iborIndex) 153 .withNotionals(faceAmount) 154 .withPaymentDayCounter(accrualDayCounter) 155 .withPaymentAdjustment(paymentConvention) 156 .withFixingDays(fixingDays) 157 .withGearings(gearings) 158 .withSpreads(spreads) 159 .withCaps(caps) 160 .withFloors(floors) 161 .inArrears(inArrears); 162 163 addRedemptionsToCashflows(std::vector<Real>(1, redemption)); 164 165 QL_ENSURE(!cashflows().empty(), "bond with no cashflows!"); 166 QL_ENSURE(redemptions_.size() == 1, "multiple redemptions created"); 167 168 registerWith(iborIndex); 169 } 170 171 } 172