Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
piecewisepricecurve.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2020 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/piecewisepricecurve.hpp
20 \brief Piecewise interpolated price term structure
21 \ingroup termstructures
22*/
23
24#ifndef quantext_piecewise_price_hpp
25#define quantext_piecewise_price_hpp
26
29#include <ql/termstructures/localbootstrap.hpp>
30#include <ql/termstructures/yield/bootstraptraits.hpp>
31#include <ql/patterns/lazyobject.hpp>
32
33namespace QuantExt {
34
35//! Traits class that is needed for Bootstrap classes to work
37
38 //! Helper type
39 typedef QuantLib::BootstrapHelper<PriceTermStructure> helper;
40
41 //! Start date of the term structure
42 static QuantLib::Date initialDate(const PriceTermStructure* ts) {
43 return ts->referenceDate();
44 }
45
46 //! Dummy value at reference date. Updated below along with first guess.
47 static QuantLib::Real initialValue(const PriceTermStructure* ts) {
48 return 1.0;
49 }
50
51 //! Guesses
52 template <class C>
53 static QuantLib::Real guess(QuantLib::Size i, const C* c, bool validData, QuantLib::Size j) {
54 // Take the market value from the helper. Here, we rely on the all the helpers being alive and sorted.
55 // We will check this in the PiecewisePriceCurve constructor.
56 return c->instrument(i-1)->quote()->value();
57 }
58
59 //! Minimum value after a given iteration.
60 template <class C>
61 static QuantLib::Real minValueAfter(QuantLib::Size i, const C* c, bool validData, QuantLib::Size j) {
62 // Bounds around the guess. Can widen these and try again within the bootstrap.
63 Real g = guess(i, c, validData, j);
64 return g < 0.0 ? g * 5.0 / 4.0 : g * 3.0 / 4.0;
65 }
66
67 //! Maximum value after a given iteration.
68 template <class C>
69 static QuantLib::Real maxValueAfter(QuantLib::Size i, const C* c, bool validData, QuantLib::Size j) {
70 // Bounds around the guess. Can widen these and try again within the bootstrap.
71 Real g = guess(i, c, validData, j);
72 return g < 0.0 ? g * 3.0 / 4.0 : g * 5.0 / 4.0;
73 }
74
75 //! Root finding update
76 static void updateGuess(std::vector<QuantLib::Real>& data, QuantLib::Real price, QuantLib::Size i) {
77 data[i] = price;
78 // Update the value at the reference date also.
79 if (i == 1)
80 data[0] = price;
81 }
82
83 //! Maximum number of iterations to perform in search for root
84 static QuantLib::Size maxIterations() { return 100; }
85};
86
87//! Piecewise price term structure
88/*! This term structure is bootstrapped on a number of instruments which are passed as a vector of handles to
89 PriceHelper instances. Their maturities mark the boundaries of the interpolated segments.
90
91 Each segment is determined sequentially starting from the earliest period to the latest and is chosen so that
92 the instrument whose maturity marks the end of such segment is correctly repriced on the curve.
93
94 \warning The bootstrapping algorithm raises an exception if any two instruments have the same maturity date.
95
96 \ingroup termstructures
97*/
98template <class Interpolator, template <class> class Bootstrap = IterativeBootstrap>
99class PiecewisePriceCurve : public InterpolatedPriceCurve<Interpolator> {
100
101private:
103
104public:
106 typedef QuantLib::BootstrapHelper<PriceTermStructure> helper;
108 typedef Interpolator interpolator_type;
109
110 //! \name Constructors
111 //@{
112 PiecewisePriceCurve(const QuantLib::Date& referenceDate,
113 const std::vector<QuantLib::ext::shared_ptr<helper> >& instruments,
114 const QuantLib::DayCounter& dayCounter,
115 const QuantLib::Currency& currency,
116 const Interpolator& i = Interpolator(),
117 const Bootstrap<this_curve>& bootstrap = Bootstrap<this_curve>());
118 //@}
119
120 //! \name TermStructure interface
121 //@{
122 QuantLib::Date maxDate() const override;
123 QuantLib::Time maxTime() const override;
124 //@}
125
126 //! \name PriceTermStructure interface
127 //@{
128 QuantLib::Time minTime() const override;
129 std::vector<QuantLib::Date> pillarDates() const override;
130 //@}
131
132 //! \name InterpolatedPriceCurve interface
133 //@{
134 const std::vector<QuantLib::Time>& times() const;
135 const std::vector<QuantLib::Real>& prices() const;
136 //@}
137
138 //! Return the i-th instrument
139 const QuantLib::ext::shared_ptr<helper>& instrument(QuantLib::Size i) const;
140
141private:
142 //! \name LazyObject interface
143 //@{
144 void performCalculations() const override;
145 //@}
146
147 //! \name PriceTermStructure implementation
148 //@{
149 QuantLib::Real priceImpl(QuantLib::Time t) const override;
150 //@}
151
152 std::vector<QuantLib::ext::shared_ptr<helper> > instruments_;
154
155 friend class Bootstrap<this_curve>;
156 friend class BootstrapError<this_curve>;
157 friend class PenaltyFunction<this_curve>;
159};
160
161template <class Interpolator, template <class> class Bootstrap>
163 const QuantLib::Date& referenceDate,
164 const std::vector<QuantLib::ext::shared_ptr<helper> >& instruments,
165 const QuantLib::DayCounter& dayCounter,
166 const QuantLib::Currency& currency,
167 const Interpolator& i,
168 const Bootstrap<this_curve>& bootstrap)
169 : base_curve(referenceDate, dayCounter, currency, i), instruments_(instruments),
170 accuracy_(1e-12), bootstrap_(bootstrap) {
171
172 // Ensure that the instruments are sorted and that they are all alive i.e. pillar > reference date.
173 // Need this because of the way that we have set up PriceTraits.
174 std::sort(instruments_.begin(), instruments_.end(), QuantLib::detail::BootstrapHelperSorter());
175
176 auto it = std::find_if(instruments_.begin(), instruments_.end(),
177 [&referenceDate](const QuantLib::ext::shared_ptr<helper>& inst) { return inst->pillarDate() > referenceDate; });
178 QL_REQUIRE(it != instruments_.end(), "PiecewisePriceCurve: all instruments are expired.");
179 if (it != instruments_.begin()) {
180 instruments_.erase(instruments_.begin(), it);
181 }
182
183 bootstrap_.setup(this);
184}
185
186template <class Interpolator, template <class> class Bootstrap>
188 this->calculate();
189 return base_curve::maxDate();
190}
191
192template <class Interpolator, template <class> class Bootstrap>
194 this->calculate();
195 return base_curve::maxTime();
196}
197
198template <class Interpolator, template <class> class Bootstrap>
200 this->calculate();
201 return base_curve::minTime();
202}
203
204template <class Interpolator, template <class> class Bootstrap>
206 this->calculate();
207 return base_curve::pillarDates();
208}
209
210template <class Interpolator, template <class> class Bootstrap>
211const std::vector<QuantLib::Time>& PiecewisePriceCurve<Interpolator, Bootstrap>::times() const {
212 this->calculate();
213 return base_curve::times();
214}
215
216template <class Interpolator, template <class> class Bootstrap>
217const std::vector<QuantLib::Real>& PiecewisePriceCurve<Interpolator, Bootstrap>::prices() const {
218 this->calculate();
219 return base_curve::prices();
220}
221
222template <class Interpolator, template <class> class Bootstrap>
223const QuantLib::ext::shared_ptr<QuantLib::BootstrapHelper<PriceTermStructure> >&
225 QL_REQUIRE(i < instruments_.size(), "Index (" << i << ") greater than the number of instruments (" <<
226 instruments_.size() << ").");
227 return instruments_[i];
228}
229
230template <class Interpolator, template <class> class Bootstrap>
232 bootstrap_.calculate();
233 base_curve::performCalculations();
234}
235
236template <class Interpolator, template <class> class Bootstrap>
237QuantLib::Real PiecewisePriceCurve<Interpolator, Bootstrap>::priceImpl(QuantLib::Time t) const {
238 this->calculate();
239 return base_curve::priceImpl(t);
240}
241
242}
243
244#endif
Interpolated price curve.
Definition: pricecurve.hpp:50
const QuantLib::Currency & currency() const override
The currency in which prices are expressed.
Definition: pricecurve.hpp:92
Piecewise price term structure.
QuantLib::Time minTime() const override
The minimum time for which the curve can return values.
void performCalculations() const override
PiecewisePriceCurve< Interpolator, Bootstrap > this_curve
PiecewisePriceCurve(const QuantLib::Date &referenceDate, const std::vector< QuantLib::ext::shared_ptr< helper > > &instruments, const QuantLib::DayCounter &dayCounter, const QuantLib::Currency &currency, const Interpolator &i=Interpolator(), const Bootstrap< this_curve > &bootstrap=Bootstrap< this_curve >())
Bootstrap< this_curve > bootstrap_
const QuantLib::ext::shared_ptr< helper > & instrument(QuantLib::Size i) const
Return the i-th instrument.
QuantLib::BootstrapHelper< PriceTermStructure > helper
const std::vector< QuantLib::Time > & times() const
InterpolatedPriceCurve< Interpolator > base_curve
QuantLib::Date maxDate() const override
const std::vector< QuantLib::Real > & prices() const
std::vector< QuantLib::Date > pillarDates() const override
The pillar dates for the PriceTermStructure.
std::vector< QuantLib::ext::shared_ptr< helper > > instruments_
QuantLib::Real priceImpl(QuantLib::Time t) const override
Price calculation.
QuantLib::Time maxTime() const override
Straight copy of ql/termstructures/iterativebootstrap.hpp with minor changes.
Interpolated price curve.
Traits class that is needed for Bootstrap classes to work.
static void updateGuess(std::vector< QuantLib::Real > &data, QuantLib::Real price, QuantLib::Size i)
Root finding update.
static QuantLib::Real guess(QuantLib::Size i, const C *c, bool validData, QuantLib::Size j)
Guesses.
QuantLib::BootstrapHelper< PriceTermStructure > helper
Helper type.
static QuantLib::Date initialDate(const PriceTermStructure *ts)
Start date of the term structure.
static QuantLib::Size maxIterations()
Maximum number of iterations to perform in search for root.
static QuantLib::Real maxValueAfter(QuantLib::Size i, const C *c, bool validData, QuantLib::Size j)
Maximum value after a given iteration.
static QuantLib::Real minValueAfter(QuantLib::Size i, const C *c, bool validData, QuantLib::Size j)
Minimum value after a given iteration.
static QuantLib::Real initialValue(const PriceTermStructure *ts)
Dummy value at reference date. Updated below along with first guess.