1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2004 Jeff Yu
5 Copyright (C) 2004 M-Dimension Consulting Inc.
6 Copyright (C) 2005, 2006, 2007, 2008 StatPro Italia srl
7 Copyright (C) 2007, 2008, 2009 Ferdinando Ametrano
8 Copyright (C) 2007 Chiara Fornarola
9 Copyright (C) 2008 Simon Ibbotson
10
11 This file is part of QuantLib, a free-software/open-source library
12 for financial quantitative analysts and developers - http://quantlib.org/
13
14 QuantLib is free software: you can redistribute it and/or modify it
15 under the terms of the QuantLib license. You should have received a
16 copy of the license along with this program; if not, please email
17 <quantlib-dev@lists.sf.net>. The license is also available online at
18 <http://quantlib.org/license.shtml>.
19
20 This program is distributed in the hope that it will be useful, but WITHOUT
21 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22 FOR A PARTICULAR PURPOSE. See the license for more details.
23*/
24
25/*! \file bond.hpp
26 \brief concrete bond class
27*/
28
29#ifndef quantlib_bond_hpp
30#define quantlib_bond_hpp
31
32#include <ql/instrument.hpp>
33
34#include <ql/time/calendar.hpp>
35#include <ql/cashflow.hpp>
36#include <ql/compounding.hpp>
37
38#include <vector>
39
40namespace QuantLib {
41
42 class DayCounter;
43
44 //! Base bond class
45 /*! Derived classes must fill the uninitialized data members.
46
47 \warning Most methods assume that the cash flows are stored
48 sorted by date, the redemption(s) being after any
49 cash flow at the same date. In particular, if there's
50 one single redemption, it must be the last cash flow,
51
52 \ingroup instruments
53
54 \test
55 - price/yield calculations are cross-checked for consistency.
56 - price/yield calculations are checked against known good
57 values.
58 */
59 class Bond : public Instrument {
60 public:
61 //! Bond price information
62 class Price {
63 public:
64 enum Type { Dirty, Clean };
65 Price() : amount_(Null<Real>()) {}
66 Price(Real amount, Type type) : amount_(amount), type_(type) {}
67 Real amount() const {
68 QL_REQUIRE(amount_ != Null<Real>(), "no amount given");
69 return amount_;
70 }
71 Type type() const { return type_; }
72 private:
73 Real amount_;
74 Type type_;
75 };
76
77 //! constructor for amortizing or non-amortizing bonds.
78 /*! Redemptions and maturity are calculated from the coupon
79 data, if available. Therefore, redemptions must not be
80 included in the passed cash flows.
81 */
82 Bond(Natural settlementDays,
83 Calendar calendar,
84 const Date& issueDate = Date(),
85 const Leg& coupons = Leg());
86
87 //! old constructor for non amortizing bonds.
88 /*! \warning The last passed cash flow must be the bond
89 redemption. No other cash flow can have a date
90 later than the redemption date.
91 */
92 Bond(Natural settlementDays,
93 Calendar calendar,
94 Real faceAmount,
95 const Date& maturityDate,
96 const Date& issueDate = Date(),
97 const Leg& cashflows = Leg());
98
99 class arguments;
100 class results;
101 class engine;
102
103 //! \name Instrument interface
104 //@{
105 bool isExpired() const override;
106 //@}
107 //! \name Observable interface
108 //@{
109 void deepUpdate() override;
110 //@}
111 //! \name Inspectors
112 //@{
113 Natural settlementDays() const;
114 const Calendar& calendar() const;
115
116 const std::vector<Real>& notionals() const;
117 virtual Real notional(Date d = Date()) const;
118
119 /*! \note returns all the cashflows, including the redemptions. */
120 const Leg& cashflows() const;
121 /*! returns just the redemption flows (not interest payments) */
122 const Leg& redemptions() const;
123 /*! returns the redemption, if only one is defined */
124 const ext::shared_ptr<CashFlow>& redemption() const;
125
126 Date startDate() const;
127 Date maturityDate() const;
128 Date issueDate() const;
129
130 bool isTradable(Date d = Date()) const;
131 Date settlementDate(Date d = Date()) const;
132 //@}
133
134 //! \name Calculations
135 //@{
136
137 //! theoretical clean price
138 /*! The default bond settlement is used for calculation.
139
140 \warning the theoretical price calculated from a flat term
141 structure might differ slightly from the price
142 calculated from the corresponding yield by means
143 of the other overload of this function. If the
144 price from a constant yield is desired, it is
145 advisable to use such other overload.
146 */
147 Real cleanPrice() const;
148
149 //! theoretical dirty price
150 /*! The default bond settlement is used for calculation.
151
152 \warning the theoretical price calculated from a flat term
153 structure might differ slightly from the price
154 calculated from the corresponding yield by means
155 of the other overload of this function. If the
156 price from a constant yield is desired, it is
157 advisable to use such other overload.
158 */
159 Real dirtyPrice() const;
160
161 //! theoretical settlement value
162 /*! The default bond settlement date is used for calculation. */
163 Real settlementValue() const;
164
165 //! theoretical bond yield
166 /*! The default bond settlement and theoretical price are used
167 for calculation.
168 */
169 Rate yield(const DayCounter& dc,
170 Compounding comp,
171 Frequency freq,
172 Real accuracy = 1.0e-8,
173 Size maxEvaluations = 100,
174 Real guess = 0.05,
175 Bond::Price::Type priceType = Bond::Price::Clean) const;
176
177 //! clean price given a yield and settlement date
178 /*! The default bond settlement is used if no date is given. */
179 Real cleanPrice(Rate yield,
180 const DayCounter& dc,
181 Compounding comp,
182 Frequency freq,
183 Date settlementDate = Date()) const;
184
185 //! dirty price given a yield and settlement date
186 /*! The default bond settlement is used if no date is given. */
187 Real dirtyPrice(Rate yield,
188 const DayCounter& dc,
189 Compounding comp,
190 Frequency freq,
191 Date settlementDate = Date()) const;
192
193 //! settlement value as a function of the clean price
194 /*! The default bond settlement date is used for calculation. */
195 Real settlementValue(Real cleanPrice) const;
196
197 //! yield given a (clean) price and settlement date
198 /*! The default bond settlement is used if no date is given. */
199 Rate yield(Real cleanPrice,
200 const DayCounter& dc,
201 Compounding comp,
202 Frequency freq,
203 Date settlementDate = Date(),
204 Real accuracy = 1.0e-8,
205 Size maxEvaluations = 100,
206 Real guess = 0.05,
207 Bond::Price::Type priceType = Bond::Price::Clean) const;
208
209 //! accrued amount at a given date
210 /*! The default bond settlement is used if no date is given. */
211 virtual Real accruedAmount(Date d = Date()) const;
212 //@}
213
214 /*! Expected next coupon: depending on (the bond and) the given date
215 the coupon can be historic, deterministic or expected in a
216 stochastic sense. When the bond settlement date is used the coupon
217 is the already-fixed not-yet-paid one.
218
219 The current bond settlement is used if no date is given.
220 */
221 virtual Rate nextCouponRate(Date d = Date()) const;
222
223 //! Previous coupon already paid at a given date
224 /*! Expected previous coupon: depending on (the bond and) the given
225 date the coupon can be historic, deterministic or expected in a
226 stochastic sense. When the bond settlement date is used the coupon
227 is the last paid one.
228
229 The current bond settlement is used if no date is given.
230 */
231 Rate previousCouponRate(Date d = Date()) const;
232
233 Date nextCashFlowDate(Date d = Date()) const;
234 Date previousCashFlowDate(Date d = Date()) const;
235
236 protected:
237 void setupExpired() const override;
238 void setupArguments(PricingEngine::arguments*) const override;
239 void fetchResults(const PricingEngine::results*) const override;
240
241 /*! This method can be called by derived classes in order to
242 build redemption payments from the existing cash flows.
243 It must be called after setting up the cashflows_ vector
244 and will fill the notionalSchedule_, notionals_, and
245 redemptions_ data members.
246
247 If given, the elements of the redemptions vector will
248 multiply the amount of the redemption cash flow. The
249 elements will be taken in base 100, i.e., a redemption
250 equal to 100 does not modify the amount.
251
252 \pre The cashflows_ vector must contain at least one
253 coupon and must be sorted by date.
254 */
255 void addRedemptionsToCashflows(const std::vector<Real>& redemptions
256 = std::vector<Real>());
257
258 /*! This method can be called by derived classes in order to
259 build a bond with a single redemption payment. It will
260 fill the notionalSchedule_, notionals_, and redemptions_
261 data members.
262 */
263 void setSingleRedemption(Real notional,
264 Real redemption,
265 const Date& date);
266
267 /*! This method can be called by derived classes in order to
268 build a bond with a single redemption payment. It will
269 fill the notionalSchedule_, notionals_, and redemptions_
270 data members.
271 */
272 void setSingleRedemption(Real notional,
273 const ext::shared_ptr<CashFlow>& redemption);
274
275 /*! used internally to collect notional information from the
276 coupons. It should not be called by derived classes,
277 unless they already provide redemption cash flows (in
278 which case they must set up the redemptions_ data member
279 independently). It will fill the notionalSchedule_ and
280 notionals_ data members.
281 */
282 void calculateNotionalsFromCashflows();
283
284 Natural settlementDays_;
285 Calendar calendar_;
286 std::vector<Date> notionalSchedule_;
287 std::vector<Real> notionals_;
288 Leg cashflows_; // all cashflows
289 Leg redemptions_; // the redemptions
290
291 Date maturityDate_, issueDate_;
292 mutable Real settlementValue_;
293 };
294
295 class Bond::arguments : public PricingEngine::arguments {
296 public:
297 Date settlementDate;
298 Leg cashflows;
299 Calendar calendar;
300 void validate() const override;
301 };
302
303 class Bond::results : public Instrument::results {
304 public:
305 Real settlementValue;
306 void reset() override {
307 settlementValue = Null<Real>();
308 Instrument::results::reset();
309 }
310 };
311
312 class Bond::engine : public GenericEngine<Bond::arguments,
313 Bond::results> {};
314
315
316 // inline definitions
317
318 inline Natural Bond::settlementDays() const {
319 return settlementDays_;
320 }
321
322 inline const Calendar& Bond::calendar() const {
323 return calendar_;
324 }
325
326 inline const std::vector<Real>& Bond::notionals() const {
327 return notionals_;
328 }
329
330 inline const Leg& Bond::cashflows() const {
331 return cashflows_;
332 }
333
334 inline const Leg& Bond::redemptions() const {
335 return redemptions_;
336 }
337
338 inline Date Bond::issueDate() const {
339 return issueDate_;
340 }
341
342}
343
344#endif
345

source code of quantlib/ql/instruments/bond.hpp