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) 2010 Alessandro Roveda
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 nonlinearfittingmethods.hpp
22 \brief nonlinear methods to fit a bond discount function
23*/
24
25#ifndef quantlib_nonlinear_fitting_methods_hpp
26#define quantlib_nonlinear_fitting_methods_hpp
27
28#include <ql/termstructures/yield/fittedbonddiscountcurve.hpp>
29#include <ql/math/bspline.hpp>
30#include <ql/shared_ptr.hpp>
31
32namespace QuantLib {
33
34 //! Exponential-splines fitting method
35 /*! Fits a discount function to the exponential form
36 \f[
37 d(t) = \sum_{i=1}^9 c_i \exp^{-kappa i t}
38 \f]
39 where the constants \f$ c_i \f$ and \f$ \kappa \f$ are to be
40 determined. See:Li, B., E. DeWetering, G. Lucas, R. Brenner
41 and A. Shapiro (2001): "Merrill Lynch Exponential Spline
42 Model." Merrill Lynch Working Paper
43
44 \f$ \kappa \f$ can be passed a fixed value, in which case it
45 is excluded from optimization.
46
47 \warning convergence may be slow
48 */
49 class ExponentialSplinesFitting
50 : public FittedBondDiscountCurve::FittingMethod {
51 public:
52 ExponentialSplinesFitting(bool constrainAtZero = true,
53 const Array& weights = Array(),
54 const ext::shared_ptr<OptimizationMethod>& optimizationMethod =
55 ext::shared_ptr<OptimizationMethod>(),
56 const Array& l2 = Array(),
57 Real minCutoffTime = 0.0,
58 Real maxCutoffTime = QL_MAX_REAL,
59 Size numCoeffs = 9,
60 Real fixedKappa = Null<Real>());
61 ExponentialSplinesFitting(bool constrainAtZero,
62 const Array& weights,
63 const Array& l2,
64 Real minCutoffTime = 0.0,
65 Real maxCutoffTime = QL_MAX_REAL,
66 Size numCoeffs = 9,
67 Real fixedKappa = Null<Real>());
68 ExponentialSplinesFitting(bool constrainAtZero,
69 Size numCoeffs,
70 Real fixedKappa,
71 const Array& weights = Array() );
72
73
74 std::unique_ptr<FittedBondDiscountCurve::FittingMethod> clone() const override;
75 private:
76 Natural numCoeffs_;
77 Real fixedKappa_;
78 Size size() const override;
79 DiscountFactor discountFunction(const Array& x, Time t) const override;
80 };
81
82
83 //! Nelson-Siegel fitting method
84 /*! Fits a discount function to the form
85 \f$ d(t) = \exp^{-r t}, \f$ where the zero rate \f$r\f$ is defined as
86 \f[
87 r \equiv c_0 + (c_1 + c_2)*(1 - exp^{-\kappa*t})/(\kappa t) -
88 c_2 exp^{ - \kappa t}.
89 \f]
90 See: Nelson, C. and A. Siegel (1985): "Parsimonious modeling of yield
91 curves for US Treasury bills." NBER Working Paper Series, no 1594.
92 */
93 class NelsonSiegelFitting
94 : public FittedBondDiscountCurve::FittingMethod {
95 public:
96 NelsonSiegelFitting(const Array& weights = Array(),
97 const ext::shared_ptr<OptimizationMethod>& optimizationMethod =
98 ext::shared_ptr<OptimizationMethod>(),
99 const Array& l2 = Array(),
100 Real minCutoffTime = 0.0,
101 Real maxCutoffTime = QL_MAX_REAL);
102 NelsonSiegelFitting(const Array& weights,
103 const Array& l2,
104 Real minCutoffTime = 0.0,
105 Real maxCutoffTime = QL_MAX_REAL);
106 std::unique_ptr<FittedBondDiscountCurve::FittingMethod> clone() const override;
107 private:
108 Size size() const override;
109 DiscountFactor discountFunction(const Array& x, Time t) const override;
110 };
111
112
113 //! Svensson Fitting method
114 /*! Fits a discount function to the form
115 \f$ d(t) = \exp^{-r t}, \f$ where the zero rate \f$r\f$ is defined as
116 \f[
117 r \equiv c_0 + (c_0 + c_1)(\frac {1 - exp^{-\kappa t}}{\kappa t})
118 - c_2exp^{ - \kappa t}
119 + c_3{(\frac{1 - exp^{-\kappa_1 t}}{\kappa_1 t} -exp^{-\kappa_1 t})}.
120 \f]
121 See: Svensson, L. (1994). Estimating and interpreting forward
122 interest rates: Sweden 1992-4.
123 Discussion paper, Centre for Economic Policy Research(1051).
124 */
125 class SvenssonFitting
126 : public FittedBondDiscountCurve::FittingMethod {
127 public:
128 SvenssonFitting(const Array& weights = Array(),
129 const ext::shared_ptr<OptimizationMethod>& optimizationMethod =
130 ext::shared_ptr<OptimizationMethod>(),
131 const Array& l2 = Array(),
132 Real minCutoffTime = 0.0,
133 Real maxCutoffTime = QL_MAX_REAL);
134 SvenssonFitting(const Array& weights,
135 const Array& l2,
136 Real minCutoffTime = 0.0,
137 Real maxCutoffTime = QL_MAX_REAL);
138 std::unique_ptr<FittedBondDiscountCurve::FittingMethod> clone() const override;
139 private:
140 Size size() const override;
141 DiscountFactor discountFunction(const Array& x, Time t) const override;
142 };
143
144
145 //! CubicSpline B-splines fitting method
146 /*! Fits a discount function to a set of cubic B-splines
147 \f$ N_{i,3}(t) \f$, i.e.,
148 \f[
149 d(t) = \sum_{i=0}^{n} c_i * N_{i,3}(t)
150 \f]
151
152 See: McCulloch, J. 1971, "Measuring the Term Structure of
153 Interest Rates." Journal of Business, 44: 19-31
154
155 McCulloch, J. 1975, "The tax adjusted yield curve."
156 Journal of Finance, XXX811-30
157
158 \warning "The results are extremely sensitive to the number
159 and location of the knot points, and there is no
160 optimal way of selecting them." James, J. and
161 N. Webber, "Interest Rate Modelling" John Wiley,
162 2000, pp. 440.
163 */
164 class CubicBSplinesFitting
165 : public FittedBondDiscountCurve::FittingMethod {
166 public:
167 CubicBSplinesFitting(const std::vector<Time>& knotVector,
168 bool constrainAtZero = true,
169 const Array& weights = Array(),
170 const ext::shared_ptr<OptimizationMethod>& optimizationMethod =
171 ext::shared_ptr<OptimizationMethod>(),
172 const Array& l2 = Array(),
173 Real minCutoffTime = 0.0,
174 Real maxCutoffTime = QL_MAX_REAL);
175 CubicBSplinesFitting(const std::vector<Time>& knotVector,
176 bool constrainAtZero,
177 const Array& weights,
178 const Array& l2,
179 Real minCutoffTime = 0.0,
180 Real maxCutoffTime = QL_MAX_REAL);
181 //! cubic B-spline basis functions
182 Real basisFunction(Integer i, Time t) const;
183 std::unique_ptr<FittedBondDiscountCurve::FittingMethod> clone() const override;
184 private:
185 Size size() const override;
186 DiscountFactor discountFunction(const Array& x, Time t) const override;
187 BSpline splines_;
188 Size size_;
189 //! N_th basis function coefficient to solve for when d(0)=1
190 Natural N_;
191 };
192
193
194 //! Simple polynomial fitting method
195 /* Fits a discount function to the simple polynomial form:
196 \f[
197 d(t) = \sum_{i=0}^{degree} c_i * t^{i}
198 \f]
199 where the constants \f$ c_i \f$ are to be determined.
200
201 This is a simple/crude, but fast and robust, means of fitting
202 a yield curve.
203 */
204 class SimplePolynomialFitting
205 : public FittedBondDiscountCurve::FittingMethod {
206 public:
207 SimplePolynomialFitting(Natural degree,
208 bool constrainAtZero = true,
209 const Array& weights = Array(),
210 const ext::shared_ptr<OptimizationMethod>& optimizationMethod =
211 ext::shared_ptr<OptimizationMethod>(),
212 const Array& l2 = Array(),
213 Real minCutoffTime = 0.0,
214 Real maxCutoffTime = QL_MAX_REAL);
215 SimplePolynomialFitting(Natural degree,
216 bool constrainAtZero,
217 const Array& weights,
218 const Array& l2,
219 Real minCutoffTime = 0.0,
220 Real maxCutoffTime = QL_MAX_REAL);
221 std::unique_ptr<FittedBondDiscountCurve::FittingMethod> clone() const override;
222 private:
223 Size size() const override;
224 DiscountFactor discountFunction(const Array& x, Time t) const override;
225 Size size_;
226 };
227
228
229 //! Spread fitting method helper
230 /* Fits a spread curve on top of a discount function according to given parametric method
231 */
232 class SpreadFittingMethod
233 : public FittedBondDiscountCurve::FittingMethod {
234 public:
235 SpreadFittingMethod(const ext::shared_ptr<FittingMethod>& method,
236 Handle<YieldTermStructure> discountCurve,
237 Real minCutoffTime = 0.0,
238 Real maxCutoffTime = QL_MAX_REAL);
239 std::unique_ptr<FittedBondDiscountCurve::FittingMethod> clone() const override;
240 protected:
241 void init() override;
242
243 private:
244 Size size() const override;
245 DiscountFactor discountFunction(const Array& x, Time t) const override;
246 // underlying parametric method
247 ext::shared_ptr<FittingMethod> method_;
248 // adjustment in case underlying discount curve has different reference date
249 DiscountFactor rebase_;
250 // discount curve from on top of which the spread will be calculated
251 Handle<YieldTermStructure> discountingCurve_;
252 };
253}
254
255
256#endif
257

source code of quantlib/ql/termstructures/yield/nonlinearfittingmethods.hpp