1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 StatPro Italia srl
5 Copyright (C) 2009, 2015 Ferdinando Ametrano
6 Copyright (C) 2015 Paolo Mazzocchi
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 zerocurve.hpp
23 \brief interpolated zero-rates structure
24*/
25
26#ifndef quantlib_zero_curve_hpp
27#define quantlib_zero_curve_hpp
28
29#include <ql/termstructures/yield/zeroyieldstructure.hpp>
30#include <ql/termstructures/interpolatedcurve.hpp>
31#include <ql/math/interpolations/linearinterpolation.hpp>
32#include <ql/interestrate.hpp>
33#include <ql/math/comparison.hpp>
34#include <ql/utilities/dataformatters.hpp>
35#include <utility>
36
37namespace QuantLib {
38
39 //! YieldTermStructure based on interpolation of zero rates
40 /*! \ingroup yieldtermstructures */
41 template <class Interpolator>
42 class InterpolatedZeroCurve : public ZeroYieldStructure,
43 protected InterpolatedCurve<Interpolator> {
44 public:
45 // constructor
46 InterpolatedZeroCurve(
47 const std::vector<Date>& dates,
48 const std::vector<Rate>& yields,
49 const DayCounter& dayCounter,
50 const Calendar& calendar = Calendar(),
51 const std::vector<Handle<Quote> >& jumps = {},
52 const std::vector<Date>& jumpDates = {},
53 const Interpolator& interpolator = {},
54 Compounding compounding = Continuous,
55 Frequency frequency = Annual);
56 InterpolatedZeroCurve(
57 const std::vector<Date>& dates,
58 const std::vector<Rate>& yields,
59 const DayCounter& dayCounter,
60 const Calendar& calendar,
61 const Interpolator& interpolator,
62 Compounding compounding = Continuous,
63 Frequency frequency = Annual);
64 InterpolatedZeroCurve(
65 const std::vector<Date>& dates,
66 const std::vector<Rate>& yields,
67 const DayCounter& dayCounter,
68 const Interpolator& interpolator,
69 Compounding compounding = Continuous,
70 Frequency frequency = Annual);
71 //! \name TermStructure interface
72 //@{
73 Date maxDate() const override;
74 //@}
75 //! \name other inspectors
76 //@{
77 const std::vector<Time>& times() const;
78 const std::vector<Date>& dates() const;
79 const std::vector<Real>& data() const;
80 const std::vector<Rate>& zeroRates() const;
81 std::vector<std::pair<Date, Real> > nodes() const;
82 //@}
83
84 protected:
85 explicit InterpolatedZeroCurve(
86 const DayCounter&,
87 const Interpolator& interpolator = {});
88 InterpolatedZeroCurve(
89 const Date& referenceDate,
90 const DayCounter&,
91 const std::vector<Handle<Quote> >& jumps = {},
92 const std::vector<Date>& jumpDates = {},
93 const Interpolator& interpolator = {});
94 InterpolatedZeroCurve(
95 Natural settlementDays,
96 const Calendar&,
97 const DayCounter&,
98 const std::vector<Handle<Quote> >& jumps = {},
99 const std::vector<Date>& jumpDates = {},
100 const Interpolator& interpolator = {});
101
102 //! \name ZeroYieldStructure implementation
103 //@{
104 Rate zeroYieldImpl(Time t) const override;
105 //@}
106 mutable std::vector<Date> dates_;
107 private:
108 void initialize(const Compounding& compounding, const Frequency& frequency);
109 };
110
111 //! Term structure based on linear interpolation of zero yields
112 /*! \ingroup yieldtermstructures */
113 typedef InterpolatedZeroCurve<Linear> ZeroCurve;
114
115
116 // inline definitions
117
118 template <class T>
119 inline Date InterpolatedZeroCurve<T>::maxDate() const {
120 if (this->maxDate_ != Date())
121 return this->maxDate_;
122 return dates_.back();
123 }
124
125 template <class T>
126 inline const std::vector<Time>& InterpolatedZeroCurve<T>::times() const {
127 return this->times_;
128 }
129
130 template <class T>
131 inline const std::vector<Date>& InterpolatedZeroCurve<T>::dates() const {
132 return dates_;
133 }
134
135 template <class T>
136 inline const std::vector<Real>&
137 InterpolatedZeroCurve<T>::data() const {
138 return this->data_;
139 }
140
141 template <class T>
142 inline const std::vector<Rate>&
143 InterpolatedZeroCurve<T>::zeroRates() const {
144 return this->data_;
145 }
146
147 template <class T>
148 inline std::vector<std::pair<Date, Real> >
149 InterpolatedZeroCurve<T>::nodes() const {
150 std::vector<std::pair<Date, Real> > results(dates_.size());
151 for (Size i=0; i<dates_.size(); ++i)
152 results[i] = std::make_pair(dates_[i], this->data_[i]);
153 return results;
154 }
155
156 #ifndef __DOXYGEN__
157
158 // template definitions
159
160 template <class T>
161 Rate InterpolatedZeroCurve<T>::zeroYieldImpl(Time t) const {
162 if (t <= this->times_.back())
163 return this->interpolation_(t, true);
164
165 // flat fwd extrapolation
166 Time tMax = this->times_.back();
167 Rate zMax = this->data_.back();
168 Rate instFwdMax = zMax + tMax * this->interpolation_.derivative(tMax);
169 return (zMax * tMax + instFwdMax * (t-tMax)) / t;
170 }
171
172 template <class T>
173 InterpolatedZeroCurve<T>::InterpolatedZeroCurve(
174 const DayCounter& dayCounter,
175 const T& interpolator)
176 : ZeroYieldStructure(dayCounter), InterpolatedCurve<T>(interpolator) {}
177
178 template <class T>
179 InterpolatedZeroCurve<T>::InterpolatedZeroCurve(
180 const Date& referenceDate,
181 const DayCounter& dayCounter,
182 const std::vector<Handle<Quote> >& jumps,
183 const std::vector<Date>& jumpDates,
184 const T& interpolator)
185 : ZeroYieldStructure(referenceDate, Calendar(), dayCounter, jumps, jumpDates),
186 InterpolatedCurve<T>(interpolator) {}
187
188 template <class T>
189 InterpolatedZeroCurve<T>::InterpolatedZeroCurve(
190 Natural settlementDays,
191 const Calendar& calendar,
192 const DayCounter& dayCounter,
193 const std::vector<Handle<Quote> >& jumps,
194 const std::vector<Date>& jumpDates,
195 const T& interpolator)
196 : ZeroYieldStructure(settlementDays, calendar, dayCounter, jumps, jumpDates),
197 InterpolatedCurve<T>(interpolator) {}
198
199 template <class T>
200 InterpolatedZeroCurve<T>::InterpolatedZeroCurve(
201 const std::vector<Date>& dates,
202 const std::vector<Rate>& yields,
203 const DayCounter& dayCounter,
204 const Calendar& calendar,
205 const std::vector<Handle<Quote> >& jumps,
206 const std::vector<Date>& jumpDates,
207 const T& interpolator,
208 Compounding compounding,
209 Frequency frequency)
210 : ZeroYieldStructure(dates.at(n: 0), calendar, dayCounter, jumps, jumpDates),
211 InterpolatedCurve<T>(std::vector<Time>(), yields, interpolator),
212 dates_(dates)
213 {
214 initialize(compounding,frequency);
215 }
216
217 template <class T>
218 InterpolatedZeroCurve<T>::InterpolatedZeroCurve(
219 const std::vector<Date>& dates,
220 const std::vector<Rate>& yields,
221 const DayCounter& dayCounter,
222 const Calendar& calendar,
223 const T& interpolator,
224 Compounding compounding,
225 Frequency frequency)
226 : ZeroYieldStructure(dates.at(n: 0), calendar, dayCounter),
227 InterpolatedCurve<T>(std::vector<Time>(), yields, interpolator),
228 dates_(dates)
229 {
230 initialize(compounding,frequency);
231 }
232
233 template <class T>
234 InterpolatedZeroCurve<T>::InterpolatedZeroCurve(
235 const std::vector<Date>& dates,
236 const std::vector<Rate>& yields,
237 const DayCounter& dayCounter,
238 const T& interpolator,
239 Compounding compounding,
240 Frequency frequency)
241 : ZeroYieldStructure(dates.at(n: 0), Calendar(), dayCounter),
242 InterpolatedCurve<T>(std::vector<Time>(), yields, interpolator),
243 dates_(dates)
244 {
245 initialize(compounding,frequency);
246 }
247
248 #endif
249
250 template <class T>
251 void InterpolatedZeroCurve<T>::initialize(const Compounding& compounding,
252 const Frequency& frequency)
253 {
254 QL_REQUIRE(dates_.size() >= T::requiredPoints,
255 "not enough input dates given");
256 QL_REQUIRE(this->data_.size() == dates_.size(),
257 "dates/data count mismatch");
258
259 this->setupTimes(dates_, dates_[0], dayCounter());
260
261 if (compounding != Continuous) {
262 // adjusting zero rates to match continuous compounding
263
264 // The first time is 0.0, so we can't use it.
265 // We fall back to about one day.
266 Time dt = 1.0/365;
267 InterestRate r(this->data_[0], dayCounter(), compounding, frequency);
268 this->data_[0] = r.equivalentRate(comp: Continuous, freq: NoFrequency, t: dt);
269
270 for (Size i=1; i<dates_.size(); ++i) {
271 InterestRate r(this->data_[i], dayCounter(), compounding, frequency);
272 this->data_[i] = r.equivalentRate(Continuous, NoFrequency, this->times_[i]);
273 }
274 }
275
276 this->setupInterpolation();
277 this->interpolation_.update();
278 }
279
280}
281
282#endif
283

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