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 
40 namespace 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 };
Price()65             Price() : amount_(Null<Real>()) {}
Price(Real amount,Type type)66             Price(Real amount, Type type) : amount_(amount), type_(type) {}
amount() const67             Real amount() const {
68                 QL_REQUIRE(amount_ != Null<Real>(), "no amount given");
69                 return amount_;
70             }
type() const71             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              const 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              const 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;
106         //@}
107         //! \name Observable interface
108         //@{
109         void deepUpdate();
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;
238         void setupArguments(PricingEngine::arguments*) const;
239         void fetchResults(const PricingEngine::results*) const;
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;
301     };
302 
303     class Bond::results : public Instrument::results {
304       public:
305         Real settlementValue;
reset()306         void reset() {
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 
settlementDays() const318     inline Natural Bond::settlementDays() const {
319         return settlementDays_;
320     }
321 
calendar() const322     inline const Calendar& Bond::calendar() const {
323         return calendar_;
324     }
325 
notionals() const326     inline const std::vector<Real>& Bond::notionals() const {
327         return notionals_;
328     }
329 
cashflows() const330     inline const Leg& Bond::cashflows() const {
331         return cashflows_;
332     }
333 
redemptions() const334     inline const Leg& Bond::redemptions() const {
335         return redemptions_;
336     }
337 
issueDate() const338     inline Date Bond::issueDate() const {
339         return issueDate_;
340     }
341 
342 }
343 
344 #endif
345