/src/quantlib/ql/termstructures/volatility/interpolatedsmilesection.hpp
Line | Count | Source |
1 | | /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | |
3 | | /* |
4 | | Copyright (C) 2006 Ferdinando Ametrano |
5 | | Copyright (C) 2006 François du Vignaud |
6 | | Copyright (C) 2015 Peter Caspers |
7 | | |
8 | | This file is part of QuantLib, a free-software/open-source library |
9 | | for financial quantitative analysts and developers - http://quantlib.org/ |
10 | | |
11 | | QuantLib is free software: you can redistribute it and/or modify it |
12 | | under the terms of the QuantLib license. You should have received a |
13 | | copy of the license along with this program; if not, please email |
14 | | <quantlib-dev@lists.sf.net>. The license is also available online at |
15 | | <https://www.quantlib.org/license.shtml>. |
16 | | |
17 | | This program is distributed in the hope that it will be useful, but WITHOUT |
18 | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
19 | | FOR A PARTICULAR PURPOSE. See the license for more details. |
20 | | */ |
21 | | |
22 | | /*! \file interpolatedsmilesection.hpp |
23 | | \brief Interpolated smile section class |
24 | | */ |
25 | | |
26 | | #ifndef quantlib_interpolated_smile_section_hpp |
27 | | #define quantlib_interpolated_smile_section_hpp |
28 | | |
29 | | #include <ql/math/interpolations/linearinterpolation.hpp> |
30 | | #include <ql/patterns/lazyobject.hpp> |
31 | | #include <ql/quotes/simplequote.hpp> |
32 | | #include <ql/termstructure.hpp> |
33 | | #include <ql/termstructures/volatility/smilesection.hpp> |
34 | | #include <ql/time/daycounters/actual365fixed.hpp> |
35 | | #include <utility> |
36 | | |
37 | | namespace QuantLib { |
38 | | |
39 | | template<class Interpolator> |
40 | | class InterpolatedSmileSection : public SmileSection, |
41 | | public LazyObject { |
42 | | public: |
43 | | InterpolatedSmileSection(Time expiryTime, |
44 | | std::vector<Rate> strikes, |
45 | | const std::vector<Handle<Quote> >& stdDevHandles, |
46 | | Handle<Quote> atmLevel, |
47 | | const Interpolator& interpolator = Interpolator(), |
48 | | const DayCounter& dc = Actual365Fixed(), |
49 | | VolatilityType type = ShiftedLognormal, |
50 | | Real shift = 0.0); |
51 | | InterpolatedSmileSection(Time expiryTime, |
52 | | std::vector<Rate> strikes, |
53 | | const std::vector<Real>& stdDevs, |
54 | | Real atmLevel, |
55 | | const Interpolator& interpolator = Interpolator(), |
56 | | const DayCounter& dc = Actual365Fixed(), |
57 | | VolatilityType type = ShiftedLognormal, |
58 | | Real shift = 0.0); |
59 | | InterpolatedSmileSection(const Date& d, |
60 | | std::vector<Rate> strikes, |
61 | | const std::vector<Handle<Quote> >& stdDevHandles, |
62 | | Handle<Quote> atmLevel, |
63 | | const DayCounter& dc = Actual365Fixed(), |
64 | | const Interpolator& interpolator = Interpolator(), |
65 | | const Date& referenceDate = Date(), |
66 | | VolatilityType type = ShiftedLognormal, |
67 | | Real shift = 0.0); |
68 | | InterpolatedSmileSection(const Date& d, |
69 | | std::vector<Rate> strikes, |
70 | | const std::vector<Real>& stdDevs, |
71 | | Real atmLevel, |
72 | | const DayCounter& dc = Actual365Fixed(), |
73 | | const Interpolator& interpolator = Interpolator(), |
74 | | const Date& referenceDate = Date(), |
75 | | VolatilityType type = ShiftedLognormal, |
76 | | Real shift = 0.0); |
77 | | |
78 | | void performCalculations() const override; |
79 | | Real varianceImpl(Rate strike) const override; |
80 | | Volatility volatilityImpl(Rate strike) const override; |
81 | 0 | Real minStrike() const override { return strikes_.front(); }Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::minStrike() const Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::minStrike() const |
82 | 0 | Real maxStrike() const override { return strikes_.back(); }Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::maxStrike() const Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::maxStrike() const |
83 | 0 | Real atmLevel() const override { return atmLevel_->value(); }Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::atmLevel() const Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::atmLevel() const |
84 | | void update() override; |
85 | | |
86 | | private: |
87 | | Real exerciseTimeSquareRoot_; |
88 | | std::vector<Rate> strikes_; |
89 | | std::vector<Handle<Quote> > stdDevHandles_; |
90 | | Handle<Quote> atmLevel_; |
91 | | mutable std::vector<Volatility> vols_; |
92 | | mutable Interpolation interpolation_; |
93 | | }; |
94 | | |
95 | | |
96 | | template <class Interpolator> |
97 | | InterpolatedSmileSection<Interpolator>::InterpolatedSmileSection( |
98 | | Time timeToExpiry, |
99 | | std::vector<Rate> strikes, |
100 | | const std::vector<Handle<Quote> >& stdDevHandles, |
101 | | Handle<Quote> atmLevel, |
102 | | const Interpolator& interpolator, |
103 | | const DayCounter& dc, |
104 | | const VolatilityType type, |
105 | | const Real shift) |
106 | | : SmileSection(timeToExpiry, dc, type, shift), |
107 | | exerciseTimeSquareRoot_(std::sqrt(exerciseTime())), strikes_(std::move(strikes)), |
108 | | stdDevHandles_(stdDevHandles), atmLevel_(std::move(atmLevel)), vols_(stdDevHandles.size()) { |
109 | | for (auto& stdDevHandle : stdDevHandles_) |
110 | | LazyObject::registerWith(stdDevHandle); |
111 | | LazyObject::registerWith(atmLevel_); |
112 | | // check strikes!!!!!!!!!!!!!!!!!!!! |
113 | | interpolation_ = interpolator.interpolate(strikes_.begin(), |
114 | | strikes_.end(), |
115 | | vols_.begin()); |
116 | | } |
117 | | |
118 | | template <class Interpolator> |
119 | | InterpolatedSmileSection<Interpolator>::InterpolatedSmileSection( |
120 | | Time timeToExpiry, |
121 | | std::vector<Rate> strikes, |
122 | | const std::vector<Real>& stdDevs, |
123 | | Real atmLevel, |
124 | | const Interpolator& interpolator, |
125 | | const DayCounter& dc, |
126 | | const VolatilityType type, |
127 | | const Real shift) |
128 | 0 | : SmileSection(timeToExpiry, dc, type, shift), |
129 | 0 | exerciseTimeSquareRoot_(std::sqrt(exerciseTime())), strikes_(std::move(strikes)), |
130 | 0 | stdDevHandles_(stdDevs.size()), vols_(stdDevs.size()) { |
131 | | // fill dummy handles to allow generic handle-based |
132 | | // computations later on |
133 | 0 | for (Size i=0; i<stdDevs.size(); ++i) |
134 | 0 | stdDevHandles_[i] = Handle<Quote>(ext::shared_ptr<Quote>(new |
135 | 0 | SimpleQuote(stdDevs[i]))); |
136 | 0 | atmLevel_ = Handle<Quote> |
137 | 0 | (ext::shared_ptr<Quote>(new SimpleQuote(atmLevel))); |
138 | | // check strikes!!!!!!!!!!!!!!!!!!!! |
139 | 0 | interpolation_ = interpolator.interpolate(strikes_.begin(), |
140 | 0 | strikes_.end(), |
141 | 0 | vols_.begin()); |
142 | 0 | } Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::InterpolatedSmileSection(double, std::__1::vector<double, std::__1::allocator<double> >, std::__1::vector<double, std::__1::allocator<double> > const&, double, QuantLib::Cubic const&, QuantLib::DayCounter const&, QuantLib::VolatilityType, double) Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::InterpolatedSmileSection(double, std::__1::vector<double, std::__1::allocator<double> >, std::__1::vector<double, std::__1::allocator<double> > const&, double, QuantLib::Linear const&, QuantLib::DayCounter const&, QuantLib::VolatilityType, double) |
143 | | |
144 | | template <class Interpolator> |
145 | | InterpolatedSmileSection<Interpolator>::InterpolatedSmileSection( |
146 | | const Date& d, |
147 | | std::vector<Rate> strikes, |
148 | | const std::vector<Handle<Quote> >& stdDevHandles, |
149 | | Handle<Quote> atmLevel, |
150 | | const DayCounter& dc, |
151 | | const Interpolator& interpolator, |
152 | | const Date& referenceDate, |
153 | | const VolatilityType type, |
154 | | const Real shift) |
155 | | : SmileSection(d, dc, referenceDate, type, shift), |
156 | | exerciseTimeSquareRoot_(std::sqrt(exerciseTime())), strikes_(std::move(strikes)), |
157 | | stdDevHandles_(stdDevHandles), atmLevel_(std::move(atmLevel)), vols_(stdDevHandles.size()) { |
158 | | for (auto& stdDevHandle : stdDevHandles_) |
159 | | LazyObject::registerWith(stdDevHandle); |
160 | | LazyObject::registerWith(atmLevel_); |
161 | | // check strikes!!!!!!!!!!!!!!!!!!!! |
162 | | interpolation_ = interpolator.interpolate(strikes_.begin(), |
163 | | strikes_.end(), |
164 | | vols_.begin()); |
165 | | } |
166 | | |
167 | | template <class Interpolator> |
168 | | InterpolatedSmileSection<Interpolator>::InterpolatedSmileSection( |
169 | | const Date& d, |
170 | | std::vector<Rate> strikes, |
171 | | const std::vector<Real>& stdDevs, |
172 | | Real atmLevel, |
173 | | const DayCounter& dc, |
174 | | const Interpolator& interpolator, |
175 | | const Date& referenceDate, |
176 | | const VolatilityType type, |
177 | | const Real shift) |
178 | 0 | : SmileSection(d, dc, referenceDate, type, shift), |
179 | 0 | exerciseTimeSquareRoot_(std::sqrt(exerciseTime())), strikes_(std::move(strikes)), |
180 | 0 | stdDevHandles_(stdDevs.size()), vols_(stdDevs.size()) { |
181 | | //fill dummy handles to allow generic handle-based |
182 | | // computations later on |
183 | 0 | for (Size i=0; i<stdDevs.size(); ++i) |
184 | 0 | stdDevHandles_[i] = Handle<Quote>(ext::shared_ptr<Quote>(new |
185 | 0 | SimpleQuote(stdDevs[i]))); |
186 | 0 | atmLevel_ = Handle<Quote> |
187 | 0 | (ext::shared_ptr<Quote>(new SimpleQuote(atmLevel))); |
188 | | // check strikes!!!!!!!!!!!!!!!!!!!! |
189 | 0 | interpolation_ = interpolator.interpolate(strikes_.begin(), |
190 | 0 | strikes_.end(), |
191 | 0 | vols_.begin()); |
192 | 0 | } |
193 | | |
194 | | |
195 | | template <class Interpolator> |
196 | | inline void InterpolatedSmileSection<Interpolator>::performCalculations() |
197 | 0 | const { |
198 | 0 | for (Size i=0; i<stdDevHandles_.size(); ++i) |
199 | 0 | vols_[i] = stdDevHandles_[i]->value()/exerciseTimeSquareRoot_; |
200 | 0 | interpolation_.update(); |
201 | 0 | } Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::performCalculations() const Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::performCalculations() const |
202 | | |
203 | | #ifndef __DOXYGEN__ |
204 | | template <class Interpolator> |
205 | 0 | Real InterpolatedSmileSection<Interpolator>::varianceImpl(Real strike) const { |
206 | 0 | calculate(); |
207 | 0 | Real v = interpolation_(strike, true); |
208 | 0 | return v*v*exerciseTime(); |
209 | 0 | } Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::varianceImpl(double) const Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::varianceImpl(double) const |
210 | | |
211 | | template <class Interpolator> |
212 | 0 | Real InterpolatedSmileSection<Interpolator>::volatilityImpl(Real strike) const { |
213 | 0 | calculate(); |
214 | 0 | return interpolation_(strike, true); |
215 | 0 | } Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::volatilityImpl(double) const Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::volatilityImpl(double) const |
216 | | |
217 | | template <class Interpolator> |
218 | 0 | void InterpolatedSmileSection<Interpolator>::update() { |
219 | 0 | LazyObject::update(); |
220 | 0 | SmileSection::update(); |
221 | 0 | } Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::update() Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::update() |
222 | | #endif |
223 | | |
224 | | } |
225 | | |
226 | | #endif |