41#include <ql/math/interpolations/bilinearinterpolation.hpp>
42#include <ql/math/interpolations/flatextrapolation2d.hpp>
43#include <ql/termstructures/volatility/interpolatedsmilesection.hpp>
45#include <ql/indexes/swapindex.hpp>
46#include <ql/math/rounding.hpp>
51 const std::vector<Period>& optionTenors,
const std::vector<Period>& swapTenors,
52 const std::vector<Spread>& strikeSpreads,
53 const std::vector<std::vector<Handle<Quote> > >& volSpreads,
54 const QuantLib::ext::shared_ptr<SwapIndex>& swapIndexBase,
55 const QuantLib::ext::shared_ptr<SwapIndex>& shortSwapIndexBase,
bool vegaWeightedSmileFit,
56 bool flatExtrapolation,
bool volsAreSpreads)
57 :
SwaptionVolatilityCube(atmVolStructure, optionTenors, swapTenors, strikeSpreads, volSpreads, swapIndexBase,
58 shortSwapIndexBase, vegaWeightedSmileFit),
59 flatExtrapolation_(flatExtrapolation), volsAreSpreads_(volsAreSpreads), volSpreadsInterpolator_(nStrikes_),
60 volSpreadsMatrix_(nStrikes_, Matrix(optionTenors.size(), swapTenors.size(), 0.0)) {
61 QL_REQUIRE(std::find(strikeSpreads_.begin(), strikeSpreads_.end(), 0.0) != strikeSpreads_.end(),
62 "SwaptionVolCube2: strikeSpreads must contain 0.0 for atm vols");
67 SwaptionVolatilityCube::performCalculations();
69 for (Size i = 0; i < nStrikes_; i++)
70 for (Size j = 0; j < nOptionTenors_; j++)
71 for (Size k = 0; k < nSwapTenors_; k++) {
75 for (Size i = 0; i < nStrikes_; i++) {
78 BilinearInterpolation(swapLengths_.begin(), swapLengths_.end(), optionTimes_.begin(),
82 swapLengths_.begin(), swapLengths_.end(), optionTimes_.begin(), optionTimes_.end(),
91 Date optionDate = optionDateFromTime(optionTime);
93 Period swapTenor(
static_cast<Integer
>(rounder(swapLength * 12.0)), Months);
95 optionDate = swapTenor > shortSwapIndexBase_->tenor()
96 ? swapIndexBase_->fixingCalendar().adjust(optionDate, Following)
97 : shortSwapIndexBase_->fixingCalendar().adjust(optionDate, Following);
102 const Period& swapTenor)
const {
104 Rate atmForward = atmStrike(optionDate, swapTenor);
105 Volatility referenceVol =
volsAreSpreads_ ? atmVol_->volatility(optionDate, swapTenor, atmForward) : 0.0;
106 Time optionTime = std::max(1E-6, timeFromReference(optionDate));
107 Real exerciseTimeSqrt = std::sqrt(optionTime);
108 std::vector<Real>
strikes, stdDevs;
110 stdDevs.reserve(nStrikes_);
111 Time length = swapLength(swapTenor);
112 for (Size i = 0; i < nStrikes_; ++i) {
113 strikes.push_back(atmForward + strikeSpreads_[i]);
116 Real shift = atmVol_->shift(optionTime, length);
119 optionTime,
strikes, stdDevs, atmForward, Linear(), Actual365Fixed(), volatilityType(), shift));
122 optionTime,
strikes, stdDevs, atmForward,
LinearFlat(), Actual365Fixed(), volatilityType(), shift));
Linear-interpolation and flat extrapolation factory and traits
void performCalculations() const override
QuantLib::ext::shared_ptr< SmileSection > smileSectionImpl(const Date &optionDate, const Period &swapTenor) const override
std::vector< Matrix > volSpreadsMatrix_
SwaptionVolCube2(const Handle< SwaptionVolatilityStructure > &atmVolStructure, const std::vector< Period > &optionTenors, const std::vector< Period > &swapTenors, const std::vector< Spread > &strikeSpreads, const std::vector< std::vector< Handle< Quote > > > &volSpreads, const QuantLib::ext::shared_ptr< SwapIndex > &swapIndexBase, const QuantLib::ext::shared_ptr< SwapIndex > &shortSwapIndexBase, bool vegaWeightedSmileFit, bool flatExtrapolation, bool volsAreSpreads=true)
const bool volsAreSpreads_
std::vector< Interpolation2D > volSpreadsInterpolator_
const bool flatExtrapolation_
Swaption volatility cube, fit-later-interpolate-early approach.