1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 /*
4  Copyright (C) 2007, 2008, 2009, 2010 Ferdinando Ametrano
5  Copyright (C) 2007 Chiara Fornarola
6  Copyright (C) 2009 StatPro Italia srl
7  Copyright (C) 2009 Nathan Abbott
8 
9  This file is part of QuantLib, a free-software/open-source library
10  for financial quantitative analysts and developers - http://quantlib.org/
11 
12  QuantLib is free software: you can redistribute it and/or modify it
13  under the terms of the QuantLib license.  You should have received a
14  copy of the license along with this program; if not, please email
15  <quantlib-dev@lists.sf.net>. The license is also available online at
16  <http://quantlib.org/license.shtml>.
17 
18  This program is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20  FOR A PARTICULAR PURPOSE.  See the license for more details.
21 */
22 
23 /*! \file bondfunctions.hpp
24     \brief bond functions
25 */
26 
27 #ifndef quantlib_bond_functions_hpp
28 #define quantlib_bond_functions_hpp
29 
30 #include <ql/cashflows/cashflows.hpp>
31 #include <ql/cashflows/duration.hpp>
32 #include <ql/cashflow.hpp>
33 #include <ql/interestrate.hpp>
34 #include <ql/instruments/bond.hpp>
35 #include <ql/shared_ptr.hpp>
36 
37 namespace QuantLib {
38 
39     // forward declarations
40     class Bond;
41     class DayCounter;
42     class YieldTermStructure;
43 
44     //! Bond adapters of CashFlows functions
45     /*! See CashFlows for functions' documentation.
46 
47         These adapters calls into CashFlows functions passing as input the
48         Bond cashflows, the dirty price (i.e. npv) calculated from clean
49         price, the bond settlement date (unless another date is given), zero
50         ex-dividend days, and excluding any cashflow on the settlement date.
51 
52         Prices are always clean, as per market convention.
53     */
54     struct BondFunctions {
55         //! \name Date inspectors
56         //@{
57         static Date startDate(const Bond& bond);
58         static Date maturityDate(const Bond& bond);
59         static bool isTradable(const Bond& bond,
60                                Date settlementDate = Date());
61         //@}
62 
63         //! \name CashFlow inspectors
64         //@{
65         static Leg::const_reverse_iterator
66         previousCashFlow(const Bond& bond,
67                          Date refDate = Date());
68         static Leg::const_iterator nextCashFlow(const Bond& bond,
69                                                 Date refDate = Date());
70         static Date previousCashFlowDate(const Bond& bond,
71                                          Date refDate = Date());
72         static Date nextCashFlowDate(const Bond& bond,
73                                      Date refDate = Date());
74         static Real previousCashFlowAmount(const Bond& bond,
75                                            Date refDate = Date());
76         static Real nextCashFlowAmount(const Bond& bond,
77                                        Date refDate = Date());
78         //@}
79 
80         //! \name Coupon inspectors
81         //@{
82         static Rate previousCouponRate(const Bond& bond,
83                                        Date settlementDate = Date());
84         static Rate nextCouponRate(const Bond& bond,
85                                    Date settlementDate = Date());
86         static Date accrualStartDate(const Bond& bond,
87                                      Date settlementDate = Date());
88         static Date accrualEndDate(const Bond& bond,
89                                    Date settlementDate = Date());
90         static Date referencePeriodStart(const Bond& bond,
91                                          Date settlementDate = Date());
92         static Date referencePeriodEnd(const Bond& bond,
93                                        Date settlementDate = Date());
94         static Time accrualPeriod(const Bond& bond,
95                                   Date settlementDate = Date());
96         static Date::serial_type accrualDays(const Bond& bond,
97                                              Date settlementDate = Date());
98         static Time accruedPeriod(const Bond& bond,
99                                   Date settlementDate = Date());
100         static Date::serial_type accruedDays(const Bond& bond,
101                                              Date settlementDate = Date());
102         static Real accruedAmount(const Bond& bond,
103                                   Date settlementDate = Date());
104         //@}
105 
106         //! \name YieldTermStructure functions
107         //@{
108         static Real cleanPrice(const Bond& bond,
109                                const YieldTermStructure& discountCurve,
110                                Date settlementDate = Date());
111         static Real bps(const Bond& bond,
112                         const YieldTermStructure& discountCurve,
113                         Date settlementDate = Date());
114         static Rate atmRate(const Bond& bond,
115                             const YieldTermStructure& discountCurve,
116                             Date settlementDate = Date(),
117                             Real cleanPrice = Null<Real>());
118         //@}
119 
120         //! \name Yield (a.k.a. Internal Rate of Return, i.e. IRR) functions
121         //@{
122         static Real cleanPrice(const Bond& bond,
123                                const InterestRate& yield,
124                                Date settlementDate = Date());
125         static Real cleanPrice(const Bond& bond,
126                                Rate yield,
127                                const DayCounter& dayCounter,
128                                Compounding compounding,
129                                Frequency frequency,
130                                Date settlementDate = Date());
131         static Real dirtyPrice(const Bond& bond,
132                                const InterestRate& yield,
133                                Date settlementDate = Date());
134         static Real dirtyPrice(const Bond& bond,
135                                Rate yield,
136                                const DayCounter& dayCounter,
137                                Compounding compounding,
138                                Frequency frequency,
139                                Date settlementDate = Date());
140         static Real bps(const Bond& bond,
141                         const InterestRate& yield,
142                         Date settlementDate = Date());
143         static Real bps(const Bond& bond,
144                         Rate yield,
145                         const DayCounter& dayCounter,
146                         Compounding compounding,
147                         Frequency frequency,
148                         Date settlementDate = Date());
149         static Rate yield(const Bond& bond,
150                           Real price,
151                           const DayCounter& dayCounter,
152                           Compounding compounding,
153                           Frequency frequency,
154                           Date settlementDate = Date(),
155                           Real accuracy = 1.0e-10,
156                           Size maxIterations = 100,
157                           Rate guess = 0.05,
158                           Bond::Price::Type priceType = Bond::Price::Clean);
159         template <typename Solver>
yieldQuantLib::BondFunctions160         static Rate yield(const Solver& solver,
161                           const Bond& bond,
162                           Real price,
163                           const DayCounter& dayCounter,
164                           Compounding compounding,
165                           Frequency frequency,
166                           Date settlementDate = Date(),
167                           Real accuracy = 1.0e-10,
168                           Rate guess = 0.05,
169                           Bond::Price::Type priceType = Bond::Price::Clean) {
170             if (settlementDate == Date())
171                 settlementDate = bond.settlementDate();
172 
173             QL_REQUIRE(BondFunctions::isTradable(bond, settlementDate),
174                        "non tradable at " << settlementDate <<
175                        " (maturity being " << bond.maturityDate() << ")");
176 
177             Real dirtyPrice = price;
178 
179             if (priceType == Bond::Price::Clean)
180                 dirtyPrice += bond.accruedAmount(settlementDate);
181 
182             dirtyPrice /= 100.0 / bond.notional(settlementDate);
183 
184             return CashFlows::yield<Solver>(solver, bond.cashflows(),
185                                             dirtyPrice, dayCounter, compounding,
186                                             frequency, false, settlementDate,
187                                             settlementDate, accuracy, guess);
188         }
189         static Time duration(const Bond& bond,
190                              const InterestRate& yield,
191                              Duration::Type type = Duration::Modified,
192                              Date settlementDate = Date() );
193         static Time duration(const Bond& bond,
194                              Rate yield,
195                              const DayCounter& dayCounter,
196                              Compounding compounding,
197                              Frequency frequency,
198                              Duration::Type type = Duration::Modified,
199                              Date settlementDate = Date() );
200         static Real convexity(const Bond& bond,
201                               const InterestRate& yield,
202                               Date settlementDate = Date());
203         static Real convexity(const Bond& bond,
204                               Rate yield,
205                               const DayCounter& dayCounter,
206                               Compounding compounding,
207                               Frequency frequency,
208                               Date settlementDate = Date());
209         static Real basisPointValue(const Bond& bond,
210                                     const InterestRate& yield,
211                                     Date settlementDate = Date());
212         static Real basisPointValue(const Bond& bond,
213                                     Rate yield,
214                                     const DayCounter& dayCounter,
215                                     Compounding compounding,
216                                     Frequency frequency,
217                                     Date settlementDate = Date());
218         static Real yieldValueBasisPoint(const Bond& bond,
219                                          const InterestRate& yield,
220                                          Date settlementDate = Date());
221         static Real yieldValueBasisPoint(const Bond& bond,
222                                          Rate yield,
223                                          const DayCounter& dayCounter,
224                                          Compounding compounding,
225                                          Frequency frequency,
226                                          Date settlementDate = Date());
227         //@}
228 
229         //! \name Z-spread functions
230         //@{
231         static Real cleanPrice(const Bond& bond,
232                                const ext::shared_ptr<YieldTermStructure>& discount,
233                                Spread zSpread,
234                                const DayCounter& dayCounter,
235                                Compounding compounding,
236                                Frequency frequency,
237                                Date settlementDate = Date());
238         static Spread zSpread(const Bond& bond,
239                               Real cleanPrice,
240                               const ext::shared_ptr<YieldTermStructure>&,
241                               const DayCounter& dayCounter,
242                               Compounding compounding,
243                               Frequency frequency,
244                               Date settlementDate = Date(),
245                               Real accuracy = 1.0e-10,
246                               Size maxIterations = 100,
247                               Rate guess = 0.0);
248         //@}
249 
250     };
251 
252 }
253 
254 #endif
255