Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
pricecurve.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2018 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19/*! \file qle/termstructures/pricecurve.hpp
20 \brief Interpolated price curve
21*/
22
23#ifndef quantext_price_curve_hpp
24#define quantext_price_curve_hpp
25
26#include <boost/algorithm/cxx11/is_sorted.hpp>
27
29
30#include <ql/currency.hpp>
31#include <ql/math/comparison.hpp>
32#include <ql/patterns/lazyobject.hpp>
33#include <ql/quote.hpp>
34#include <ql/termstructures/interpolatedcurve.hpp>
35#include <ql/time/calendars/nullcalendar.hpp>
36
37namespace QuantExt {
38
39//! Interpolated price curve
40/*! Class representing a curve of projected prices in the future.
41
42 \warning for consistency, if curve is constructed by inferring times from dates
43 using a given day counter, pass the same day counter to the constructor
44
45 \ingroup termstructures
46*/
47template <class Interpolator>
49 public QuantLib::LazyObject,
50 protected QuantLib::InterpolatedCurve<Interpolator> {
51public:
52 //! \name Constructors
53 //@{
54 //! Curve constructed from periods and prices. No conventions are applied in getting to a date from a period.
55 InterpolatedPriceCurve(const std::vector<QuantLib::Period>& tenors, const std::vector<QuantLib::Real>& prices,
56 const QuantLib::DayCounter& dc, const QuantLib::Currency& currency,
57 const Interpolator& interpolator = Interpolator());
58
59 //! Curve constructed from periods and quotes. No conventions are applied in getting to a date from a period.
60 InterpolatedPriceCurve(const std::vector<QuantLib::Period>& tenors,
61 const std::vector<QuantLib::Handle<QuantLib::Quote> >& quotes,
62 const QuantLib::DayCounter& dc, const QuantLib::Currency& currency,
63 const Interpolator& interpolator = Interpolator());
64
65 //! Curve constructed from dates and prices
66 InterpolatedPriceCurve(const QuantLib::Date& referenceDate, const std::vector<QuantLib::Date>& dates,
67 const std::vector<QuantLib::Real>& prices, const QuantLib::DayCounter& dc,
68 const QuantLib::Currency& currency, const Interpolator& interpolator = Interpolator());
69
70 //! Curve constructed from dates and quotes
71 InterpolatedPriceCurve(const QuantLib::Date& referenceDate, const std::vector<QuantLib::Date>& dates,
72 const std::vector<QuantLib::Handle<QuantLib::Quote> >& quotes,
73 const QuantLib::DayCounter& dc, const QuantLib::Currency& currency,
74 const Interpolator& interpolator = Interpolator());
75 //@}
76
77 //! \name Observer interface
78 //@{
79 void update() override;
80 //@}
81
82 //! \name TermStructure interface
83 //@{
84 QuantLib::Date maxDate() const override;
85 QuantLib::Time maxTime() const override;
86 //@}
87
88 //! \name PriceTermStructure interface
89 //@{
90 QuantLib::Time minTime() const override;
91 std::vector<QuantLib::Date> pillarDates() const override;
92 const QuantLib::Currency& currency() const override { return currency_; }
93 //@}
94
95 //! \name Inspectors
96 //@{
97 const std::vector<QuantLib::Time>& times() const { return this->times_; }
98 const std::vector<QuantLib::Real>& prices() const { return this->data_; }
99 //@}
100
101protected:
102 //! Used by PiecewisePriceCurve
103 InterpolatedPriceCurve(const QuantLib::Date& referenceDate,
104 const QuantLib::DayCounter& dc, const QuantLib::Currency& currency,
105 const Interpolator& interpolator = Interpolator());
106
107 //! \name LazyObject interface
108 //@{
109 void performCalculations() const override;
110 //@}
111
112 //! \name PriceTermStructure implementation
113 //@{
114 QuantLib::Real priceImpl(QuantLib::Time t) const override;
115 //@}
116
117 mutable std::vector<QuantLib::Date> dates_;
118
119private:
120 const QuantLib::Currency currency_;
121 std::vector<QuantLib::Handle<QuantLib::Quote> > quotes_;
122 std::vector<QuantLib::Period> tenors_;
123
124 void initialise();
125 void populateDatesFromTenors() const;
126 void convertDatesToTimes();
127 void getPricesFromQuotes() const;
128};
129
130template <class Interpolator>
131InterpolatedPriceCurve<Interpolator>::InterpolatedPriceCurve(const std::vector<QuantLib::Period>& tenors,
132 const std::vector<QuantLib::Real>& prices,
133 const QuantLib::DayCounter& dc,
134 const QuantLib::Currency& currency,
135 const Interpolator& interpolator)
136 : PriceTermStructure(0, QuantLib::NullCalendar(), dc), QuantLib::InterpolatedCurve<Interpolator>(
137 std::vector<QuantLib::Time>(tenors.size()), prices,
138 interpolator),
139 dates_(tenors.size()), currency_(currency), tenors_(tenors) {
140
141 QL_REQUIRE(boost::algorithm::is_sorted(tenors_.begin(), tenors_.end()), "Tenors must be sorted");
143 initialise();
144}
145
146template <class Interpolator>
148 const std::vector<QuantLib::Period>& tenors, const std::vector<QuantLib::Handle<QuantLib::Quote> >& quotes,
149 const QuantLib::DayCounter& dc, const QuantLib::Currency& currency, const Interpolator& interpolator)
150 : PriceTermStructure(0, QuantLib::NullCalendar(), dc), QuantLib::InterpolatedCurve<Interpolator>(
151 std::vector<QuantLib::Time>(tenors.size()),
152 std::vector<QuantLib::Real>(quotes.size()),
153 interpolator),
154 dates_(tenors.size()), currency_(currency), quotes_(quotes), tenors_(tenors) {
155
156 QL_REQUIRE(boost::algorithm::is_sorted(tenors_.begin(), tenors_.end()), "Tenors must be sorted");
158 initialise();
159
160 // Observe the quotes
161 for (QuantLib::Size i = 0; i < quotes_.size(); ++i) {
162 registerWith(quotes[i]);
163 }
164}
165
166template <class Interpolator>
168 const std::vector<QuantLib::Date>& dates,
169 const std::vector<QuantLib::Real>& prices,
170 const QuantLib::DayCounter& dc,
171 const QuantLib::Currency& currency,
172 const Interpolator& interpolator)
173 : PriceTermStructure(referenceDate, QuantLib::NullCalendar(), dc), QuantLib::InterpolatedCurve<Interpolator>(
174 std::vector<QuantLib::Time>(dates.size()),
175 prices, interpolator),
176 dates_(dates), currency_(currency) {
177
179 initialise();
180}
181
182template <class Interpolator>
184 const QuantLib::Date& referenceDate, const std::vector<QuantLib::Date>& dates,
185 const std::vector<QuantLib::Handle<QuantLib::Quote> >& quotes, const QuantLib::DayCounter& dc,
186 const QuantLib::Currency& currency, const Interpolator& interpolator)
187 : PriceTermStructure(referenceDate, QuantLib::NullCalendar(), dc), QuantLib::InterpolatedCurve<Interpolator>(
188 std::vector<QuantLib::Time>(dates.size()),
189 std::vector<QuantLib::Real>(quotes.size()),
190 interpolator),
191 dates_(dates), currency_(currency), quotes_(quotes) {
192
194 initialise();
195
196 // Observe the quotes
197 for (QuantLib::Size i = 0; i < quotes_.size(); ++i) {
198 registerWith(quotes[i]);
199 }
200}
201
202template <class Interpolator>
204 const QuantLib::Date& referenceDate, const QuantLib::DayCounter& dc,
205 const QuantLib::Currency& currency, const Interpolator& interpolator)
206 : PriceTermStructure(referenceDate, QuantLib::NullCalendar(), dc),
207 QuantLib::InterpolatedCurve<Interpolator>(interpolator), currency_(currency) {}
208
209template <class Interpolator> void InterpolatedPriceCurve<Interpolator>::update() {
210
211 QuantLib::LazyObject::update();
212
213 // TermStructure::update() update part
214 if (moving_) {
215 updated_ = false;
216 }
217}
218
219template <class Interpolator> void InterpolatedPriceCurve<Interpolator>::performCalculations() const {
220 // Calculations need to be performed if the curve is tenor based
221 if (!tenors_.empty()) {
222 populateDatesFromTenors();
223 this->interpolation_.update();
224 }
225
226 // Calculations need to be performed if the curve depends on quotes
227 if (!quotes_.empty()) {
228 getPricesFromQuotes();
229 this->interpolation_.update();
230 }
231}
232
233template <class Interpolator> QuantLib::Date InterpolatedPriceCurve<Interpolator>::maxDate() const {
234 calculate();
235 return dates_.back();
236}
237
238template <class Interpolator> QuantLib::Time InterpolatedPriceCurve<Interpolator>::maxTime() const {
239 calculate();
240 return this->times_.back();
241}
242
243template <class Interpolator> QuantLib::Time InterpolatedPriceCurve<Interpolator>::minTime() const {
244 calculate();
245 return this->times_.front();
246}
247
248template <class Interpolator> std::vector<QuantLib::Date> InterpolatedPriceCurve<Interpolator>::pillarDates() const {
249 calculate();
250 return dates_;
251}
252
253template <class Interpolator> QuantLib::Real InterpolatedPriceCurve<Interpolator>::priceImpl(QuantLib::Time t) const {
254 // Return interpolated/extrapolated price
255 calculate();
256 return this->interpolation_(t, true);
257}
258
259template <class Interpolator> void InterpolatedPriceCurve<Interpolator>::initialise() {
260
261 QL_REQUIRE(this->data_.size() >= Interpolator::requiredPoints, "not enough times for the interpolation method");
262
263 // If we are quotes based, get prices from quotes
264 if (!quotes_.empty()) {
265 getPricesFromQuotes();
266 }
267
268 QL_REQUIRE(this->data_.size() == this->times_.size(), "Number of times must equal number of prices");
269
270 QuantLib::InterpolatedCurve<Interpolator>::setupInterpolation();
271 this->interpolation_.update();
272}
273
274template <class Interpolator> void InterpolatedPriceCurve<Interpolator>::populateDatesFromTenors() const {
275 QuantLib::Date asof = QuantLib::Settings::instance().evaluationDate();
276 for (QuantLib::Size i = 0; i < dates_.size(); ++i) {
277 dates_[i] = asof + tenors_[i];
278 this->times_[i] = timeFromReference(dates_[i]);
279 }
280}
281
283
284 QL_REQUIRE(!dates_.empty(), "Dates cannot be empty for InterpolatedPriceCurve");
285 this->times_[0] = timeFromReference(dates_[0]);
286 for (QuantLib::Size i = 1; i < dates_.size(); ++i) {
287 QL_REQUIRE(dates_[i] > dates_[i - 1], "invalid date (" << dates_[i] << ", vs " << dates_[i - 1] << ")");
288 this->times_[i] = timeFromReference(dates_[i]);
289 QL_REQUIRE(!QuantLib::close(this->times_[i], this->times_[i - 1]), "two dates correspond to the same time "
290 "under this curve's day count convention");
291 }
292}
293
294template <class Interpolator> void InterpolatedPriceCurve<Interpolator>::getPricesFromQuotes() const {
295
296 for (QuantLib::Size i = 0; i < quotes_.size(); ++i) {
297 QL_REQUIRE(!this->quotes_[i].empty(), "price quote at index " << i << " is empty");
298 this->data_[i] = quotes_[i]->value();
299 }
300}
301
302} // namespace QuantExt
303
304#endif
Interpolated price curve.
Definition: pricecurve.hpp:50
const QuantLib::Currency currency_
Definition: pricecurve.hpp:120
QuantLib::Time minTime() const override
The minimum time for which the curve can return values.
Definition: pricecurve.hpp:243
void performCalculations() const override
Definition: pricecurve.hpp:219
InterpolatedPriceCurve(const std::vector< QuantLib::Period > &tenors, const std::vector< QuantLib::Real > &prices, const QuantLib::DayCounter &dc, const QuantLib::Currency &currency, const Interpolator &interpolator=Interpolator())
Curve constructed from periods and prices. No conventions are applied in getting to a date from a per...
Definition: pricecurve.hpp:131
const QuantLib::Currency & currency() const override
The currency in which prices are expressed.
Definition: pricecurve.hpp:92
std::vector< QuantLib::Date > dates_
Definition: pricecurve.hpp:117
const std::vector< QuantLib::Time > & times() const
Definition: pricecurve.hpp:97
std::vector< QuantLib::Period > tenors_
Definition: pricecurve.hpp:122
std::vector< QuantLib::Handle< QuantLib::Quote > > quotes_
Definition: pricecurve.hpp:121
QuantLib::Date maxDate() const override
Definition: pricecurve.hpp:233
const std::vector< QuantLib::Real > & prices() const
Definition: pricecurve.hpp:98
std::vector< QuantLib::Date > pillarDates() const override
The pillar dates for the PriceTermStructure.
Definition: pricecurve.hpp:248
QuantLib::Real priceImpl(QuantLib::Time t) const override
Price calculation.
Definition: pricecurve.hpp:253
QuantLib::Time maxTime() const override
Definition: pricecurve.hpp:238
Term structure of prices.