/src/quantlib/ql/pricingengines/bond/bondfunctions.hpp
Line | Count | Source |
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 | | <https://www.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 | | \note Prices are assumed to be a percentage of par (per 100). For bonds |
55 | | with a face value other than 100 (e.g., 25), any price input (like in |
56 | | zSpread or yield calculations) must be provided per 100: |
57 | | `quote = cash price * 100 / face`. Returned prices are also per 100. |
58 | | */ |
59 | | struct BondFunctions { |
60 | | //! \name Date inspectors |
61 | | //@{ |
62 | | static Date startDate(const Bond& bond); |
63 | | static Date maturityDate(const Bond& bond); |
64 | | static bool isTradable(const Bond& bond, |
65 | | Date settlementDate = Date()); |
66 | | //@} |
67 | | |
68 | | //! \name CashFlow inspectors |
69 | | //@{ |
70 | | static Leg::const_reverse_iterator |
71 | | previousCashFlow(const Bond& bond, |
72 | | Date refDate = Date()); |
73 | | static Leg::const_iterator nextCashFlow(const Bond& bond, |
74 | | Date refDate = Date()); |
75 | | static Date previousCashFlowDate(const Bond& bond, |
76 | | Date refDate = Date()); |
77 | | static Date nextCashFlowDate(const Bond& bond, |
78 | | Date refDate = Date()); |
79 | | static Real previousCashFlowAmount(const Bond& bond, |
80 | | Date refDate = Date()); |
81 | | static Real nextCashFlowAmount(const Bond& bond, |
82 | | Date refDate = Date()); |
83 | | //@} |
84 | | |
85 | | //! \name Coupon inspectors |
86 | | //@{ |
87 | | static Rate previousCouponRate(const Bond& bond, |
88 | | Date settlementDate = Date()); |
89 | | static Rate nextCouponRate(const Bond& bond, |
90 | | Date settlementDate = Date()); |
91 | | static Date accrualStartDate(const Bond& bond, |
92 | | Date settlementDate = Date()); |
93 | | static Date accrualEndDate(const Bond& bond, |
94 | | Date settlementDate = Date()); |
95 | | static Date referencePeriodStart(const Bond& bond, |
96 | | Date settlementDate = Date()); |
97 | | static Date referencePeriodEnd(const Bond& bond, |
98 | | Date settlementDate = Date()); |
99 | | static Time accrualPeriod(const Bond& bond, |
100 | | Date settlementDate = Date()); |
101 | | static Date::serial_type accrualDays(const Bond& bond, |
102 | | Date settlementDate = Date()); |
103 | | static Time accruedPeriod(const Bond& bond, |
104 | | Date settlementDate = Date()); |
105 | | static Date::serial_type accruedDays(const Bond& bond, |
106 | | Date settlementDate = Date()); |
107 | | static Real accruedAmount(const Bond& bond, |
108 | | Date settlementDate = Date()); |
109 | | //@} |
110 | | |
111 | | //! \name YieldTermStructure functions |
112 | | //@{ |
113 | | static Real cleanPrice(const Bond& bond, |
114 | | const YieldTermStructure& discountCurve, |
115 | | Date settlementDate = Date()); |
116 | | static Real dirtyPrice(const Bond& bond, |
117 | | const YieldTermStructure& discountCurve, |
118 | | Date settlementDate = Date()); |
119 | | static Real bps(const Bond& bond, |
120 | | const YieldTermStructure& discountCurve, |
121 | | Date settlementDate = Date()); |
122 | | |
123 | | static Rate atmRate(const Bond& bond, |
124 | | const YieldTermStructure& discountCurve, |
125 | | Date settlementDate = Date(), |
126 | | Bond::Price price = {}); |
127 | | //@} |
128 | | |
129 | | //! \name Yield (a.k.a. Internal Rate of Return, i.e. IRR) functions |
130 | | //@{ |
131 | | static Real cleanPrice(const Bond& bond, |
132 | | const InterestRate& yield, |
133 | | Date settlementDate = Date()); |
134 | | static Real cleanPrice(const Bond& bond, |
135 | | Rate yield, |
136 | | const DayCounter& dayCounter, |
137 | | Compounding compounding, |
138 | | Frequency frequency, |
139 | | Date settlementDate = Date()); |
140 | | static Real dirtyPrice(const Bond& bond, |
141 | | const InterestRate& yield, |
142 | | Date settlementDate = Date()); |
143 | | static Real dirtyPrice(const Bond& bond, |
144 | | Rate yield, |
145 | | const DayCounter& dayCounter, |
146 | | Compounding compounding, |
147 | | Frequency frequency, |
148 | | Date settlementDate = Date()); |
149 | | static Real bps(const Bond& bond, |
150 | | const InterestRate& yield, |
151 | | Date settlementDate = Date()); |
152 | | static Real bps(const Bond& bond, |
153 | | Rate yield, |
154 | | const DayCounter& dayCounter, |
155 | | Compounding compounding, |
156 | | Frequency frequency, |
157 | | Date settlementDate = Date()); |
158 | | static Rate yield(const Bond& bond, |
159 | | Bond::Price price, |
160 | | const DayCounter& dayCounter, |
161 | | Compounding compounding, |
162 | | Frequency frequency, |
163 | | Date settlementDate = Date(), |
164 | | Real accuracy = 1.0e-10, |
165 | | Size maxIterations = 100, |
166 | | Rate guess = 0.05); |
167 | | template <typename Solver> |
168 | | static Rate yield(const Solver& solver, |
169 | | const Bond& bond, |
170 | | Bond::Price price, |
171 | | const DayCounter& dayCounter, |
172 | | Compounding compounding, |
173 | | Frequency frequency, |
174 | | Date settlementDate = Date(), |
175 | | Real accuracy = 1.0e-10, |
176 | 0 | Rate guess = 0.05) { |
177 | 0 | if (settlementDate == Date()) |
178 | 0 | settlementDate = bond.settlementDate(); |
179 | |
|
180 | 0 | QL_REQUIRE(BondFunctions::isTradable(bond, settlementDate), |
181 | 0 | "non tradable at " << settlementDate << |
182 | 0 | " (maturity being " << bond.maturityDate() << ")"); |
183 | | |
184 | 0 | Real amount = price.amount(); |
185 | |
|
186 | 0 | if (price.type() == Bond::Price::Clean) |
187 | 0 | amount += bond.accruedAmount(settlementDate); |
188 | |
|
189 | 0 | amount /= 100.0 / bond.notional(settlementDate); |
190 | |
|
191 | 0 | return CashFlows::yield<Solver>(solver, bond.cashflows(), amount, dayCounter, |
192 | 0 | compounding, |
193 | 0 | frequency, false, settlementDate, |
194 | 0 | settlementDate, accuracy, guess); |
195 | 0 | } |
196 | | static Time duration(const Bond& bond, |
197 | | const InterestRate& yield, |
198 | | Duration::Type type = Duration::Modified, |
199 | | Date settlementDate = Date() ); |
200 | | static Time duration(const Bond& bond, |
201 | | Rate yield, |
202 | | const DayCounter& dayCounter, |
203 | | Compounding compounding, |
204 | | Frequency frequency, |
205 | | Duration::Type type = Duration::Modified, |
206 | | Date settlementDate = Date() ); |
207 | | static Real convexity(const Bond& bond, |
208 | | const InterestRate& yield, |
209 | | Date settlementDate = Date()); |
210 | | static Real convexity(const Bond& bond, |
211 | | Rate yield, |
212 | | const DayCounter& dayCounter, |
213 | | Compounding compounding, |
214 | | Frequency frequency, |
215 | | Date settlementDate = Date()); |
216 | | static Real basisPointValue(const Bond& bond, |
217 | | const InterestRate& yield, |
218 | | Date settlementDate = Date()); |
219 | | static Real basisPointValue(const Bond& bond, |
220 | | Rate yield, |
221 | | const DayCounter& dayCounter, |
222 | | Compounding compounding, |
223 | | Frequency frequency, |
224 | | Date settlementDate = Date()); |
225 | | static Real yieldValueBasisPoint(const Bond& bond, |
226 | | const InterestRate& yield, |
227 | | Date settlementDate = Date()); |
228 | | static Real yieldValueBasisPoint(const Bond& bond, |
229 | | Rate yield, |
230 | | const DayCounter& dayCounter, |
231 | | Compounding compounding, |
232 | | Frequency frequency, |
233 | | Date settlementDate = Date()); |
234 | | //@} |
235 | | |
236 | | //! \name Z-spread functions |
237 | | //@{ |
238 | | static Real cleanPrice(const Bond& bond, |
239 | | const ext::shared_ptr<YieldTermStructure>& discount, |
240 | | Spread zSpread, |
241 | | Compounding compounding, |
242 | | Frequency frequency, |
243 | | Date settlementDate = Date()); |
244 | | /*! \deprecated Use the overload without a day counter. |
245 | | Deprecated in version 1.42. |
246 | | */ |
247 | | [[deprecated("Use the overload without a day counter")]] |
248 | | static Real cleanPrice(const Bond& bond, |
249 | | const ext::shared_ptr<YieldTermStructure>& discount, |
250 | | Spread zSpread, |
251 | | const DayCounter& dayCounter, |
252 | | Compounding compounding, |
253 | | Frequency frequency, |
254 | | Date settlementDate = Date()); |
255 | | static Real dirtyPrice(const Bond& bond, |
256 | | const ext::shared_ptr<YieldTermStructure>& discount, |
257 | | Spread zSpread, |
258 | | Compounding compounding, |
259 | | Frequency frequency, |
260 | | Date settlementDate = Date()); |
261 | | /*! \deprecated Use the overload without a day counter. |
262 | | Deprecated in version 1.42. |
263 | | */ |
264 | | [[deprecated("Use the overload without a day counter")]] |
265 | | static Real dirtyPrice(const Bond& bond, |
266 | | const ext::shared_ptr<YieldTermStructure>& discount, |
267 | | Spread zSpread, |
268 | | const DayCounter& dayCounter, |
269 | | Compounding compounding, |
270 | | Frequency frequency, |
271 | | Date settlementDate = Date()); |
272 | | static Spread zSpread(const Bond& bond, |
273 | | Bond::Price price, |
274 | | const ext::shared_ptr<YieldTermStructure>&, |
275 | | Compounding compounding, |
276 | | Frequency frequency, |
277 | | Date settlementDate = Date(), |
278 | | Real accuracy = 1.0e-10, |
279 | | Size maxIterations = 100, |
280 | | Rate guess = 0.0); |
281 | | /*! \deprecated Use the overload without a day counter. |
282 | | Deprecated in version 1.42. |
283 | | */ |
284 | | [[deprecated("Use the overload without a day counter")]] |
285 | | static Spread zSpread(const Bond& bond, |
286 | | Bond::Price price, |
287 | | const ext::shared_ptr<YieldTermStructure>&, |
288 | | const DayCounter& dayCounter, |
289 | | Compounding compounding, |
290 | | Frequency frequency, |
291 | | Date settlementDate = Date(), |
292 | | Real accuracy = 1.0e-10, |
293 | | Size maxIterations = 100, |
294 | | Rate guess = 0.0); |
295 | | //@} |
296 | | |
297 | | }; |
298 | | |
299 | | } |
300 | | |
301 | | #endif |