1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2005, 2006, 2007, 2008 StatPro Italia srl
5 Copyright (C) 2007, 2008, 2009 Ferdinando Ametrano
6 Copyright (C) 2007 Chris Kenyon
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 piecewiseyieldcurve.hpp
23 \brief piecewise-interpolated term structure
24*/
25
26#ifndef quantlib_piecewise_yield_curve_hpp
27#define quantlib_piecewise_yield_curve_hpp
28
29#include <ql/patterns/lazyobject.hpp>
30#include <ql/termstructures/iterativebootstrap.hpp>
31#include <ql/termstructures/localbootstrap.hpp>
32#include <ql/termstructures/yield/bootstraptraits.hpp>
33#include <utility>
34
35namespace QuantLib {
36
37 class MultiCurveSensitivities;
38
39 //! Piecewise yield term structure
40 /*! This term structure is bootstrapped on a number of interest
41 rate instruments which are passed as a vector of pointers to
42 RateHelper instances. Their maturities mark the boundaries of
43 the interpolated segments.
44
45 Each segment is determined sequentially starting from the
46 earliest period to the latest and is chosen so that the
47 instrument whose maturity marks the end of such segment is
48 correctly repriced on the curve.
49
50 \warning The bootstrapping algorithm will raise an exception if
51 any two instruments have the same maturity date.
52
53 \ingroup yieldtermstructures
54
55 \test
56 - the correctness of the returned values is tested by
57 checking them against the original inputs.
58 - the observability of the term structure is tested.
59 */
60 template <class Traits, class Interpolator,
61 template <class> class Bootstrap = IterativeBootstrap>
62 class PiecewiseYieldCurve
63 : public Traits::template curve<Interpolator>::type,
64 public LazyObject {
65 private:
66 typedef typename Traits::template curve<Interpolator>::type base_curve;
67 typedef PiecewiseYieldCurve<Traits,Interpolator,Bootstrap> this_curve;
68 public:
69 typedef Traits traits_type;
70 typedef Interpolator interpolator_type;
71 typedef Bootstrap<this_curve> bootstrap_type;
72
73 //! \name Constructors
74 //@{
75 PiecewiseYieldCurve(
76 const Date& referenceDate,
77 std::vector<ext::shared_ptr<typename Traits::helper> > instruments,
78 const DayCounter& dayCounter,
79 const std::vector<Handle<Quote> >& jumps = {},
80 const std::vector<Date>& jumpDates = {},
81 const Interpolator& i = {},
82 bootstrap_type bootstrap = {})
83 : base_curve(referenceDate, dayCounter, jumps, jumpDates, i),
84 instruments_(std::move(instruments)), accuracy_(1.0e-12),
85 bootstrap_(std::move(bootstrap)) {
86 bootstrap_.setup(this);
87 }
88
89 PiecewiseYieldCurve(const Date& referenceDate,
90 std::vector<ext::shared_ptr<typename Traits::helper> > instruments,
91 const DayCounter& dayCounter,
92 const Interpolator& i,
93 bootstrap_type bootstrap = bootstrap_type())
94 : base_curve(
95 referenceDate, dayCounter, {}, {}, i),
96 instruments_(std::move(instruments)), accuracy_(1.0e-12),
97 bootstrap_(std::move(bootstrap)) {
98 bootstrap_.setup(this);
99 }
100
101 PiecewiseYieldCurve(const Date& referenceDate,
102 std::vector<ext::shared_ptr<typename Traits::helper> > instruments,
103 const DayCounter& dayCounter,
104 bootstrap_type bootstrap)
105 : base_curve(referenceDate,
106 dayCounter),
107 instruments_(std::move(instruments)), accuracy_(1.0e-12),
108 bootstrap_(std::move(bootstrap)) {
109 bootstrap_.setup(this);
110 }
111
112 PiecewiseYieldCurve(
113 Natural settlementDays,
114 const Calendar& calendar,
115 std::vector<ext::shared_ptr<typename Traits::helper> > instruments,
116 const DayCounter& dayCounter,
117 const std::vector<Handle<Quote> >& jumps = {},
118 const std::vector<Date>& jumpDates = {},
119 const Interpolator& i = {},
120 bootstrap_type bootstrap = {})
121 : base_curve(settlementDays, calendar, dayCounter, jumps, jumpDates, i),
122 instruments_(std::move(instruments)), accuracy_(1.0e-12),
123 bootstrap_(std::move(bootstrap)) {
124 bootstrap_.setup(this);
125 }
126
127 PiecewiseYieldCurve(Natural settlementDays,
128 const Calendar& calendar,
129 std::vector<ext::shared_ptr<typename Traits::helper> > instruments,
130 const DayCounter& dayCounter,
131 const Interpolator& i,
132 bootstrap_type bootstrap = bootstrap_type())
133 : base_curve(settlementDays,
134 calendar,
135 dayCounter,
136 {},
137 {},
138 i),
139 instruments_(std::move(instruments)), accuracy_(1.0e-12),
140 bootstrap_(std::move(bootstrap)) {
141 bootstrap_.setup(this);
142 }
143
144 PiecewiseYieldCurve(
145 Natural settlementDays,
146 const Calendar& calendar,
147 const std::vector<ext::shared_ptr<typename Traits::helper> >&
148 instruments,
149 const DayCounter& dayCounter,
150 const bootstrap_type& bootstrap)
151 : base_curve(settlementDays, calendar, dayCounter),
152 instruments_(instruments),
153 accuracy_(1.0e-12), bootstrap_(bootstrap) {
154 bootstrap_.setup(this);
155 }
156 //@}
157 //! \name TermStructure interface
158 //@{
159 Date maxDate() const override;
160 //@}
161 //! \name base_curve interface
162 //@{
163 const std::vector<Time>& times() const;
164 const std::vector<Date>& dates() const;
165 const std::vector<Real>& data() const;
166 std::vector<std::pair<Date, Real> > nodes() const;
167 //@}
168 //! \name Observer interface
169 //@{
170 void update() override;
171 //@}
172 private:
173 //! \name LazyObject interface
174 //@{
175 void performCalculations() const override;
176 //@}
177 // methods
178 DiscountFactor discountImpl(Time) const override;
179 // data members
180 std::vector<ext::shared_ptr<typename Traits::helper> > instruments_;
181 Real accuracy_;
182
183 // bootstrapper classes are declared as friend to manipulate
184 // the curve data. They might be passed the data instead, but
185 // it would increase the complexity---which is high enough
186 // already.
187 friend class MultiCurveSensitivities;
188 friend class Bootstrap<this_curve>;
189 friend class BootstrapError<this_curve> ;
190 friend class PenaltyFunction<this_curve>;
191 Bootstrap<this_curve> bootstrap_;
192 };
193
194
195 // inline definitions
196
197 template <class C, class I, template <class> class B>
198 inline Date PiecewiseYieldCurve<C,I,B>::maxDate() const {
199 calculate();
200 return base_curve::maxDate();
201 }
202
203 template <class C, class I, template <class> class B>
204 inline const std::vector<Time>& PiecewiseYieldCurve<C,I,B>::times() const {
205 calculate();
206 return base_curve::times();
207 }
208
209 template <class C, class I, template <class> class B>
210 inline const std::vector<Date>& PiecewiseYieldCurve<C,I,B>::dates() const {
211 calculate();
212 return base_curve::dates();
213 }
214
215 template <class C, class I, template <class> class B>
216 inline const std::vector<Real>& PiecewiseYieldCurve<C,I,B>::data() const {
217 calculate();
218 return base_curve::data();
219 }
220
221 template <class C, class I, template <class> class B>
222 inline std::vector<std::pair<Date, Real> >
223 PiecewiseYieldCurve<C,I,B>::nodes() const {
224 calculate();
225 return base_curve::nodes();
226 }
227
228 template <class C, class I, template <class> class B>
229 inline void PiecewiseYieldCurve<C,I,B>::update() {
230
231 // it dispatches notifications only if (!calculated_ && !frozen_)
232 LazyObject::update();
233
234 // do not use base_curve::update() as it would always notify observers
235
236 // TermStructure::update() update part
237 if (this->moving_)
238 this->updated_ = false;
239
240 }
241
242 template <class C, class I, template <class> class B>
243 inline
244 DiscountFactor PiecewiseYieldCurve<C,I,B>::discountImpl(Time t) const {
245 calculate();
246 return base_curve::discountImpl(t);
247 }
248
249 template <class C, class I, template <class> class B>
250 inline void PiecewiseYieldCurve<C,I,B>::performCalculations() const {
251 // just delegate to the bootstrapper
252 bootstrap_.calculate();
253 }
254
255}
256
257#endif
258

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