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