/src/quantlib/ql/experimental/callablebonds/callablebond.hpp
Line | Count | Source |
1 | | /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | |
3 | | /* |
4 | | Copyright (C) 2008 Allen Kuo |
5 | | Copyright (C) 2017 BN Algorithms Ltd |
6 | | |
7 | | This file is part of QuantLib, a free-software/open-source library |
8 | | for financial quantitative analysts and developers - http://quantlib.org/ |
9 | | |
10 | | QuantLib is free software: you can redistribute it and/or modify it |
11 | | under the terms of the QuantLib license. You should have received a |
12 | | copy of the license along with this program; if not, please email |
13 | | <quantlib-dev@lists.sf.net>. The license is also available online at |
14 | | <https://www.quantlib.org/license.shtml>. |
15 | | |
16 | | This program is distributed in the hope that it will be useful, but WITHOUT |
17 | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
18 | | FOR A PARTICULAR PURPOSE. See the license for more details. |
19 | | */ |
20 | | |
21 | | /*! \file callablebond.hpp |
22 | | \brief callable bond classes |
23 | | */ |
24 | | |
25 | | #ifndef quantlib_callable_bond_hpp |
26 | | #define quantlib_callable_bond_hpp |
27 | | |
28 | | #include <ql/instruments/bond.hpp> |
29 | | #include <ql/pricingengine.hpp> |
30 | | #include <ql/instruments/callabilityschedule.hpp> |
31 | | #include <ql/termstructures/yieldtermstructure.hpp> |
32 | | #include <ql/handle.hpp> |
33 | | #include <ql/quotes/simplequote.hpp> |
34 | | |
35 | | namespace QuantLib { |
36 | | |
37 | | class Schedule; |
38 | | class DayCounter; |
39 | | |
40 | | //! Callable bond base class |
41 | | /*! Base callable bond class for fixed and zero coupon bonds. |
42 | | Defines commonalities between fixed and zero coupon callable |
43 | | bonds. At present, only European and Bermudan put/call schedules |
44 | | supported (no American optionality), as defined by the Callability |
45 | | class. |
46 | | |
47 | | \todo models/shortrate/calibrationHelpers |
48 | | \todo OAS/OAD |
49 | | \todo floating rate callable bonds ? |
50 | | |
51 | | \ingroup instruments |
52 | | */ |
53 | | class CallableBond : public Bond { |
54 | | public: |
55 | | class arguments; |
56 | | class results; |
57 | | class engine; |
58 | | |
59 | | //! \name Inspectors |
60 | | //@{ |
61 | | //! return the bond's put/call schedule |
62 | 0 | const CallabilitySchedule& callability() const { |
63 | 0 | return putCallSchedule_; |
64 | 0 | } |
65 | | //@} |
66 | | |
67 | | //! \name Calculations |
68 | | //@{ |
69 | | //! returns the Black implied forward yield volatility |
70 | | /*! the forward yield volatility, see Hull, Fourth Edition, |
71 | | Chapter 20, pg 536). Relevant only to European put/call |
72 | | schedules |
73 | | */ |
74 | | Volatility impliedVolatility( |
75 | | const Bond::Price& targetPrice, |
76 | | const Handle<YieldTermStructure>& discountCurve, |
77 | | Real accuracy, |
78 | | Size maxEvaluations, |
79 | | Volatility minVol, |
80 | | Volatility maxVol) const; |
81 | | |
82 | | //! Calculate the Option Adjusted Spread (OAS) |
83 | | /*! Calculates the spread that needs to be added to the |
84 | | reference curve so that the theoretical model value |
85 | | matches the marketPrice. |
86 | | |
87 | | */ |
88 | | Spread OAS(Real cleanPrice, |
89 | | const Handle<YieldTermStructure>& engineTS, |
90 | | const DayCounter& dayCounter, |
91 | | Compounding compounding, |
92 | | Frequency frequency, |
93 | | Date settlementDate = Date(), |
94 | | Real accuracy = 1.0e-10, |
95 | | Size maxIterations = 100, |
96 | | Rate guess = 0.0); |
97 | | |
98 | | //! Calculate the clean price based on the given |
99 | | //! option-adjust-spread (oas) over the given yield term |
100 | | //! structure (engineTS) |
101 | | Real cleanPriceOAS(Real oas, |
102 | | const Handle<YieldTermStructure>& engineTS, |
103 | | const DayCounter& dayCounter, |
104 | | Compounding compounding, |
105 | | Frequency frequency, |
106 | | Date settlementDate = Date()); |
107 | | |
108 | | //! Calculate the effective duration, i.e., the first |
109 | | //! differential of the dirty price w.r.t. a parallel shift of |
110 | | //! the yield term structure divided by current dirty price |
111 | | Real effectiveDuration(Real oas, |
112 | | const Handle<YieldTermStructure>& engineTS, |
113 | | const DayCounter& dayCounter, |
114 | | Compounding compounding, |
115 | | Frequency frequency, |
116 | | Real bump=2e-4); |
117 | | |
118 | | //! Calculate the effective convexity, i.e., the second |
119 | | //! differential of the dirty price w.r.t. a parallel shift of |
120 | | //! the yield term structure divided by current dirty price |
121 | | Real effectiveConvexity(Real oas, |
122 | | const Handle<YieldTermStructure>& engineTS, |
123 | | const DayCounter& dayCounter, |
124 | | Compounding compounding, |
125 | | Frequency frequency, |
126 | | Real bump=2e-4); |
127 | | //@} |
128 | | |
129 | | void setupArguments(PricingEngine::arguments* args) const override; |
130 | | |
131 | | protected: |
132 | | CallableBond(Natural settlementDays, |
133 | | const Date& maturityDate, |
134 | | const Calendar& calendar, |
135 | | DayCounter paymentDayCounter, |
136 | | Real faceAmount, |
137 | | const Date& issueDate = Date(), |
138 | | CallabilitySchedule putCallSchedule = CallabilitySchedule()); |
139 | | |
140 | | DayCounter paymentDayCounter_; |
141 | | Frequency frequency_; |
142 | | CallabilitySchedule putCallSchedule_; |
143 | | Real faceAmount_; |
144 | | // helper class for Black implied volatility calculation |
145 | | class ImpliedVolHelper; |
146 | | // helper class for option adjusted spread calculations |
147 | | class NPVSpreadHelper; |
148 | | |
149 | | private: |
150 | | /* Used internally. |
151 | | same as Bond::accruedAmount() but with enable early |
152 | | payments true. Forces accrued to be calculated in a |
153 | | consistent way for future put/ call dates, which can be |
154 | | problematic in lattice engines when option dates are also |
155 | | coupon dates. |
156 | | */ |
157 | | Real accrued(Date settlement) const; |
158 | | }; |
159 | | |
160 | | class CallableBond::arguments : public Bond::arguments { |
161 | | public: |
162 | 0 | arguments() = default; |
163 | | std::vector<Date> couponDates; |
164 | | std::vector<Real> couponAmounts; |
165 | | Real faceAmount; |
166 | | //! redemption = face amount * redemption / 100. |
167 | | Real redemption; |
168 | | Date redemptionDate; |
169 | | DayCounter paymentDayCounter; |
170 | | Frequency frequency; |
171 | | CallabilitySchedule putCallSchedule; |
172 | | //! bond full/dirty/cash prices |
173 | | std::vector<Real> callabilityPrices; |
174 | | std::vector<Date> callabilityDates; |
175 | | //! Spread to apply to the valuation. This is a continuously |
176 | | //! componded rate added to the model. Currently only applied |
177 | | //! by the TreeCallableFixedRateBondEngine |
178 | | Real spread; |
179 | | void validate() const override; |
180 | | }; |
181 | | |
182 | | //! results for a callable bond calculation |
183 | | class CallableBond::results : public Bond::results { |
184 | | public: |
185 | | // no extra results set yet |
186 | | }; |
187 | | |
188 | | //! base class for callable fixed rate bond engine |
189 | | class CallableBond::engine |
190 | | : public GenericEngine<CallableBond::arguments, |
191 | | CallableBond::results> {}; |
192 | | |
193 | | |
194 | | //! callable/puttable fixed rate bond |
195 | | /*! Callable fixed rate bond class. |
196 | | |
197 | | \ingroup instruments |
198 | | */ |
199 | | class CallableFixedRateBond : public CallableBond { |
200 | | public: |
201 | | CallableFixedRateBond(Natural settlementDays, |
202 | | Real faceAmount, |
203 | | Schedule schedule, |
204 | | const std::vector<Rate>& coupons, |
205 | | const DayCounter& accrualDayCounter, |
206 | | BusinessDayConvention paymentConvention = Following, |
207 | | Real redemption = 100.0, |
208 | | const Date& issueDate = Date(), |
209 | | const CallabilitySchedule& putCallSchedule = {}, |
210 | | const Period& exCouponPeriod = Period(), |
211 | | const Calendar& exCouponCalendar = Calendar(), |
212 | | BusinessDayConvention exCouponConvention = Unadjusted, |
213 | | bool exCouponEndOfMonth = false); |
214 | | }; |
215 | | |
216 | | //! callable/puttable zero coupon bond |
217 | | /*! Callable zero coupon bond class. |
218 | | |
219 | | \ingroup instruments |
220 | | */ |
221 | | class CallableZeroCouponBond : public CallableBond { |
222 | | public: |
223 | | CallableZeroCouponBond(Natural settlementDays, |
224 | | Real faceAmount, |
225 | | const Calendar& calendar, |
226 | | const Date& maturityDate, |
227 | | const DayCounter& dayCounter, |
228 | | BusinessDayConvention paymentConvention = Following, |
229 | | Real redemption = 100.0, |
230 | | const Date& issueDate = Date(), |
231 | | const CallabilitySchedule& putCallSchedule = {}); |
232 | | }; |
233 | | |
234 | | } |
235 | | |
236 | | #endif |