Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
swaptionvolcube2.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 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/*
20 Copyright (C) 2006 Ferdinando Ametrano
21 Copyright (C) 2006 Katiuscia Manzoni
22 Copyright (C) 2015 Peter Caspers
23
24 This file is part of QuantLib, a free-software/open-source library
25 for financial quantitative analysts and developers - http://quantlib.org/
26
27 QuantLib is free software: you can redistribute it and/or modify it
28 under the terms of the QuantLib license. You should have received a
29 copy of the license along with this program; if not, please email
30 <quantlib-dev@lists.sf.net>. The license is also available online at
31 <http://quantlib.org/license.shtml>.
32
33 This program is distributed in the hope that it will be useful, but WITHOUT
34 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
35 FOR A PARTICULAR PURPOSE. See the license for more details.
36*/
37
40
41#include <ql/math/interpolations/bilinearinterpolation.hpp>
42#include <ql/math/interpolations/flatextrapolation2d.hpp>
43#include <ql/termstructures/volatility/interpolatedsmilesection.hpp>
44
45#include <ql/indexes/swapindex.hpp>
46#include <ql/math/rounding.hpp>
47
48namespace QuantExt {
49
50SwaptionVolCube2::SwaptionVolCube2(const Handle<SwaptionVolatilityStructure>& atmVolStructure,
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");
63}
64
66
67 SwaptionVolatilityCube::performCalculations();
68 //! set volSpreadsMatrix_ by volSpreads_ quotes
69 for (Size i = 0; i < nStrikes_; i++)
70 for (Size j = 0; j < nOptionTenors_; j++)
71 for (Size k = 0; k < nSwapTenors_; k++) {
72 volSpreadsMatrix_[i][j][k] = volSpreads_[j * nSwapTenors_ + k][i]->value();
73 }
74 //! create volSpreadsInterpolator_
75 for (Size i = 0; i < nStrikes_; i++) {
78 BilinearInterpolation(swapLengths_.begin(), swapLengths_.end(), optionTimes_.begin(),
79 optionTimes_.end(), volSpreadsMatrix_[i]);
80 else
81 volSpreadsInterpolator_[i] = FlatExtrapolator2D(QuantLib::ext::make_shared<BilinearInterpolation>(
82 swapLengths_.begin(), swapLengths_.end(), optionTimes_.begin(), optionTimes_.end(),
84 volSpreadsInterpolator_[i].enableExtrapolation();
85 }
86}
87
88QuantLib::ext::shared_ptr<SmileSection> SwaptionVolCube2::smileSectionImpl(Time optionTime, Time swapLength) const {
89
90 calculate();
91 Date optionDate = optionDateFromTime(optionTime);
92 Rounding rounder(0);
93 Period swapTenor(static_cast<Integer>(rounder(swapLength * 12.0)), Months);
94 // ensure that option date is valid fixing date
95 optionDate = swapTenor > shortSwapIndexBase_->tenor()
96 ? swapIndexBase_->fixingCalendar().adjust(optionDate, Following)
97 : shortSwapIndexBase_->fixingCalendar().adjust(optionDate, Following);
98 return smileSectionImpl(optionDate, swapTenor);
99}
100
101QuantLib::ext::shared_ptr<SmileSection> SwaptionVolCube2::smileSectionImpl(const Date& optionDate,
102 const Period& swapTenor) const {
103 calculate();
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;
109 strikes.reserve(nStrikes_);
110 stdDevs.reserve(nStrikes_);
111 Time length = swapLength(swapTenor);
112 for (Size i = 0; i < nStrikes_; ++i) {
113 strikes.push_back(atmForward + strikeSpreads_[i]);
114 stdDevs.push_back(exerciseTimeSqrt * (referenceVol + volSpreadsInterpolator_[i](length, optionTime)));
115 }
116 Real shift = atmVol_->shift(optionTime, length);
118 return QuantLib::ext::shared_ptr<SmileSection>(new InterpolatedSmileSection<Linear>(
119 optionTime, strikes, stdDevs, atmForward, Linear(), Actual365Fixed(), volatilityType(), shift));
120 else
121 return QuantLib::ext::shared_ptr<SmileSection>(new InterpolatedSmileSection<LinearFlat>(
122 optionTime, strikes, stdDevs, atmForward, LinearFlat(), Actual365Fixed(), volatilityType(), shift));
123}
124} // namespace QuantExt
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)
std::vector< Interpolation2D > volSpreadsInterpolator_
flat interpolation decorator
Swaption volatility cube, fit-later-interpolate-early approach.
vector< Real > strikes