Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
piecewiseoptionletcurve.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2019 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/piecewiseoptionletcurve.hpp
20 \brief One-dimensional curve of bootstrapped optionlet volatilities
21*/
22
23#ifndef quantext_piecewise_optionlet_curve_hpp
24#define quantext_piecewise_optionlet_curve_hpp
25
26#include <ql/patterns/lazyobject.hpp>
27#include <ql/termstructures/localbootstrap.hpp>
28#include <ql/termstructures/yield/bootstraptraits.hpp>
32
33namespace QuantExt {
34
35//! \e Traits class that is needed for Bootstrap classes to work
37
38 //! Helper type
39 typedef QuantLib::BootstrapHelper<QuantLib::OptionletVolatilityStructure> helper;
40
41 //! Start date of the optionlet volatility term structure
42 static QuantLib::Date initialDate(const QuantLib::OptionletVolatilityStructure* ovts) {
43 return ovts->referenceDate();
44 }
45
46 //! The value at the reference date of the term structure
47 static QuantLib::Real initialValue(const QuantLib::OptionletVolatilityStructure* ovts) { return 0.0; }
48
49 //! Guesses
50 template <class C> static QuantLib::Real guess(QuantLib::Size i, const C* c, bool validData, QuantLib::Size) {
51
52 // Previous value
53 if (validData) {
54 return c->data()[i];
55 }
56
57 // First iteration, not sure if we can do any better here.
58 if (i == 1) {
59 if (c->volatilityType() == QuantLib::Normal) {
60 return 0.0020;
61 } else {
62 return 0.20;
63 }
64 }
65
66 // Flat extrapolation
67 return c->data()[i - 1];
68 }
69
70 //! Minimum value after a given iteration. Lower bound for optionlet volatility is 0.
71 template <class C>
72 static QuantLib::Real minValueAfter(QuantLib::Size i, const C* c, bool validData, QuantLib::Size) {
73 // Choose arbitrarily small positive number
74 if (c->volatilityType() == QuantLib::Normal) {
75 return 1e-8;
76 } else {
77 return 1e-4;
78 }
79 }
80
81 //! Maximum value after a given iteration.
82 template <class C>
83 static QuantLib::Real maxValueAfter(QuantLib::Size i, const C* c, bool validData, QuantLib::Size) {
84 // Choose large and reasonable positive number
85 // Not sure if it makes sense to attempt to use value at previous pillar
86 if (c->volatilityType() == QuantLib::Normal) {
87 return 0.50;
88 } else {
89 return 5;
90 }
91 }
92
93 //! Root finding update
94 static void updateGuess(std::vector<QuantLib::Real>& data, QuantLib::Real vol, QuantLib::Size i) { data[i] = vol; }
95
96 //! Maximum number of iterations to perform in search for root
97 static QuantLib::Size maxIterations() { return 100; }
98};
99
100template <class Interpolator, template <class> class Bootstrap = QuantExt::IterativeBootstrap>
101class PiecewiseOptionletCurve : public InterpolatedOptionletCurve<Interpolator>, public QuantLib::LazyObject {
102
103public:
105 typedef QuantLib::BootstrapHelper<QuantLib::OptionletVolatilityStructure> helper;
106
107 //! Bootstrap needs these typedefs
109 typedef Interpolator interpolator_type;
110
111 //! \name Constructors
112 //@{
113 PiecewiseOptionletCurve(const QuantLib::Date& referenceDate,
114 const std::vector<QuantLib::ext::shared_ptr<helper> >& instruments,
115 const QuantLib::Calendar& calendar, QuantLib::BusinessDayConvention bdc,
116 const QuantLib::DayCounter& dayCounter,
117 QuantLib::VolatilityType volatilityType = QuantLib::Normal,
118 QuantLib::Real displacement = 0.0, bool flatFirstPeriod = true,
119 const Interpolator& i = Interpolator(),
120 const Bootstrap<this_curve>& bootstrap = Bootstrap<this_curve>());
121
122 PiecewiseOptionletCurve(QuantLib::Natural settlementDays,
123 const std::vector<QuantLib::ext::shared_ptr<helper> >& instruments,
124 const QuantLib::Calendar& calendar, QuantLib::BusinessDayConvention bdc,
125 const QuantLib::DayCounter& dayCounter,
126 QuantLib::VolatilityType volatilityType = QuantLib::Normal,
127 QuantLib::Real displacement = 0.0, bool flatFirstPeriod = true,
128 const Interpolator& i = Interpolator(),
129 const Bootstrap<this_curve>& bootstrap = Bootstrap<this_curve>());
130 //@}
131
132 //! \name TermStructure interface
133 //@{
134 QuantLib::Date maxDate() const override;
135 //@}
136
137 //! \name InterpolatedOptionletCurve interface
138 //@{
139 const std::vector<QuantLib::Time>& times() const;
140 const std::vector<QuantLib::Date>& dates() const;
141 const std::vector<QuantLib::Real>& volatilities() const;
142 std::vector<std::pair<QuantLib::Date, QuantLib::Real> > nodes() const;
143 //@}
144
145 //! \name Observer interface
146 //@{
147 void update() override;
148 //@}
149
150private:
152
153 //! \name LazyObject interface
154 //@{
155 void performCalculations() const override;
156 //@}
157
158 //! \name OptionletVolatilityStructure interface
159 //@{
160 QuantLib::Real volatilityImpl(QuantLib::Time optionTime, QuantLib::Rate strike) const override;
161 //@}
162
163 //! Vector of helper instruments to be matched
164 std::vector<QuantLib::ext::shared_ptr<helper> > instruments_;
165
166 //! Accuracy of the match
167 QuantLib::Real accuracy_;
168
169 // Bootstrapper classes are declared as friend to manipulate the curve data
170 friend class Bootstrap<this_curve>;
171 friend class BootstrapError<this_curve>;
172 friend class PenaltyFunction<this_curve>;
173
175};
176
177template <class Interpolator, template <class> class Bootstrap>
179 const QuantLib::Date& referenceDate, const std::vector<QuantLib::ext::shared_ptr<helper> >& instruments,
180 const QuantLib::Calendar& calendar, QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter& dayCounter,
181 QuantLib::VolatilityType volatilityType, QuantLib::Real displacement, bool flatFirstPeriod, const Interpolator& i,
182 const Bootstrap<this_curve>& bootstrap)
183 : base_curve(referenceDate, calendar, bdc, dayCounter, volatilityType, displacement, flatFirstPeriod, i),
184 instruments_(instruments), accuracy_(1e-12), bootstrap_(bootstrap) {
185 bootstrap_.setup(this);
186}
187
188template <class Interpolator, template <class> class Bootstrap>
190 QuantLib::Natural settlementDays, const std::vector<QuantLib::ext::shared_ptr<helper> >& instruments,
191 const QuantLib::Calendar& calendar, QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter& dayCounter,
192 QuantLib::VolatilityType volatilityType, QuantLib::Real displacement, bool flatFirstPeriod, const Interpolator& i,
193 const Bootstrap<this_curve>& bootstrap)
194 : base_curve(settlementDays, calendar, bdc, dayCounter, volatilityType, displacement, flatFirstPeriod, i),
195 instruments_(instruments), accuracy_(1e-12), bootstrap_(bootstrap) {
196 bootstrap_.setup(this);
197}
198
199template <class Interpolator, template <class> class Bootstrap>
201 calculate();
202 return base_curve::maxDate();
203}
204
205template <class Interpolator, template <class> class Bootstrap>
206inline const std::vector<QuantLib::Time>& PiecewiseOptionletCurve<Interpolator, Bootstrap>::times() const {
207 calculate();
208 return base_curve::times();
209}
210
211template <class Interpolator, template <class> class Bootstrap>
212inline const std::vector<QuantLib::Date>& PiecewiseOptionletCurve<Interpolator, Bootstrap>::dates() const {
213 calculate();
214 return base_curve::dates();
215}
216
217template <class Interpolator, template <class> class Bootstrap>
218inline const std::vector<QuantLib::Real>& PiecewiseOptionletCurve<Interpolator, Bootstrap>::volatilities() const {
219 calculate();
220 return base_curve::volatilities();
221}
222
223template <class Interpolator, template <class> class Bootstrap>
224inline std::vector<std::pair<QuantLib::Date, QuantLib::Real> >
226 calculate();
227 return base_curve::nodes();
228}
229
230template <class Interpolator, template <class> class Bootstrap>
232
233 // Derives from InterpolatedOptionletCurve and LazyObject, both of which are Observers and have their own
234 // implementation of the virtual update() method.
235
236 // Call LazyObject::update() to notify Observers but only when this PiecewiseOptionletCurve has been "calculated"
237 // and it has not been "frozen"
238 LazyObject::update();
239
240 // Do not want to call TermStructure::update() here because it will notify all Observers regardless of whether
241 // this PiecewiseOptionletCurve's "calculated" or "frozen" status i.e. defeating the purpose of LazyObject
242
243 // We do not want to miss changes in Settings::instance().evaluationDate() if this TermStructure has a floating
244 // reference date so we make sure that TermStructure::updated_ is set to false.
245 if (this->moving_)
246 this->updated_ = false;
247}
248
249template <class Interpolator, template <class> class Bootstrap>
250inline QuantLib::Real PiecewiseOptionletCurve<Interpolator, Bootstrap>::volatilityImpl(QuantLib::Time optionTime,
251 QuantLib::Rate strike) const {
252 calculate();
253 return base_curve::volatilityImpl(optionTime, strike);
254}
255
256template <class Interpolator, template <class> class Bootstrap>
258 // Perform the bootstrap
259 bootstrap_.calculate();
260}
261
262} // namespace QuantExt
263
264#endif
Helper for bootstrapping optionlet volatilities from cap floor volatilities.
QuantLib::Real displacement() const override
QuantLib::VolatilityType volatilityType() const override
QuantLib::Real volatilityImpl(QuantLib::Time optionTime, QuantLib::Rate strike) const override
const std::vector< QuantLib::Time > & times() const
InterpolatedOptionletCurve< Interpolator > base_curve
QuantLib::Date maxDate() const override
const std::vector< QuantLib::Real > & volatilities() const
QuantLib::Real accuracy_
Accuracy of the match.
PiecewiseOptionletCurve(const QuantLib::Date &referenceDate, const std::vector< QuantLib::ext::shared_ptr< helper > > &instruments, const QuantLib::Calendar &calendar, QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter &dayCounter, QuantLib::VolatilityType volatilityType=QuantLib::Normal, QuantLib::Real displacement=0.0, bool flatFirstPeriod=true, const Interpolator &i=Interpolator(), const Bootstrap< this_curve > &bootstrap=Bootstrap< this_curve >())
QuantLib::BootstrapHelper< QuantLib::OptionletVolatilityStructure > helper
const std::vector< QuantLib::Date > & dates() const
std::vector< QuantLib::ext::shared_ptr< helper > > instruments_
Vector of helper instruments to be matched.
std::vector< std::pair< QuantLib::Date, QuantLib::Real > > nodes() const
PiecewiseOptionletCurve< Interpolator, Bootstrap > this_curve
OptionletTraits traits_type
Bootstrap needs these typedefs.
Straight copy of ql/termstructures/iterativebootstrap.hpp with minor changes.
Interpolated one-dimensional curve of optionlet volatilities.
Traits class that is needed for Bootstrap classes to work
static void updateGuess(std::vector< QuantLib::Real > &data, QuantLib::Real vol, QuantLib::Size i)
Root finding update.
static QuantLib::Size maxIterations()
Maximum number of iterations to perform in search for root.
static QuantLib::Date initialDate(const QuantLib::OptionletVolatilityStructure *ovts)
Start date of the optionlet volatility term structure.
static QuantLib::Real minValueAfter(QuantLib::Size i, const C *c, bool validData, QuantLib::Size)
Minimum value after a given iteration. Lower bound for optionlet volatility is 0.
static QuantLib::Real guess(QuantLib::Size i, const C *c, bool validData, QuantLib::Size)
Guesses.
QuantLib::BootstrapHelper< QuantLib::OptionletVolatilityStructure > helper
Helper type.
static QuantLib::Real initialValue(const QuantLib::OptionletVolatilityStructure *ovts)
The value at the reference date of the term structure.
static QuantLib::Real maxValueAfter(QuantLib::Size i, const C *c, bool validData, QuantLib::Size)
Maximum value after a given iteration.