Coverage Report

Created: 2026-09-28 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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