QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
convertiblebonds.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2005, 2006 Theo Boafo
5 Copyright (C) 2006, 2007 StatPro Italia srl
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21#include <ql/cashflows/couponpricer.hpp>
22#include <ql/cashflows/fixedratecoupon.hpp>
23#include <ql/cashflows/iborcoupon.hpp>
24#include <ql/cashflows/simplecashflow.hpp>
25#include <ql/exercise.hpp>
26#include <ql/instruments/bonds/convertiblebonds.hpp>
27#include <ql/utilities/null_deleter.hpp>
28#include <utility>
29
30namespace QuantLib {
31
32 ConvertibleBond::ConvertibleBond(ext::shared_ptr<Exercise> exercise,
33 Real conversionRatio,
34 const CallabilitySchedule& callability,
35 const Date& issueDate,
36 Natural settlementDays,
37 const Schedule& schedule,
38 Real redemption)
39 : Bond(settlementDays, schedule.calendar(), issueDate), exercise_(std::move(exercise)),
40 conversionRatio_(conversionRatio), callability_(callability), redemption_(redemption) {
41
42 maturityDate_ = schedule.endDate();
43
44 if (!callability.empty()) {
45 QL_REQUIRE(callability.back()->date() <= maturityDate_,
46 "last callability date (" << callability.back()->date()
47 << ") later than maturity (" << maturityDate_
48 << ")");
49 }
50 }
51
52
53 ConvertibleZeroCouponBond::ConvertibleZeroCouponBond(const ext::shared_ptr<Exercise>& exercise,
54 Real conversionRatio,
55 const CallabilitySchedule& callability,
56 const Date& issueDate,
57 Natural settlementDays,
58 const DayCounter& dayCounter,
59 const Schedule& schedule,
60 Real redemption)
61 : ConvertibleBond(exercise,
62 conversionRatio,
63 callability,
64 issueDate,
65 settlementDays,
66 schedule,
67 redemption) {
68
69 cashflows_ = Leg();
70
71 // !!! notional forcibly set to 100
73 }
74
75
77 const ext::shared_ptr<Exercise>& exercise,
78 Real conversionRatio,
79 const CallabilitySchedule& callability,
80 const Date& issueDate,
81 Natural settlementDays,
82 const std::vector<Rate>& coupons,
83 const DayCounter& dayCounter,
84 const Schedule& schedule,
85 Real redemption,
86 const Period& exCouponPeriod,
87 const Calendar& exCouponCalendar,
88 const BusinessDayConvention exCouponConvention,
89 bool exCouponEndOfMonth)
90 : ConvertibleBond(exercise,
91 conversionRatio,
92 callability,
93 issueDate,
94 settlementDays,
95 schedule,
96 redemption) {
97
98 // !!! notional forcibly set to 100
99 cashflows_ = FixedRateLeg(schedule)
100 .withNotionals(100.0)
101 .withCouponRates(coupons, dayCounter)
103 .withExCouponPeriod(exCouponPeriod, exCouponCalendar, exCouponConvention,
104 exCouponEndOfMonth);
105
106 addRedemptionsToCashflows(std::vector<Real>(1, redemption));
107
108 QL_ENSURE(redemptions_.size() == 1, "multiple redemptions created");
109 }
110
111
113 const ext::shared_ptr<Exercise>& exercise,
114 Real conversionRatio,
115 const CallabilitySchedule& callability,
116 const Date& issueDate,
117 Natural settlementDays,
118 const ext::shared_ptr<IborIndex>& index,
119 Natural fixingDays,
120 const std::vector<Spread>& spreads,
121 const DayCounter& dayCounter,
122 const Schedule& schedule,
123 Real redemption,
124 const Period& exCouponPeriod,
125 const Calendar& exCouponCalendar,
126 const BusinessDayConvention exCouponConvention,
127 bool exCouponEndOfMonth)
128 : ConvertibleBond(exercise,
129 conversionRatio,
130 callability,
131 issueDate,
132 settlementDays,
133 schedule,
134 redemption) {
135
136 // !!! notional forcibly set to 100
137 cashflows_ = IborLeg(schedule, index)
138 .withPaymentDayCounter(dayCounter)
139 .withNotionals(100.0)
141 .withFixingDays(fixingDays)
142 .withSpreads(spreads)
143 .withExCouponPeriod(exCouponPeriod, exCouponCalendar, exCouponConvention,
144 exCouponEndOfMonth);
145
146 addRedemptionsToCashflows(std::vector<Real>(1, redemption));
147
148 QL_ENSURE(redemptions_.size() == 1, "multiple redemptions created");
149
150 registerWith(index);
151 }
152
154 auto* args = dynamic_cast<ConvertibleBond::arguments*>(arguments);
155 QL_REQUIRE(args != nullptr, "wrong argument type");
156
157 args->exercise = exercise_;
158 args->conversionRatio = conversionRatio_;
159
160 Date settlement = settlementDate();
161
162 Size n = callability_.size();
163 args->callabilityDates.clear();
164 args->callabilityTypes.clear();
165 args->callabilityPrices.clear();
166 args->callabilityTriggers.clear();
167 args->callabilityDates.reserve(n);
168 args->callabilityTypes.reserve(n);
169 args->callabilityPrices.reserve(n);
170 args->callabilityTriggers.reserve(n);
171 for (Size i = 0; i < n; i++) {
172 if (!callability_[i]->hasOccurred(settlement, false)) {
173 args->callabilityTypes.push_back(callability_[i]->type());
174 args->callabilityDates.push_back(callability_[i]->date());
175 args->callabilityPrices.push_back(callability_[i]->price().amount());
176 if (callability_[i]->price().type() == Bond::Price::Clean)
177 args->callabilityPrices.back() +=
178 accruedAmount(callability_[i]->date());
179 ext::shared_ptr<SoftCallability> softCall =
180 ext::dynamic_pointer_cast<SoftCallability>(callability_[i]);
181 if (softCall != nullptr)
182 args->callabilityTriggers.push_back(softCall->trigger());
183 else
184 args->callabilityTriggers.push_back(Null<Real>());
185 }
186 }
187
188 args->cashflows = cashflows();
189
190 args->issueDate = issueDate_;
191 args->settlementDate = settlement;
192 args->settlementDays = settlementDays_;
193 args->redemption = redemption_;
194 }
195
196
198
199 QL_REQUIRE(exercise, "no exercise given");
200 QL_REQUIRE(conversionRatio != Null<Real>(), "null conversion ratio");
201 QL_REQUIRE(conversionRatio > 0.0,
202 "positive conversion ratio required: " << conversionRatio << " not allowed");
203
204 QL_REQUIRE(redemption != Null<Real>(), "null redemption");
205 QL_REQUIRE(redemption >= 0.0,
206 "positive redemption required: " << redemption << " not allowed");
207
208 QL_REQUIRE(settlementDate != Date(), "null settlement date");
209
210 QL_REQUIRE(settlementDays != Null<Natural>(), "null settlement days");
211
212 QL_REQUIRE(callabilityDates.size() == callabilityTypes.size(),
213 "different number of callability dates and types");
214 QL_REQUIRE(callabilityDates.size() == callabilityPrices.size(),
215 "different number of callability dates and prices");
216 QL_REQUIRE(callabilityDates.size() == callabilityTriggers.size(),
217 "different number of callability dates and triggers");
218
219 QL_REQUIRE(!cashflows.empty(), "no cashflows given");
220 }
221
222}
Base bond class.
Definition: bond.hpp:59
Leg redemptions_
Definition: bond.hpp:289
void addRedemptionsToCashflows(const std::vector< Real > &redemptions=std::vector< Real >())
Definition: bond.cpp:304
virtual Real accruedAmount(Date d=Date()) const
accrued amount at a given date
Definition: bond.cpp:256
const Leg & cashflows() const
Definition: bond.hpp:330
Natural settlementDays_
Definition: bond.hpp:284
Leg cashflows_
Definition: bond.hpp:288
const ext::shared_ptr< CashFlow > & redemption() const
Definition: bond.cpp:140
void setSingleRedemption(Real notional, Real redemption, const Date &date)
Definition: bond.cpp:331
Date issueDate_
Definition: bond.hpp:291
Date maturityDate_
Definition: bond.hpp:291
Date settlementDate(Date d=Date()) const
Definition: bond.cpp:161
calendar class
Definition: calendar.hpp:61
ext::shared_ptr< Exercise > exercise
std::vector< Callability::Type > callabilityTypes
base class for convertible bonds
void setupArguments(PricingEngine::arguments *) const override
const CallabilitySchedule & callability() const
ConvertibleBond(ext::shared_ptr< Exercise > exercise, Real conversionRatio, const CallabilitySchedule &callability, const Date &issueDate, Natural settlementDays, const Schedule &schedule, Real redemption)
ext::shared_ptr< Exercise > exercise_
CallabilitySchedule callability_
ConvertibleFixedCouponBond(const ext::shared_ptr< Exercise > &exercise, Real conversionRatio, const CallabilitySchedule &callability, const Date &issueDate, Natural settlementDays, const std::vector< Rate > &coupons, const DayCounter &dayCounter, const Schedule &schedule, Real redemption=100, const Period &exCouponPeriod=Period(), const Calendar &exCouponCalendar=Calendar(), BusinessDayConvention exCouponConvention=Unadjusted, bool exCouponEndOfMonth=false)
ConvertibleFloatingRateBond(const ext::shared_ptr< Exercise > &exercise, Real conversionRatio, const CallabilitySchedule &callability, const Date &issueDate, Natural settlementDays, const ext::shared_ptr< IborIndex > &index, Natural fixingDays, const std::vector< Spread > &spreads, const DayCounter &dayCounter, const Schedule &schedule, Real redemption=100, const Period &exCouponPeriod=Period(), const Calendar &exCouponCalendar=Calendar(), BusinessDayConvention exCouponConvention=Unadjusted, bool exCouponEndOfMonth=false)
ConvertibleZeroCouponBond(const ext::shared_ptr< Exercise > &exercise, Real conversionRatio, const CallabilitySchedule &callability, const Date &issueDate, Natural settlementDays, const DayCounter &dayCounter, const Schedule &schedule, Real redemption=100)
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
helper class building a sequence of fixed rate coupons
FixedRateLeg & withNotionals(Real)
FixedRateLeg & withPaymentAdjustment(BusinessDayConvention)
FixedRateLeg & withCouponRates(Rate, const DayCounter &paymentDayCounter, Compounding comp=Simple, Frequency freq=Annual)
FixedRateLeg & withExCouponPeriod(const Period &, const Calendar &, BusinessDayConvention, bool endOfMonth=false)
helper class building a sequence of capped/floored ibor-rate coupons
Definition: iborcoupon.hpp:133
IborLeg & withSpreads(Spread spread)
Definition: iborcoupon.cpp:208
IborLeg & withPaymentAdjustment(BusinessDayConvention)
Definition: iborcoupon.cpp:173
IborLeg & withPaymentDayCounter(const DayCounter &)
Definition: iborcoupon.cpp:168
IborLeg & withNotionals(Real notional)
Definition: iborcoupon.cpp:158
IborLeg & withExCouponPeriod(const Period &, const Calendar &, BusinessDayConvention, bool endOfMonth=false)
Definition: iborcoupon.cpp:248
IborLeg & withFixingDays(Natural fixingDays)
Definition: iborcoupon.cpp:188
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 Date & endDate() const
Definition: schedule.hpp:184
BusinessDayConvention businessDayConvention() const
Definition: schedule.hpp:196
BusinessDayConvention
Business Day conventions.
QL_REAL Real
real number
Definition: types.hpp:50
unsigned QL_INTEGER Natural
positive integer
Definition: types.hpp:43
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
std::vector< ext::shared_ptr< Callability > > CallabilitySchedule
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.
Definition: cashflow.hpp:78
STL namespace.