23#ifndef quantext_optionlet_curve_hpp
24#define quantext_optionlet_curve_hpp
26#include <ql/math/comparison.hpp>
27#include <ql/math/interpolations/linearinterpolation.hpp>
28#include <ql/termstructures/interpolatedcurve.hpp>
29#include <ql/termstructures/volatility/flatsmilesection.hpp>
30#include <ql/termstructures/volatility/optionlet/optionletvolatilitystructure.hpp>
31#include <ql/utilities/dataformatters.hpp>
42template <
class Interpolator>
44 protected QuantLib::InterpolatedCurve<Interpolator> {
63 const std::vector<QuantLib::Real>&
volatilities, QuantLib::BusinessDayConvention bdc,
64 const QuantLib::DayCounter& dayCounter,
65 const QuantLib::Calendar& calendar = QuantLib::Calendar(),
67 QuantLib::Real
displacement = 0.0,
bool flatFirstPeriod =
true,
68 const Interpolator& interpolator = Interpolator());
72 QuantLib::Date
maxDate()
const override;
77 QuantLib::Rate
minStrike()
const override;
78 QuantLib::Rate
maxStrike()
const override;
89 const std::vector<QuantLib::Time>&
times()
const;
90 const std::vector<QuantLib::Date>&
dates()
const;
92 const std::vector<QuantLib::Real>&
data()
const;
93 std::vector<std::pair<QuantLib::Date, QuantLib::Real> >
nodes()
const;
99 QuantLib::Real
displacement = 0.0,
bool flatFirstPeriod =
true,
100 const Interpolator& interpolator = Interpolator());
103 QuantLib::BusinessDayConvention bdc,
const QuantLib::DayCounter& dayCounter,
105 QuantLib::Real
displacement = 0.0,
bool flatFirstPeriod =
true,
106 const Interpolator& interpolator = Interpolator());
109 QuantLib::BusinessDayConvention bdc,
const QuantLib::DayCounter& dayCounter,
111 QuantLib::Real
displacement = 0.0,
bool flatFirstPeriod =
true,
112 const Interpolator& interpolator = Interpolator());
119 QuantLib::ext::shared_ptr<QuantLib::SmileSection>
smileSectionImpl(QuantLib::Time optionTime)
const override;
123 QuantLib::Real
volatilityImpl(QuantLib::Time optionTime, QuantLib::Rate strike)
const override;
127 mutable std::vector<QuantLib::Date>
dates_;
148template <
class Interpolator>
150 const std::vector<QuantLib::Date>& dates,
const std::vector<QuantLib::Real>& volatilities,
151 QuantLib::BusinessDayConvention bdc,
const QuantLib::DayCounter& dayCounter,
const QuantLib::Calendar& calendar,
152 QuantLib::VolatilityType volatilityType, QuantLib::Real displacement,
bool flatFirstPeriod,
153 const Interpolator& interpolator)
154 :
QuantLib::OptionletVolatilityStructure(dates.at(0), calendar, bdc, dayCounter),
155 QuantLib::InterpolatedCurve<Interpolator>(std::vector<
QuantLib::Time>(), volatilities, interpolator),
156 dates_(dates), volatilityType_(volatilityType), displacement_(displacement), flatFirstPeriod_(flatFirstPeriod) {
160template <
class Interpolator>
162 const QuantLib::DayCounter& dayCounter,
163 QuantLib::VolatilityType volatilityType,
164 QuantLib::Real displacement,
bool flatFirstPeriod,
165 const Interpolator& interpolator)
166 :
QuantLib::OptionletVolatilityStructure(bdc, dayCounter),
QuantLib::InterpolatedCurve<Interpolator>(interpolator),
167 volatilityType_(volatilityType), displacement_(displacement), flatFirstPeriod_(flatFirstPeriod) {}
169template <
class Interpolator>
171 const QuantLib::Date& referenceDate,
const QuantLib::Calendar& calendar, QuantLib::BusinessDayConvention bdc,
172 const QuantLib::DayCounter& dayCounter, QuantLib::VolatilityType volatilityType, QuantLib::Real displacement,
173 bool flatFirstPeriod,
const Interpolator& interpolator)
174 :
QuantLib::OptionletVolatilityStructure(referenceDate, calendar, bdc, dayCounter),
175 QuantLib::InterpolatedCurve<Interpolator>(interpolator), volatilityType_(volatilityType),
176 displacement_(displacement), flatFirstPeriod_(flatFirstPeriod) {}
178template <
class Interpolator>
180 QuantLib::Natural settlementDays,
const QuantLib::Calendar& calendar, QuantLib::BusinessDayConvention bdc,
181 const QuantLib::DayCounter& dayCounter, QuantLib::VolatilityType volatilityType, QuantLib::Real displacement,
182 bool flatFirstPeriod,
const Interpolator& interpolator)
183 :
QuantLib::OptionletVolatilityStructure(settlementDays, calendar, bdc, dayCounter),
184 QuantLib::InterpolatedCurve<Interpolator>(interpolator), volatilityType_(volatilityType),
185 displacement_(displacement), flatFirstPeriod_(flatFirstPeriod) {}
188 if (this->maxDate_ != Date())
189 return this->maxDate_;
190 return dates_.back();
194 if (volatilityType() == QuantLib::ShiftedLognormal) {
195 return displacement_ > 0.0 ? -displacement_ : 0.0;
204 return volatilityType_;
218 if (flatFirstPeriod_)
219 this->data_[0] = this->data_[1];
224 if (flatFirstPeriod_)
225 this->data_[0] = this->data_[1];
231 std::vector<std::pair<QuantLib::Date, QuantLib::Real> > results(dates_.size());
232 for (QuantLib::Size i = 0; i < dates_.size(); ++i)
233 results[i] = std::make_pair(dates_[i], this->data_[i]);
234 if (flatFirstPeriod_)
235 results[0].second = this->data_[1];
240QuantLib::ext::shared_ptr<QuantLib::SmileSection>
242 QuantLib::Volatility vol = volatility(optionTime, 0.0,
true);
243 return QuantLib::ext::make_shared<QuantLib::FlatSmileSection>(
244 optionTime, vol, dayCounter(), QuantLib::Null<QuantLib::Rate>(), volatilityType_, displacement_);
249 if (flatFirstPeriod_ && optionTime < this->times_[1])
250 return this->data_[1];
252 return this->interpolation_(optionTime,
true);
257 QL_REQUIRE(dates_.size() >= T::requiredPoints,
"Not enough input dates given for interpolation method");
258 QL_REQUIRE(this->data_.size() == dates_.size(),
"Number of dates does not equal the number of volatilities");
260 this->times_.resize(dates_.size());
261 this->times_[0] = 0.0;
262 for (QuantLib::Size i = 1; i < dates_.size(); ++i) {
263 QL_REQUIRE(dates_[i] > dates_[i - 1],
"Dates must be increasing but "
264 << QuantLib::io::ordinal(i) <<
" date " << dates_[i]
265 <<
" is not after " << QuantLib::io::ordinal(i - 1) <<
" date "
267 this->times_[i] = dayCounter().yearFraction(dates_[0], dates_[i]);
268 QL_REQUIRE(!QuantLib::close(this->times_[i], this->times_[i - 1]),
269 "The " << QuantLib::io::ordinal(i) <<
" date " << dates_[i] <<
" and "
270 << QuantLib::io::ordinal(i - 1) <<
" date " << dates_[i - 1]
271 <<
" correspond to the same time, " << this->times_[i]
272 <<
", under this curve's day count convention, " << dayCounter());
273 QL_REQUIRE(this->data_[i] > 0.0,
274 "The " << QuantLib::io::ordinal(i) <<
" volatility, " << this->data_[i] <<
", is not positive");
277 if (flatFirstPeriod_)
278 this->data_[0] = this->data_[1];
280 this->setupInterpolation();
QuantLib::Real volatilityImpl(QuantLib::Time optionTime, QuantLib::Rate strike) const override
void initialise()
Initialise the dates and the interpolation object.
QuantLib::Real displacement() const override
std::vector< QuantLib::Date > dates_
The fixing dates of the index underlying the optionlets.
const std::vector< QuantLib::Time > & times() const
const std::vector< QuantLib::Real > & data() const
QuantLib::VolatilityType volatilityType() const override
QuantLib::VolatilityType volatilityType_
The optionlet volatility type.
QuantLib::ext::shared_ptr< QuantLib::SmileSection > smileSectionImpl(QuantLib::Time optionTime) const override
QuantLib::Date maxDate() const override
const std::vector< QuantLib::Real > & volatilities() const
InterpolatedOptionletCurve(const std::vector< QuantLib::Date > &dates, const std::vector< QuantLib::Real > &volatilities, QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter &dayCounter, const QuantLib::Calendar &calendar=QuantLib::Calendar(), QuantLib::VolatilityType volatilityType=QuantLib::Normal, QuantLib::Real displacement=0.0, bool flatFirstPeriod=true, const Interpolator &interpolator=Interpolator())
QuantLib::Rate minStrike() const override
const std::vector< QuantLib::Date > & dates() const
QuantLib::Rate maxStrike() const override
std::vector< std::pair< QuantLib::Date, QuantLib::Real > > nodes() const
QuantLib::Real displacement_
If the volatility type is ShiftedLognormal, this holds the shift value.
bool flatFirstPeriod_
True if the volatility from the initial date to the first date is assumed flat.
InterpolatedOptionletCurve< QuantLib::Linear > OptionletCurve