1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2005, 2006 StatPro Italia srl
5 Copyright (C) 2005 Charles Whitmore
6 Copyright (C) 2007, 2008, 2009, 2010, 2011 Ferdinando Ametrano
7 Copyright (C) 2008 Toyin Akin
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 cashflows.hpp
24 \brief Cash-flow analysis functions
25*/
26
27#ifndef quantlib_cashflows_hpp
28#define quantlib_cashflows_hpp
29
30#include <ql/cashflows/duration.hpp>
31#include <ql/cashflow.hpp>
32#include <ql/interestrate.hpp>
33#include <ql/shared_ptr.hpp>
34
35namespace QuantLib {
36
37 class YieldTermStructure;
38
39 //! %cashflow-analysis functions
40 /*! \todo add tests */
41 class CashFlows {
42 private:
43 class IrrFinder {
44 public:
45 IrrFinder(const Leg& leg,
46 Real npv,
47 DayCounter dayCounter,
48 Compounding comp,
49 Frequency freq,
50 bool includeSettlementDateFlows,
51 Date settlementDate,
52 Date npvDate);
53
54 Real operator()(Rate y) const;
55 Real derivative(Rate y) const;
56 private:
57 void checkSign() const;
58
59 const Leg& leg_;
60 Real npv_;
61 DayCounter dayCounter_;
62 Compounding compounding_;
63 Frequency frequency_;
64 bool includeSettlementDateFlows_;
65 Date settlementDate_, npvDate_;
66 };
67 public:
68 CashFlows() = delete;
69 CashFlows(CashFlows&&) = delete;
70 CashFlows(const CashFlows&) = delete;
71 CashFlows& operator=(CashFlows&&) = delete;
72 CashFlows& operator=(const CashFlows&) = delete;
73 ~CashFlows() = default;
74
75 //! \name Date functions
76 //@{
77 static Date startDate(const Leg& leg);
78 static Date maturityDate(const Leg& leg);
79 static bool isExpired(const Leg& leg,
80 bool includeSettlementDateFlows,
81 Date settlementDate = Date());
82 //@}
83
84 //! \name CashFlow functions
85 //@{
86 //! the last cashflow paying before or at the given date
87 static Leg::const_reverse_iterator
88 previousCashFlow(const Leg& leg,
89 bool includeSettlementDateFlows,
90 Date settlementDate = Date());
91 //! the first cashflow paying after the given date
92 static Leg::const_iterator
93 nextCashFlow(const Leg& leg,
94 bool includeSettlementDateFlows,
95 Date settlementDate = Date());
96 static Date
97 previousCashFlowDate(const Leg& leg,
98 bool includeSettlementDateFlows,
99 Date settlementDate = Date());
100 static Date
101 nextCashFlowDate(const Leg& leg,
102 bool includeSettlementDateFlows,
103 Date settlementDate = Date());
104 static Real
105 previousCashFlowAmount(const Leg& leg,
106 bool includeSettlementDateFlows,
107 Date settlementDate = Date());
108 static Real
109 nextCashFlowAmount(const Leg& leg,
110 bool includeSettlementDateFlows,
111 Date settlementDate = Date());
112 //@}
113
114 //! \name Coupon inspectors
115 //@{
116 static Rate
117 previousCouponRate(const Leg& leg,
118 bool includeSettlementDateFlows,
119 Date settlementDate = Date());
120 static Rate
121 nextCouponRate(const Leg& leg,
122 bool includeSettlementDateFlows,
123 Date settlementDate = Date());
124
125 static Real
126 nominal(const Leg& leg,
127 bool includeSettlementDateFlows,
128 Date settlDate = Date());
129 static Date
130 accrualStartDate(const Leg& leg,
131 bool includeSettlementDateFlows,
132 Date settlDate = Date());
133 static Date
134 accrualEndDate(const Leg& leg,
135 bool includeSettlementDateFlows,
136 Date settlementDate = Date());
137 static Date
138 referencePeriodStart(const Leg& leg,
139 bool includeSettlementDateFlows,
140 Date settlDate = Date());
141 static Date
142 referencePeriodEnd(const Leg& leg,
143 bool includeSettlementDateFlows,
144 Date settlDate = Date());
145 static Time
146 accrualPeriod(const Leg& leg,
147 bool includeSettlementDateFlows,
148 Date settlementDate = Date());
149 static Date::serial_type
150 accrualDays(const Leg& leg,
151 bool includeSettlementDateFlows,
152 Date settlementDate = Date());
153 static Time
154 accruedPeriod(const Leg& leg,
155 bool includeSettlementDateFlows,
156 Date settlementDate = Date());
157 static Date::serial_type
158 accruedDays(const Leg& leg,
159 bool includeSettlementDateFlows,
160 Date settlementDate = Date());
161 static Real
162 accruedAmount(const Leg& leg,
163 bool includeSettlementDateFlows,
164 Date settlementDate = Date());
165 //@}
166
167 //! \name YieldTermStructure functions
168 //@{
169 //! NPV of the cash flows.
170 /*! The NPV is the sum of the cash flows, each discounted
171 according to the given term structure.
172 */
173 static Real npv(const Leg& leg,
174 const YieldTermStructure& discountCurve,
175 bool includeSettlementDateFlows,
176 Date settlementDate = Date(),
177 Date npvDate = Date());
178 //! Basis-point sensitivity of the cash flows.
179 /*! The result is the change in NPV due to a uniform
180 1-basis-point change in the rate paid by the cash
181 flows. The change for each coupon is discounted according
182 to the given term structure.
183 */
184 static Real bps(const Leg& leg,
185 const YieldTermStructure& discountCurve,
186 bool includeSettlementDateFlows,
187 Date settlementDate = Date(),
188 Date npvDate = Date());
189
190 //! NPV and BPS of the cash flows.
191 /*! The NPV and BPS of the cash flows calculated
192 together for performance reason
193 */
194 static std::pair<Real, Real> npvbps(const Leg& leg,
195 const YieldTermStructure& discountCurve,
196 bool includeSettlementDateFlows,
197 Date settlementDate = Date(),
198 Date npvDate = Date());
199
200 //! NPV and BPS of the cash flows.
201 /*! \deprecated Use the overload returning a pair of Reals.
202 Deprecated in version 1.29.
203 */
204 QL_DEPRECATED
205 static void npvbps(const Leg& leg,
206 const YieldTermStructure& discountCurve,
207 bool includeSettlementDateFlows,
208 Date settlementDate,
209 Date npvDate,
210 Real& npv,
211 Real& bps);
212
213 //! At-the-money rate of the cash flows.
214 /*! The result is the fixed rate for which a fixed rate cash flow
215 vector, equivalent to the input vector, has the required NPV
216 according to the given term structure. If the required NPV is
217 not given, the input cash flow vector's NPV is used instead.
218 */
219 static Rate atmRate(const Leg& leg,
220 const YieldTermStructure& discountCurve,
221 bool includeSettlementDateFlows,
222 Date settlementDate = Date(),
223 Date npvDate = Date(),
224 Real npv = Null<Real>());
225 //@}
226
227 //! \name Yield (a.k.a. Internal Rate of Return, i.e. IRR) functions
228 /*! The IRR is the interest rate at which the NPV of the cash
229 flows equals the dirty price.
230 */
231 //@{
232 //! NPV of the cash flows.
233 /*! The NPV is the sum of the cash flows, each discounted
234 according to the given constant interest rate. The result
235 is affected by the choice of the interest-rate compounding
236 and the relative frequency and day counter.
237 */
238 static Real npv(const Leg& leg,
239 const InterestRate& yield,
240 bool includeSettlementDateFlows,
241 Date settlementDate = Date(),
242 Date npvDate = Date());
243 static Real npv(const Leg& leg,
244 Rate yield,
245 const DayCounter& dayCounter,
246 Compounding compounding,
247 Frequency frequency,
248 bool includeSettlementDateFlows,
249 Date settlementDate = Date(),
250 Date npvDate = Date());
251 //! Basis-point sensitivity of the cash flows.
252 /*! The result is the change in NPV due to a uniform
253 1-basis-point change in the rate paid by the cash
254 flows. The change for each coupon is discounted according
255 to the given constant interest rate. The result is
256 affected by the choice of the interest-rate compounding
257 and the relative frequency and day counter.
258 */
259 static Real bps(const Leg& leg,
260 const InterestRate& yield,
261 bool includeSettlementDateFlows,
262 Date settlementDate = Date(),
263 Date npvDate = Date());
264 static Real bps(const Leg& leg,
265 Rate yield,
266 const DayCounter& dayCounter,
267 Compounding compounding,
268 Frequency frequency,
269 bool includeSettlementDateFlows,
270 Date settlementDate = Date(),
271 Date npvDate = Date());
272 //! Implied internal rate of return.
273 /*! The function verifies
274 the theoretical existence of an IRR and numerically
275 establishes the IRR to the desired precision.
276 */
277 static Rate yield(const Leg& leg,
278 Real npv,
279 const DayCounter& dayCounter,
280 Compounding compounding,
281 Frequency frequency,
282 bool includeSettlementDateFlows,
283 Date settlementDate = Date(),
284 Date npvDate = Date(),
285 Real accuracy = 1.0e-10,
286 Size maxIterations = 100,
287 Rate guess = 0.05);
288
289 template <typename Solver>
290 static Rate yield(const Solver& solver,
291 const Leg& leg,
292 Real npv,
293 const DayCounter& dayCounter,
294 Compounding compounding,
295 Frequency frequency,
296 bool includeSettlementDateFlows,
297 Date settlementDate = Date(),
298 Date npvDate = Date(),
299 Real accuracy = 1.0e-10,
300 Rate guess = 0.05) {
301 IrrFinder objFunction(leg, npv, dayCounter, compounding,
302 frequency, includeSettlementDateFlows,
303 settlementDate, npvDate);
304 return solver.solve(objFunction, accuracy, guess, guess/10.0);
305 }
306
307 //! Cash-flow duration.
308 /*! The simple duration of a string of cash flows is defined as
309 \f[
310 D_{\mathrm{simple}} = \frac{\sum t_i c_i B(t_i)}{\sum c_i B(t_i)}
311 \f]
312 where \f$ c_i \f$ is the amount of the \f$ i \f$-th cash
313 flow, \f$ t_i \f$ is its payment time, and \f$ B(t_i) \f$
314 is the corresponding discount according to the passed yield.
315
316 The modified duration is defined as
317 \f[
318 D_{\mathrm{modified}} = -\frac{1}{P} \frac{\partial P}{\partial y}
319 \f]
320 where \f$ P \f$ is the present value of the cash flows
321 according to the given IRR \f$ y \f$.
322
323 The Macaulay duration is defined for a compounded IRR as
324 \f[
325 D_{\mathrm{Macaulay}} = \left( 1 + \frac{y}{N} \right)
326 D_{\mathrm{modified}}
327 \f]
328 where \f$ y \f$ is the IRR and \f$ N \f$ is the number of
329 cash flows per year.
330 */
331 static Time duration(const Leg& leg,
332 const InterestRate& yield,
333 Duration::Type type,
334 bool includeSettlementDateFlows,
335 Date settlementDate = Date(),
336 Date npvDate = Date());
337 static Time duration(const Leg& leg,
338 Rate yield,
339 const DayCounter& dayCounter,
340 Compounding compounding,
341 Frequency frequency,
342 Duration::Type type,
343 bool includeSettlementDateFlows,
344 Date settlementDate = Date(),
345 Date npvDate = Date());
346
347 //! Cash-flow convexity
348 /*! The convexity of a string of cash flows is defined as
349 \f[
350 C = \frac{1}{P} \frac{\partial^2 P}{\partial y^2}
351 \f]
352 where \f$ P \f$ is the present value of the cash flows
353 according to the given IRR \f$ y \f$.
354 */
355 static Real convexity(const Leg& leg,
356 const InterestRate& yield,
357 bool includeSettlementDateFlows,
358 Date settlementDate = Date(),
359 Date npvDate = Date());
360 static Real convexity(const Leg& leg,
361 Rate yield,
362 const DayCounter& dayCounter,
363 Compounding compounding,
364 Frequency frequency,
365 bool includeSettlementDateFlows,
366 Date settlementDate = Date(),
367 Date npvDate = Date());
368
369 //! Basis-point value
370 /*! Obtained by setting dy = 0.0001 in the 2nd-order Taylor
371 series expansion.
372 */
373 static Real basisPointValue(const Leg& leg,
374 const InterestRate& yield,
375 bool includeSettlementDateFlows,
376 Date settlementDate = Date(),
377 Date npvDate = Date());
378 static Real basisPointValue(const Leg& leg,
379 Rate yield,
380 const DayCounter& dayCounter,
381 Compounding compounding,
382 Frequency frequency,
383 bool includeSettlementDateFlows,
384 Date settlementDate = Date(),
385 Date npvDate = Date());
386
387 //! Yield value of a basis point
388 /*! The yield value of a one basis point change in price is
389 the derivative of the yield with respect to the price
390 multiplied by 0.01
391 */
392 static Real yieldValueBasisPoint(const Leg& leg,
393 const InterestRate& yield,
394 bool includeSettlementDateFlows,
395 Date settlementDate = Date(),
396 Date npvDate = Date());
397 static Real yieldValueBasisPoint(const Leg& leg,
398 Rate yield,
399 const DayCounter& dayCounter,
400 Compounding compounding,
401 Frequency frequency,
402 bool includeSettlementDateFlows,
403 Date settlementDate = Date(),
404 Date npvDate = Date());
405 //@}
406
407 //! \name Z-spread functions
408 /*! For details on z-spread refer to:
409 "Credit Spreads Explained", Lehman Brothers European Fixed
410 Income Research - March 2004, D. O'Kane
411 */
412 //@{
413 //! NPV of the cash flows.
414 /*! The NPV is the sum of the cash flows, each discounted
415 according to the z-spreaded term structure. The result
416 is affected by the choice of the z-spread compounding
417 and the relative frequency and day counter.
418 */
419 static Real npv(const Leg& leg,
420 const ext::shared_ptr<YieldTermStructure>& discount,
421 Spread zSpread,
422 const DayCounter& dayCounter,
423 Compounding compounding,
424 Frequency frequency,
425 bool includeSettlementDateFlows,
426 Date settlementDate = Date(),
427 Date npvDate = Date());
428 //! implied Z-spread.
429 static Spread zSpread(const Leg& leg,
430 Real npv,
431 const ext::shared_ptr<YieldTermStructure>&,
432 const DayCounter& dayCounter,
433 Compounding compounding,
434 Frequency frequency,
435 bool includeSettlementDateFlows,
436 Date settlementDate = Date(),
437 Date npvDate = Date(),
438 Real accuracy = 1.0e-10,
439 Size maxIterations = 100,
440 Rate guess = 0.0);
441 //! deprecated implied Z-spread.
442 static Spread zSpread(const Leg& leg,
443 const ext::shared_ptr<YieldTermStructure>& d,
444 Real npv,
445 const DayCounter& dayCounter,
446 Compounding compounding,
447 Frequency frequency,
448 bool includeSettlementDateFlows,
449 Date settlementDate = Date(),
450 Date npvDate = Date(),
451 Real accuracy = 1.0e-10,
452 Size maxIterations = 100,
453 Rate guess = 0.0) {
454 return zSpread(leg, npv, d, dayCounter, compounding, frequency,
455 includeSettlementDateFlows, settlementDate, npvDate,
456 accuracy, maxIterations, guess);
457 }
458 //@}
459
460 };
461
462}
463
464#endif
465

source code of quantlib/ql/cashflows/cashflows.hpp