Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
capfloortermvolcurve.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/capfloortermvolcurve.hpp
20 \brief Cap floor at-the-money term volatility curve
21 \ingroup termstructures
22*/
23
24#ifndef quantext_cap_floor_term_volatility_curve_hpp
25#define quantext_cap_floor_term_volatility_curve_hpp
26
27#include <ql/math/interpolation.hpp>
28#include <ql/patterns/lazyobject.hpp>
29#include <ql/quote.hpp>
30#include <ql/termstructures/interpolatedcurve.hpp>
31#include <ql/termstructures/volatility/capfloor/capfloortermvolatilitystructure.hpp>
32#include <ql/time/daycounters/actual365fixed.hpp>
33#include <ql/utilities/dataformatters.hpp>
34#include <vector>
35
36namespace QuantExt {
37
38/*! Cap floor term volatility curve.
39 Abstract base class for one dimensional curve of cap floor volatilities.
40*/
41class CapFloorTermVolCurve : public QuantLib::CapFloorTermVolatilityStructure {
42public:
43 //! \name Constructors
44 //@{
45 CapFloorTermVolCurve(QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter& dc = QuantLib::DayCounter())
46 : QuantLib::CapFloorTermVolatilityStructure(bdc, dc) {}
47
48 CapFloorTermVolCurve(const QuantLib::Date& referenceDate, const QuantLib::Calendar& cal,
49 QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter& dc = QuantLib::DayCounter())
50 : QuantLib::CapFloorTermVolatilityStructure(referenceDate, cal, bdc, dc) {}
51
52 //! calculate the reference date based on the global evaluation date
53 CapFloorTermVolCurve(QuantLib::Natural settlementDays, const QuantLib::Calendar& cal,
54 QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter& dc = QuantLib::DayCounter())
55 : QuantLib::CapFloorTermVolatilityStructure(settlementDays, cal, bdc, dc) {}
56 //@}
57
58 //! Return the tenors used in the CapFloorTermVolCurve
59 virtual std::vector<QuantLib::Period> optionTenors() const = 0;
60};
61
62//! Interpolated cap floor term volatility curve
63/*! Class that interpolates a vector of cap floor volatilities.
64
65 Based on the class QuantLib::CapFloorTermVolCurve with changes:
66 - allows for a user provided interpolation (main reason for copy)
67 - does not derive from boost::noncopyable (is this needed?)
68*/
69template <class Interpolator>
70class InterpolatedCapFloorTermVolCurve : public QuantLib::LazyObject,
72 protected QuantLib::InterpolatedCurve<Interpolator> {
73
74public:
75 /*! Constructor with floating reference date
76 \param settlementDays Number of days from evaluation date to curve reference date.
77 \param calendar The calendar used to derive cap floor maturity dates from \p optionTenors.
78 Also used to advance from today to reference date if necessary.
79 \param bdc The business day convention used to derive cap floor maturity dates from \p optionTenors.
80 \param optionTenors The cap floor tenors. The first tenor must be positive.
81 \param volatilities The cap floor volatility quotes.
82 \param dayCounter The day counter used to convert from dates to times.
83 \param flatFirstPeriod Set to \c true to use the first element of \p volatilities between time zero and the
84 first element of \p optionTenors. If this is \c false, the volatility at time zero is
85 set to zero and interpolation between time and the first element of \p optionTenors is
86 used.
87 \param interpolator An instance of the interpolator to use. Allows for specification of \p Interpolator
88 instances that use a constructor that takes arguments.
89 */
90 InterpolatedCapFloorTermVolCurve(QuantLib::Natural settlementDays, const QuantLib::Calendar& calendar,
91 QuantLib::BusinessDayConvention bdc,
92 const std::vector<QuantLib::Period>& optionTenors,
93 const std::vector<QuantLib::Handle<QuantLib::Quote> >& volatilities,
94 const QuantLib::DayCounter& dayCounter = QuantLib::Actual365Fixed(),
95 bool flatFirstPeriod = true, const Interpolator& interpolator = Interpolator());
96
97 /*! Constructor with fixed reference date
98 \param settlementDate The curve reference date.
99 \param calendar The calendar used to derive cap floor maturity dates from \p optionTenors.
100 Also used to advance from today to reference date if necessary.
101 \param bdc The business day convention used to derive cap floor maturity dates from \p optionTenors.
102 \param optionTenors The cap floor tenors. The first tenor must be positive.
103 \param volatilities The cap floor volatility quotes.
104 \param dayCounter The day counter used to convert from dates to times.
105 \param flatFirstPeriod Set to \c true to use the first element of \p volatilities between time zero and the
106 first element of \p optionTenors. If this is \c false, the volatility at time zero is
107 set to zero and interpolation between time and the first element of \p optionTenors is
108 used.
109 \param interpolator An instance of the interpolator to use. Allows for specification of \p Interpolator
110 instances that use a constructor that takes arguments.
111 */
112 InterpolatedCapFloorTermVolCurve(const QuantLib::Date& settlementDate, const QuantLib::Calendar& calendar,
113 QuantLib::BusinessDayConvention bdc,
114 const std::vector<QuantLib::Period>& optionTenors,
115 const std::vector<QuantLib::Handle<QuantLib::Quote> >& volatilities,
116 const QuantLib::DayCounter& dayCounter = QuantLib::Actual365Fixed(),
117 bool flatFirstPeriod = true, const Interpolator& interpolator = Interpolator());
118
119 //! \name TermStructure interface
120 //@{
121 QuantLib::Date maxDate() const override;
122 //@}
123
124 //! \name VolatilityTermStructure interface
125 //@{
126 QuantLib::Rate minStrike() const override;
127 QuantLib::Rate maxStrike() const override;
128 //@}
129
130 //! \name LazyObject interface
131 //@{
132 void update() override;
133 void performCalculations() const override;
134 //@}
135
136 //! \name CapFloorTermVolCurve interface
137 //@{
138 std::vector<QuantLib::Period> optionTenors() const override;
139 //@}
140
141 //! \name Inspectors
142 //@{
143 const std::vector<QuantLib::Date>& optionDates() const;
144 const std::vector<QuantLib::Time>& optionTimes() const;
145 //@}
146
147protected:
148 //! \name CapFloorTermVolatilityStructure interface
149 //@{
150 QuantLib::Volatility volatilityImpl(QuantLib::Time length, QuantLib::Rate) const override;
151 //@}
152
153private:
154 //! Check the constructor arguments for consistency
155 void checkInputs() const;
156
157 //! Register this curve with the volatility quotes
159
160 //! Number of underlying cap floor instruments
161 QuantLib::Size nOptionTenors_;
162
163 //! Underlying cap floor tenors
164 std::vector<QuantLib::Period> optionTenors_;
165
166 /*! Underlying cap floor maturity dates.
167 Mutable since if the curve is \c moving, the dates need to be updated from \c const method.
168 */
169 mutable std::vector<QuantLib::Date> optionDates_;
170
171 /*! Time to maturity of underlying cap floor instruments.
172 Mutable since if the curve is \c moving, the times need to be updated from \c const method.
173 */
174 mutable std::vector<QuantLib::Time> optionTimes_;
175
176 //! Cap floor term volatility quotes
177 std::vector<QuantLib::Handle<QuantLib::Quote> > volatilities_;
178
179 //! True for flat volatility from time zero to the first cap floor date
181};
182
183template <class Interpolator>
185 QuantLib::Natural settlementDays, const QuantLib::Calendar& calendar, QuantLib::BusinessDayConvention bdc,
186 const std::vector<QuantLib::Period>& optionTenors,
187 const std::vector<QuantLib::Handle<QuantLib::Quote> >& volatilities, const QuantLib::DayCounter& dayCounter,
188 bool flatFirstPeriod, const Interpolator& interpolator)
189 : CapFloorTermVolCurve(settlementDays, calendar, bdc, dayCounter), QuantLib::InterpolatedCurve<Interpolator>(
190 optionTenors.size() + 1, interpolator),
191 nOptionTenors_(optionTenors.size()), optionTenors_(optionTenors), optionDates_(nOptionTenors_),
192 optionTimes_(nOptionTenors_), volatilities_(volatilities), flatFirstPeriod_(flatFirstPeriod) {
193
194 checkInputs();
196}
197
198template <class Interpolator>
200 const QuantLib::Date& settlementDate, const QuantLib::Calendar& calendar, QuantLib::BusinessDayConvention bdc,
201 const std::vector<QuantLib::Period>& optionTenors,
202 const std::vector<QuantLib::Handle<QuantLib::Quote> >& volatilities, const QuantLib::DayCounter& dayCounter,
203 bool flatFirstPeriod, const Interpolator& interpolator)
204 : CapFloorTermVolCurve(settlementDate, calendar, bdc, dayCounter), QuantLib::InterpolatedCurve<Interpolator>(
205 optionTenors.size() + 1, interpolator),
206 nOptionTenors_(optionTenors.size()), optionTenors_(optionTenors), optionDates_(nOptionTenors_),
207 optionTimes_(nOptionTenors_), volatilities_(volatilities), flatFirstPeriod_(flatFirstPeriod) {
208
209 checkInputs();
211}
212
213template <class Interpolator> QuantLib::Date InterpolatedCapFloorTermVolCurve<Interpolator>::maxDate() const {
214 calculate();
215 return optionDates_.back();
216}
217
218template <class Interpolator> QuantLib::Rate InterpolatedCapFloorTermVolCurve<Interpolator>::minStrike() const {
219 return QL_MIN_REAL;
220}
221
222template <class Interpolator> QuantLib::Rate InterpolatedCapFloorTermVolCurve<Interpolator>::maxStrike() const {
223 return QL_MAX_REAL;
224}
225
226template <class Interpolator> void InterpolatedCapFloorTermVolCurve<Interpolator>::update() {
227 CapFloorTermVolatilityStructure::update();
228 LazyObject::update();
229}
230
232
233 // Populate the InterpolatedCurve members
234 // We make the time zero volatility equal to zero here. However, if flatFirstPeriod is set to true, there is no
235 // interpolation between time 0 and the first option date so this value of 0.0 is effectively ignored.
236 this->times_[0] = 0.0;
237 this->data_[0] = 0.0;
238 for (Size i = 0; i < nOptionTenors_; ++i) {
239 optionDates_[i] = optionDateFromTenor(optionTenors_[i]);
240 optionTimes_[i] = timeFromReference(optionDates_[i]);
241 this->times_[i + 1] = optionTimes_[i];
242 this->data_[i + 1] = volatilities_[i]->value();
243 }
244
245 // Would rather call setupInterpolation() but it is not a const method
246 this->interpolation_ =
247 this->interpolator_.interpolate(this->times_.begin(), this->times_.end(), this->data_.begin());
248}
249
250template <class Interpolator>
252 calculate();
253 return optionTenors_;
254}
255
256template <class Interpolator>
257const std::vector<QuantLib::Date>& InterpolatedCapFloorTermVolCurve<Interpolator>::optionDates() const {
258 calculate();
259 return optionDates_;
260}
261
262template <class Interpolator>
263const std::vector<QuantLib::Time>& InterpolatedCapFloorTermVolCurve<Interpolator>::optionTimes() const {
264 calculate();
265 return optionTimes_;
266}
267
268template <class Interpolator>
269QuantLib::Volatility InterpolatedCapFloorTermVolCurve<Interpolator>::volatilityImpl(QuantLib::Time length,
270 QuantLib::Rate) const {
271
272 calculate();
273
274 if (flatFirstPeriod_ && length < this->times_[1])
275 return this->data_[1];
276 else
277 return this->interpolation_(length, true);
278}
279
280template <class Interpolator> void InterpolatedCapFloorTermVolCurve<Interpolator>::checkInputs() const {
281 QL_REQUIRE(!optionTenors_.empty(), "The option tenor vector cannot be empty");
282 QL_REQUIRE(nOptionTenors_ == volatilities_.size(), "Mismatch between number of option tenors ("
283 << nOptionTenors_ << ") and number of volatilities ("
284 << volatilities_.size() << ")");
285 QL_REQUIRE(optionTenors_[0] > 0 * Days, "First option tenor needs to be positive but is: " << optionTenors_[0]);
286 for (QuantLib::Size i = 1; i < nOptionTenors_; ++i) {
287 QL_REQUIRE(optionTenors_[i] > optionTenors_[i - 1],
288 "Non increasing option tenor: " << QuantLib::io::ordinal(i) << " is " << optionTenors_[i - 1]
289 << " and " << QuantLib::io::ordinal(i + 1) << " is "
290 << optionTenors_[i]);
291 }
292}
293
295 for (QuantLib::Size i = 0; i < volatilities_.size(); ++i)
296 registerWith(volatilities_[i]);
297}
298
299} // namespace QuantExt
300
301#endif
CapFloorTermVolCurve(const QuantLib::Date &referenceDate, const QuantLib::Calendar &cal, QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter &dc=QuantLib::DayCounter())
CapFloorTermVolCurve(QuantLib::Natural settlementDays, const QuantLib::Calendar &cal, QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter &dc=QuantLib::DayCounter())
calculate the reference date based on the global evaluation date
virtual std::vector< QuantLib::Period > optionTenors() const =0
Return the tenors used in the CapFloorTermVolCurve.
CapFloorTermVolCurve(QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter &dc=QuantLib::DayCounter())
Interpolated cap floor term volatility curve.
void registerWithMarketData()
Register this curve with the volatility quotes.
const std::vector< QuantLib::Date > & optionDates() const
InterpolatedCapFloorTermVolCurve(QuantLib::Natural settlementDays, const QuantLib::Calendar &calendar, QuantLib::BusinessDayConvention bdc, const std::vector< QuantLib::Period > &optionTenors, const std::vector< QuantLib::Handle< QuantLib::Quote > > &volatilities, const QuantLib::DayCounter &dayCounter=QuantLib::Actual365Fixed(), bool flatFirstPeriod=true, const Interpolator &interpolator=Interpolator())
std::vector< QuantLib::Period > optionTenors() const override
Return the tenors used in the CapFloorTermVolCurve.
void checkInputs() const
Check the constructor arguments for consistency.
QuantLib::Volatility volatilityImpl(QuantLib::Time length, QuantLib::Rate) const override
const std::vector< QuantLib::Time > & optionTimes() const
std::vector< QuantLib::Handle< QuantLib::Quote > > volatilities_
Cap floor term volatility quotes.
QuantLib::Size nOptionTenors_
Number of underlying cap floor instruments.
std::vector< QuantLib::Period > optionTenors_
Underlying cap floor tenors.
bool flatFirstPeriod_
True for flat volatility from time zero to the first cap floor date.