QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
fittedbonddiscountcurve.hpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2007 Allen Kuo
5 Copyright (C) 2009 Ferdinando Ametrano
6 Copyright (C) 2015 Andres Hernandez
7
8 This file is part of QuantLib, a free-software/open-source library
9 for financial quantitative analysts and developers - http://quantlib.org/
10
11 QuantLib is free software: you can redistribute it and/or modify it
12 under the terms of the QuantLib license. You should have received a
13 copy of the license along with this program; if not, please email
14 <quantlib-dev@lists.sf.net>. The license is also available online at
15 <http://quantlib.org/license.shtml>.
16
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the license for more details.
20*/
21
22/*! \file fittedbonddiscountcurve.hpp
23 \brief discount curve fitted to a set of bonds
24*/
25
26#ifndef quantlib_fitted_bond_discount_curve_hpp
27#define quantlib_fitted_bond_discount_curve_hpp
28
32#include <ql/math/array.hpp>
34
35namespace QuantLib {
36
37 //! Discount curve fitted to a set of fixed-coupon bonds
38 /*! This class fits a discount function \f$ d(t) \f$ over a set of
39 bonds, using a user defined fitting method. The discount
40 function is fit in such a way so that all cashflows of all
41 input bonds, when discounted using \f$ d(t) \f$, will
42 reproduce the set of input bond prices in an optimized
43 sense. Minimized price errors are weighted by the inverse of
44 their respective bond duration.
45
46 The FittedBondDiscountCurve class acts as a generic wrapper,
47 while its inner class FittingMethod provides the
48 implementation details. Developers thus need only derive new
49 fitting methods from the latter.
50
51 \warning The method can be slow if there are many bonds to
52 fit. Speed also depends on the particular choice of
53 fitting method chosen and its convergence properties
54 under optimization. See also todo list for
55 BondDiscountCurveFittingMethod.
56
57 \todo refactor the bond helper class so that it is pure
58 virtual and returns a generic bond or its cash
59 flows. Derived classes would include helpers for
60 fixed-rate and zero-coupon bonds. In this way, both
61 bonds and bills can be used to fit a discount curve
62 using the exact same machinery. At present, only
63 fixed-coupon bonds are supported. An even better way to
64 move forward might be to get rate helpers to return
65 cashflows, in which case this class could be used to fit
66 any set of cash flows, not just bonds.
67
68 \todo add more fitting diagnostics: smoothness, standard
69 deviation, student-t test, etc. Generic smoothness
70 method may be useful for smoothing splines fitting. See
71 Fisher, M., D. Nychka and D. Zervos: "Fitting the term
72 structure of interest rates with smoothing splines."
73 Board of Governors of the Federal Reserve System,
74 Federal Resere Board Working Paper, 95-1.
75
76 \todo add extrapolation routines
77
78 \ingroup yieldtermstructures
79 */
81 public LazyObject {
82 public:
83 class FittingMethod;
84
85 //! \name Constructors
86 //@{
87 //! reference date based on current evaluation date
89 const Calendar& calendar,
90 std::vector<ext::shared_ptr<BondHelper> > bonds,
92 const FittingMethod& fittingMethod,
93 Real accuracy = 1.0e-10,
94 Size maxEvaluations = 10000,
95 Array guess = Array(),
96 Real simplexLambda = 1.0,
97 Size maxStationaryStateIterations = 100);
98 //! curve reference date fixed for life of curve
100 std::vector<ext::shared_ptr<BondHelper> > bonds,
101 const DayCounter& dayCounter,
102 const FittingMethod& fittingMethod,
103 Real accuracy = 1.0e-10,
104 Size maxEvaluations = 10000,
105 Array guess = Array(),
106 Real simplexLambda = 1.0,
107 Size maxStationaryStateIterations = 100);
108 //@}
109
110 //! \name Inspectors
111 //@{
112 //! total number of bonds used to fit the yield curve
113 Size numberOfBonds() const;
114 //! the latest date for which the curve can return values
115 Date maxDate() const override;
116 //! class holding the results of the fit
117 const FittingMethod& fitResults() const;
118 //@}
119
120 //! \name Observer interface
121 //@{
122 void update() override;
123 //@}
124
125 private:
126 void setup();
127 void performCalculations() const override;
128 DiscountFactor discountImpl(Time) const override;
129 // target accuracy level to be used in the optimization routine
131 // max number of evaluations to be used in the optimization routine
133 // sets the scale in the (Simplex) optimization routine
135 // max number of evaluations where no improvement to solution is made
137 // a guess solution may be passed into the constructor to speed calcs
139 mutable Date maxDate_;
140 std::vector<ext::shared_ptr<BondHelper> > bondHelpers_;
142 };
143
144
145 //! Base fitting method used to construct a fitted bond discount curve
146 /*! This base class provides the specific methodology/strategy
147 used to construct a FittedBondDiscountCurve. Derived classes
148 need only define the virtual function discountFunction() based
149 on the particular fitting method to be implemented, as well as
150 size(), the number of variables to be solved for/optimized. The
151 generic fitting methodology implemented here can be termed
152 nonlinear, in contrast to (typically faster, computationally)
153 linear fitting method.
154
155 Optional parameters for FittingMethod include an Array of
156 weights, which will be used as weights to each bond. If not given
157 or empty, then the bonds will be weighted by inverse duration
158
159 An optional Array may be provided as an L2 regularizor in this case
160 a L2 (gaussian) penalty is applied to each parameter starting from the
161 initial guess. This is the same as giving a Gaussian prior on the parameters
162
163 \todo derive the special-case class LinearFittingMethods from
164 FittingMethod. A linear fitting to a set of basis
165 functions \f$ b_i(t) \f$ is any fitting of the form
166 \f[
167 d(t) = \sum_{i=0} c_i b_i(t)
168 \f]
169 i.e., linear in the unknown coefficients \f$ c_i
170 \f$. Such a fitting can be reduced to a linear algebra
171 problem \f$ Ax = b \f$, and for large numbers of bonds,
172 would typically be much faster computationally than the
173 generic non-linear fitting method.
174
175 \warning some parameters to the Simplex optimization method
176 may need to be tweaked internally to the class,
177 depending on the fitting method used, in order to get
178 proper/reasonable/faster convergence.
179 */
182 // internal class
183 class FittingCost;
184 public:
185 virtual ~FittingMethod() = default;
186 //! total number of coefficients to fit/solve for
187 virtual Size size() const = 0;
188 //! output array of results of optimization problem
189 Array solution() const;
190 //! final number of iterations used in the optimization problem
192 //! final value of cost function after optimization
193 Real minimumCostValue() const;
194 //! error code of the optimization
196 //! clone of the current object
197 virtual std::unique_ptr<FittingMethod> clone() const = 0;
198 //! return whether there is a constraint at zero
199 bool constrainAtZero() const;
200 //! return weights being used
201 Array weights() const;
202 //! return l2 penalties being used
203 Array l2() const;
204 //! return optimization method being used
205 ext::shared_ptr<OptimizationMethod> optimizationMethod() const;
206 //! open discountFunction to public
207 DiscountFactor discount(const Array& x, Time t) const;
208 protected:
209 //! constructors
210 FittingMethod(bool constrainAtZero = true,
211 const Array& weights = Array(),
212 ext::shared_ptr<OptimizationMethod> optimizationMethod =
213 ext::shared_ptr<OptimizationMethod>(),
214 Array l2 = Array(),
215 Real minCutoffTime = 0.0,
216 Real maxCutoffTime = QL_MAX_REAL);
217 //! rerun every time instruments/referenceDate changes
218 virtual void init();
219 //! discount function called by FittedBondDiscountCurve
221 Time t) const = 0;
222
223 //! constrains discount function to unity at \f$ T=0 \f$, if true
225 //! internal reference to the FittedBondDiscountCurve instance
227 //! solution array found from optimization, set in calculate()
229 //! optional guess solution to be passed into constructor.
230 /*! The idea is to use a previous solution as a guess solution to
231 the discount curve, in an attempt to speed up calculations.
232 */
234 //! base class sets this cost function used in the optimization routine
235 ext::shared_ptr<FittingCost> costFunction_;
236 private:
237 // curve optimization called here- adjust optimization parameters here
238 void calculate();
239 // array of normalized (duration) weights, one for each bond helper
241 // array of l2 penalties one for each parameter
243 // whether or not the weights should be calculated internally
245 // total number of iterations used in the optimization routine
246 // (possibly including gradient evaluations)
248 // final value for the minimized cost function
250 // error code returned by OptimizationMethod::minimize()
252 // optimization method to be used, if none provided use Simplex
253 ext::shared_ptr<OptimizationMethod> optimizationMethod_;
254 // flat extrapolation of instantaneous forward before / after cutoff
256 };
257
258 // inline
259
261 return bondHelpers_.size();
262 }
263
265 calculate();
266 return maxDate_;
267 }
268
271 calculate();
272 return *fittingMethod_;
273 }
274
278 }
279
281 for (auto& bondHelper : bondHelpers_)
282 registerWith(bondHelper);
283 }
284
286 calculate();
287 return fittingMethod_->discount(fittingMethod_->solution_, t);
288 }
289
290 inline Integer
292 return numberOfIterations_;
293 }
294
295 inline
297 return costValue_;
298 }
299
300 inline
302 return errorCode_;
303 }
304
306 return solution_;
307 }
308
310 return constrainAtZero_;
311 }
312
314 return weights_;
315 }
316
318 return l2_;
319 }
320
321 inline ext::shared_ptr<OptimizationMethod>
323 return optimizationMethod_;
324 }
325
327 if (t < minCutoffTime_) {
328 // flat fwd extrapolation before min cutoff time
329 return std::exp(std::log(discountFunction(x, minCutoffTime_)) / minCutoffTime_ * t);
330 } else if (t > maxCutoffTime_) {
331 // flat fwd extrapolation after max cutoff time
332 return discountFunction(x, maxCutoffTime_) *
333 std::exp((std::log(discountFunction(x, maxCutoffTime_ + 1E-4)) -
334 std::log(discountFunction(x, maxCutoffTime_))) *
335 1E4 * (t - maxCutoffTime_));
336 } else {
337 return discountFunction(x, t);
338 }
339 }
340}
341
342#endif
1-D array used in linear algebra.
bond rate helpers
1-D array used in linear algebra.
Definition: array.hpp:52
calendar class
Definition: calendar.hpp:61
cloning proxy to an underlying object
Definition: clone.hpp:40
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
Base fitting method used to construct a fitted bond discount curve.
FittedBondDiscountCurve * curve_
internal reference to the FittedBondDiscountCurve instance
virtual void init()
rerun every time instruments/referenceDate changes
virtual Size size() const =0
total number of coefficients to fit/solve for
Array guessSolution_
optional guess solution to be passed into constructor.
ext::shared_ptr< OptimizationMethod > optimizationMethod_
bool constrainAtZero() const
return whether there is a constraint at zero
Real minimumCostValue() const
final value of cost function after optimization
Integer numberOfIterations() const
final number of iterations used in the optimization problem
Array solution_
solution array found from optimization, set in calculate()
bool constrainAtZero_
constrains discount function to unity at , if true
virtual std::unique_ptr< FittingMethod > clone() const =0
clone of the current object
virtual DiscountFactor discountFunction(const Array &x, Time t) const =0
discount function called by FittedBondDiscountCurve
EndCriteria::Type errorCode() const
error code of the optimization
Array l2() const
return l2 penalties being used
ext::shared_ptr< OptimizationMethod > optimizationMethod() const
return optimization method being used
ext::shared_ptr< FittingCost > costFunction_
base class sets this cost function used in the optimization routine
DiscountFactor discount(const Array &x, Time t) const
open discountFunction to public
Array solution() const
output array of results of optimization problem
Discount curve fitted to a set of fixed-coupon bonds.
const FittingMethod & fitResults() const
class holding the results of the fit
std::vector< ext::shared_ptr< BondHelper > > bondHelpers_
DiscountFactor discountImpl(Time) const override
discount factor calculation
Date maxDate() const override
the latest date for which the curve can return values
Size numberOfBonds() const
total number of bonds used to fit the yield curve
Framework for calculation on demand and result caching.
Definition: lazyobject.hpp:35
virtual void calculate() const
Definition: lazyobject.hpp:253
void update() override
Definition: lazyobject.hpp:188
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
virtual Natural settlementDays() const
the settlementDays used for reference date calculation
virtual const Date & referenceDate() const
the date at which discount = 1.0 and/or variance = 0.0
virtual Calendar calendar() const
the calendar used for reference and/or option date calculation
virtual DayCounter dayCounter() const
the day counter used for date/time conversion
Interest-rate term structure.
cloning proxy to an underlying object
const DefaultType & t
#define QL_MAX_REAL
Definition: qldefines.hpp:176
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
Real DiscountFactor
discount factor between dates
Definition: types.hpp:66
unsigned QL_INTEGER Natural
positive integer
Definition: types.hpp:43
QL_INTEGER Integer
integer number
Definition: types.hpp:35
std::size_t Size
size of a container
Definition: types.hpp:58
framework for calculation on demand and result caching
Abstract optimization method class.
Definition: any.hpp:35