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

source code of quantlib/ql/experimental/catbonds/catbond.cpp