24#ifndef quantext_stripped_optionlet_adapter_sabr_h
25#define quantext_stripped_optionlet_adapter_sabr_h
29#include <ql/math/interpolation.hpp>
30#include <ql/termstructures/interpolatedcurve.hpp>
31#include <ql/termstructures/volatility/flatsmilesection.hpp>
32#include <ql/termstructures/volatility/interpolatedsmilesection.hpp>
33#include <ql/termstructures/volatility/optionlet/optionletvolatilitystructure.hpp>
34#include <ql/termstructures/volatility/optionlet/strippedoptionletbase.hpp>
35#include <ql/utilities/dataformatters.hpp>
42template <
class TimeInterpolator>
51 const TimeInterpolator& ti = TimeInterpolator(),
52 const boost::optional<QuantLib::VolatilityType> outputVolatilityType = boost::none,
53 const std::vector<std::vector<std::pair<Real, bool>>>& initialModelParameters = {},
54 const QuantLib::Size maxCalibrationAttempts = 10,
55 const QuantLib::Real exitEarlyErrorThreshold = 0.005,
56 const QuantLib::Real maxAcceptableError = 0.05);
61 const QuantLib::ext::shared_ptr<QuantLib::StrippedOptionletBase>& sob,
63 const TimeInterpolator& ti = TimeInterpolator(),
64 const boost::optional<QuantLib::VolatilityType> outputVolatilityType = boost::none,
65 const std::vector<std::vector<std::pair<Real, bool>>>& initialModelParameters = {},
66 const QuantLib::Size maxCalibrationAttempts = 10,
67 const QuantLib::Real exitEarlyErrorThreshold = 0.005,
68 const QuantLib::Real maxAcceptableError = 0.05);
72 QuantLib::Date
maxDate()
const override;
77 QuantLib::Rate
minStrike()
const override;
78 QuantLib::Rate
maxStrike()
const override;
100 QuantLib::ext::shared_ptr<QuantLib::StrippedOptionletBase>
optionletBase()
const;
109 QuantLib::ext::shared_ptr<QuantLib::SmileSection>
smileSectionImpl(QuantLib::Time optionTime)
const override;
110 QuantLib::Volatility
volatilityImpl(QuantLib::Time length, QuantLib::Rate strike)
const override;
129 mutable std::map<Real, QuantLib::ext::shared_ptr<ParametricVolatilitySmileSection>>
cache_;
134template <
class TimeInterpolator>
136 const QuantLib::ext::shared_ptr<QuantLib::StrippedOptionletBase>& sob,
138 const boost::optional<QuantLib::VolatilityType> outputVolatilityType,
139 const std::vector<std::vector<std::pair<Real, bool>>>& initialModelParameters,
140 const QuantLib::Size maxCalibrationAttempts,
const QuantLib::Real exitEarlyErrorThreshold,
141 const QuantLib::Real maxAcceptableError)
142 : OptionletVolatilityStructure(sob->settlementDays(), sob->calendar(), sob->businessDayConvention(),
144 optionletBase_(sob), ti_(ti), modelVariant_(modelVariant), outputVolatilityType_(outputVolatilityType),
145 initialModelParameters_(initialModelParameters), maxCalibrationAttempts_(maxCalibrationAttempts),
146 exitEarlyErrorThreshold_(exitEarlyErrorThreshold), maxAcceptableError_(maxAcceptableError) {
150template <
class TimeInterpolator>
152 const QuantLib::Date& referenceDate,
const QuantLib::ext::shared_ptr<QuantLib::StrippedOptionletBase>& sob,
154 const boost::optional<QuantLib::VolatilityType> outputVolatilityType,
155 const std::vector<std::vector<std::pair<Real, bool>>>& initialModelParameters,
156 const QuantLib::Size maxCalibrationAttempts,
const QuantLib::Real exitEarlyErrorThreshold,
157 const QuantLib::Real maxAcceptableError)
158 : OptionletVolatilityStructure(referenceDate, sob->calendar(), sob->businessDayConvention(), sob->dayCounter()),
159 optionletBase_(sob), ti_(ti), modelVariant_(modelVariant), outputVolatilityType_(outputVolatilityType),
160 initialModelParameters_(initialModelParameters), maxCalibrationAttempts_(maxCalibrationAttempts),
161 exitEarlyErrorThreshold_(exitEarlyErrorThreshold), maxAcceptableError_(maxAcceptableError) {
165template <
class TimeInterpolator>
167 return Date::maxDate();
170template <
class TimeInterpolator>
175template <
class TimeInterpolator>
180template <
class TimeInterpolator>
182 return optionletBase_->volatilityType();
185template <
class TimeInterpolator>
187 return optionletBase_->displacement();
191 optionletBase_->update();
192 TermStructure::update();
193 LazyObject::update();
196template <
class TimeInterpolator>
200 atmInterpolation_ = std::make_unique<FlatExtrapolation>(QuantLib::ext::make_shared<LinearInterpolation>(
201 this->optionletBase()->optionletFixingTimes().begin(), this->optionletBase()->optionletFixingTimes().end(),
202 this->optionletBase()->atmOptionletRates().begin()));
203 atmInterpolation_->enableExtrapolation();
204 atmInterpolation_->update();
206 std::vector<ParametricVolatility::MarketSmile> marketSmiles;
207 std::map<std::pair<QuantLib::Real, QuantLib::Real>, std::vector<std::pair<Real, bool>>> modelParameters;
208 QL_REQUIRE(initialModelParameters_.empty() || initialModelParameters_.size() == 1 ||
209 initialModelParameters_.size() == this->optionletBase()->optionletFixingTimes().size(),
210 "SabrStrippedOptionletAdapter: initial model parameters must be empty or their size ("
211 << initialModelParameters_.size()
212 <<
") must be 1 or it must match the number of optionlet fixing times ("
213 << this->optionletBase()->optionletFixingTimes().size() <<
")");
214 for (Size i = 0; i < this->optionletBase()->optionletFixingTimes().size(); ++i) {
215 Real forward = atmInterpolation_->operator()(this->optionletBase()->optionletFixingTimes()[i]);
221 this->optionletBase()->optionletStrikes(i),
222 this->optionletBase()->optionletVolatilities(i)});
223 if (!initialModelParameters_.empty()) {
224 modelParameters[std::make_pair(this->optionletBase()->optionletFixingTimes()[i], Null<Real>())] =
225 initialModelParameters_.size() == 1 ? initialModelParameters_.front() : initialModelParameters_[i];
229 parametricVolatility_ = QuantLib::ext::make_shared<SabrParametricVolatility>(
233 Handle<YieldTermStructure>(), modelParameters, maxCalibrationAttempts_, exitEarlyErrorThreshold_,
234 maxAcceptableError_);
238 optionletBase_->update();
242template <
class TimeInterpolator>
243inline QuantLib::ext::shared_ptr<QuantLib::StrippedOptionletBase>
245 return optionletBase_;
248template <
class TimeInterpolator>
249inline QuantLib::ext::shared_ptr<QuantLib::SmileSection>
252 if (
auto c = cache_.find(optionTime); c != cache_.end()) {
255 Real forward = atmInterpolation_->operator()(optionTime);
256 QuantLib::VolatilityType outVolType = outputVolatilityType_ ? *outputVolatilityType_ : volatilityType();
257 auto tmp = QuantLib::ext::make_shared<ParametricVolatilitySmileSection>(
258 optionTime, Null<Real>(), forward, parametricVolatility_,
261 cache_[optionTime] = tmp;
265template <
class TimeInterpolator>
266inline QuantLib::Volatility
268 return smileSectionImpl(optionTime)->volatility(strike);
@ ShiftedLognormalVolatility
std::unique_ptr< FlatExtrapolation > atmInterpolation_
void performCalculations() const override
QuantLib::Real displacement() const override
TimeInterpolator ti_
The interpolation object in the time direction.
QuantLib::ext::shared_ptr< QuantExt::ParametricVolatility > parametricVolatility() const
void deepUpdate() override
std::map< Real, QuantLib::ext::shared_ptr< ParametricVolatilitySmileSection > > cache_
State.
std::vector< std::vector< std::pair< Real, bool > > > initialModelParameters_
QuantLib::ext::shared_ptr< QuantLib::StrippedOptionletBase > optionletBase_
Base optionlet object that provides the stripped optionlet volatilities.
boost::optional< QuantLib::VolatilityType > outputVolatilityType_
QuantLib::Real exitEarlyErrorThreshold_
QuantExt::SabrParametricVolatility::ModelVariant modelVariant_
SABR specific inputs.
QuantLib::VolatilityType volatilityType() const override
QuantLib::Real maxAcceptableError_
QuantLib::ext::shared_ptr< QuantLib::SmileSection > smileSectionImpl(QuantLib::Time optionTime) const override
QuantLib::Date maxDate() const override
QuantLib::ext::shared_ptr< QuantLib::StrippedOptionletBase > optionletBase() const
QuantLib::ext::shared_ptr< ParametricVolatility > parametricVolatility_
QuantLib::Rate minStrike() const override
SabrStrippedOptionletAdapter(const QuantLib::ext::shared_ptr< QuantLib::StrippedOptionletBase > &sob, const QuantExt::SabrParametricVolatility::ModelVariant modelVariant, const TimeInterpolator &ti=TimeInterpolator(), const boost::optional< QuantLib::VolatilityType > outputVolatilityType=boost::none, const std::vector< std::vector< std::pair< Real, bool > > > &initialModelParameters={}, const QuantLib::Size maxCalibrationAttempts=10, const QuantLib::Real exitEarlyErrorThreshold=0.005, const QuantLib::Real maxAcceptableError=0.05)
QuantLib::Rate maxStrike() const override
QuantLib::Size maxCalibrationAttempts_
QuantLib::Volatility volatilityImpl(QuantLib::Time length, QuantLib::Rate strike) const override