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 <http://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
35namespace 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 const CallabilitySchedule& callability() const {
63 return putCallSchedule_;
64 }
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 /*! \warning This version of the method takes an NPV as target, not a price.
83
84 \deprecated Use the other overload.
85 Deprecated in version 1.28.
86 */
87 QL_DEPRECATED
88 Volatility impliedVolatility(
89 Real targetValue,
90 const Handle<YieldTermStructure>& discountCurve,
91 Real accuracy,
92 Size maxEvaluations,
93 Volatility minVol,
94 Volatility maxVol) const;
95
96 //! Calculate the Option Adjusted Spread (OAS)
97 /*! Calculates the spread that needs to be added to the
98 reference curve so that the theoretical model value
99 matches the marketPrice.
100
101 */
102 Spread OAS(Real cleanPrice,
103 const Handle<YieldTermStructure>& engineTS,
104 const DayCounter& dayCounter,
105 Compounding compounding,
106 Frequency frequency,
107 Date settlementDate = Date(),
108 Real accuracy = 1.0e-10,
109 Size maxIterations = 100,
110 Rate guess = 0.0);
111
112 //! Calculate the clean price based on the given
113 //! option-adjust-spread (oas) over the given yield term
114 //! structure (engineTS)
115 Real cleanPriceOAS(Real oas,
116 const Handle<YieldTermStructure>& engineTS,
117 const DayCounter& dayCounter,
118 Compounding compounding,
119 Frequency frequency,
120 Date settlementDate = Date());
121
122 //! Calculate the effective duration, i.e., the first
123 //! differential of the dirty price w.r.t. a parallel shift of
124 //! the yield term structure divided by current dirty price
125 Real effectiveDuration(Real oas,
126 const Handle<YieldTermStructure>& engineTS,
127 const DayCounter& dayCounter,
128 Compounding compounding,
129 Frequency frequency,
130 Real bump=2e-4);
131
132 //! Calculate the effective convexity, i.e., the second
133 //! differential of the dirty price w.r.t. a parallel shift of
134 //! the yield term structure divided by current dirty price
135 Real effectiveConvexity(Real oas,
136 const Handle<YieldTermStructure>& engineTS,
137 const DayCounter& dayCounter,
138 Compounding compounding,
139 Frequency frequency,
140 Real bump=2e-4);
141 //@}
142
143 void setupArguments(PricingEngine::arguments* args) const override;
144
145 protected:
146 CallableBond(Natural settlementDays,
147 const Date& maturityDate,
148 const Calendar& calendar,
149 DayCounter paymentDayCounter,
150 Real faceAmount,
151 const Date& issueDate = Date(),
152 CallabilitySchedule putCallSchedule = CallabilitySchedule());
153
154 DayCounter paymentDayCounter_;
155 Frequency frequency_;
156 CallabilitySchedule putCallSchedule_;
157 Real faceAmount_;
158 // helper class for Black implied volatility calculation
159 class ImpliedVolHelper;
160 // helper class for option adjusted spread calculations
161 class NPVSpreadHelper;
162
163 private:
164 /* Used internally.
165 same as Bond::accruedAmount() but with enable early
166 payments true. Forces accrued to be calculated in a
167 consistent way for future put/ call dates, which can be
168 problematic in lattice engines when option dates are also
169 coupon dates.
170 */
171 Real accrued(Date settlement) const;
172 };
173
174 class CallableBond::arguments : public Bond::arguments {
175 public:
176 arguments() = default;
177 std::vector<Date> couponDates;
178 std::vector<Real> couponAmounts;
179 Real faceAmount;
180 //! redemption = face amount * redemption / 100.
181 Real redemption;
182 Date redemptionDate;
183 DayCounter paymentDayCounter;
184 Frequency frequency;
185 CallabilitySchedule putCallSchedule;
186 //! bond full/dirty/cash prices
187 std::vector<Real> callabilityPrices;
188 std::vector<Date> callabilityDates;
189 //! Spread to apply to the valuation. This is a continuously
190 //! componded rate added to the model. Currently only applied
191 //! by the TreeCallableFixedRateBondEngine
192 Real spread;
193 void validate() const override;
194 };
195
196 //! results for a callable bond calculation
197 class CallableBond::results : public Bond::results {
198 public:
199 // no extra results set yet
200 };
201
202 //! base class for callable fixed rate bond engine
203 class CallableBond::engine
204 : public GenericEngine<CallableBond::arguments,
205 CallableBond::results> {};
206
207
208 //! callable/puttable fixed rate bond
209 /*! Callable fixed rate bond class.
210
211 \ingroup instruments
212 */
213 class CallableFixedRateBond : public CallableBond {
214 public:
215 CallableFixedRateBond(Natural settlementDays,
216 Real faceAmount,
217 const Schedule& schedule,
218 const std::vector<Rate>& coupons,
219 const DayCounter& accrualDayCounter,
220 BusinessDayConvention paymentConvention = Following,
221 Real redemption = 100.0,
222 const Date& issueDate = Date(),
223 const CallabilitySchedule& putCallSchedule = {},
224 const Period& exCouponPeriod = Period(),
225 const Calendar& exCouponCalendar = Calendar(),
226 BusinessDayConvention exCouponConvention = Unadjusted,
227 bool exCouponEndOfMonth = false);
228 };
229
230 //! callable/puttable zero coupon bond
231 /*! Callable zero coupon bond class.
232
233 \ingroup instruments
234 */
235 class CallableZeroCouponBond : public CallableBond {
236 public:
237 CallableZeroCouponBond(Natural settlementDays,
238 Real faceAmount,
239 const Calendar& calendar,
240 const Date& maturityDate,
241 const DayCounter& dayCounter,
242 BusinessDayConvention paymentConvention = Following,
243 Real redemption = 100.0,
244 const Date& issueDate = Date(),
245 const CallabilitySchedule& putCallSchedule = {});
246 };
247
248}
249
250#endif
251

source code of quantlib/ql/experimental/callablebonds/callablebond.hpp