Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
spreadedoptionletvolatility2.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2020 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
21
22#include <ql/math/interpolations/bilinearinterpolation.hpp>
23#include <ql/math/interpolations/flatextrapolation2d.hpp>
24
25namespace QuantExt {
26
27SpreadedOptionletVolatility2::SpreadedOptionletVolatility2(const Handle<OptionletVolatilityStructure>& baseVol,
28 const std::vector<Date>& optionDates,
29 const std::vector<Real>& strikes,
30 const std::vector<std::vector<Handle<Quote>>>& volSpreads)
31 : baseVol_(baseVol), optionDates_(optionDates), strikes_(strikes), volSpreads_(volSpreads) {
32 registerWith(baseVol_);
33
34 QL_REQUIRE(!optionDates_.empty(), "SpreadedOptionletVolatility2(): optionDates are empty");
35 QL_REQUIRE(!strikes_.empty(), "SpreadedOptionletVolatility2(): strikes are empty");
36
37 // add an artificial option date if we only have one to ensure the interpolation is working
38 if (optionDates_.size() == 1) {
39 optionDates_.push_back(optionDates_.back() + 1);
40 volSpreads_.push_back(volSpreads_.back());
41 }
42
43 // add an artificial strike if we only have one to ensure the interpolation is working
44 if (strikes_.size() == 1) {
45 strikes_.push_back(strikes_.back() + 0.01);
46 for (auto& v : volSpreads_)
47 v.push_back(v.back());
48 }
49
50 optionTimes_.resize(optionDates_.size());
51 volSpreadValues_ = Matrix(strikes_.size(), optionDates_.size());
52 for (auto const& v : volSpreads_)
53 for (auto const& q : v)
54 registerWith(q);
55}
56
57DayCounter SpreadedOptionletVolatility2::dayCounter() const { return baseVol_->dayCounter(); }
58Date SpreadedOptionletVolatility2::maxDate() const { return baseVol_->maxDate(); }
59Time SpreadedOptionletVolatility2::maxTime() const { return baseVol_->maxTime(); }
60const Date& SpreadedOptionletVolatility2::referenceDate() const { return baseVol_->referenceDate(); }
61Calendar SpreadedOptionletVolatility2::calendar() const { return baseVol_->calendar(); }
62Natural SpreadedOptionletVolatility2::settlementDays() const { return baseVol_->settlementDays(); }
64 return baseVol_->businessDayConvention();
65}
66Rate SpreadedOptionletVolatility2::minStrike() const { return baseVol_->minStrike(); }
67Rate SpreadedOptionletVolatility2::maxStrike() const { return baseVol_->maxStrike(); }
68VolatilityType SpreadedOptionletVolatility2::volatilityType() const { return baseVol_->volatilityType(); }
69Real SpreadedOptionletVolatility2::displacement() const { return baseVol_->displacement(); }
70
71QuantLib::ext::shared_ptr<SmileSection> SpreadedOptionletVolatility2::smileSectionImpl(Time optionTime) const {
72 calculate();
73 std::vector<Real> volSpreads(strikes_.size());
74 for (Size k = 0; k < strikes_.size(); ++k) {
75 volSpreads[k] = volSpreadInterpolation_(optionTime, strikes_[k]);
76 }
77 return QuantLib::ext::make_shared<SpreadedSmileSection2>(baseVol_->smileSection(optionTime), volSpreads, strikes_);
78}
79
80Volatility SpreadedOptionletVolatility2::volatilityImpl(Time optionTime, Rate strike) const {
81 return smileSectionImpl(optionTime)->volatility(strike);
82}
83
85 for (Size i = 0; i < optionDates_.size(); ++i)
86 optionTimes_[i] = timeFromReference(optionDates_[i]);
87 for (Size k = 0; k < strikes_.size(); ++k) {
88 for (Size i = 0; i < optionDates_.size(); ++i) {
89 QL_REQUIRE(!volSpreads_[i][k].empty(), "SpreadedOptionletVolatility2::performCalculations(): volSpread at "
90 << i << ", " << k << " is empty");
91 volSpreadValues_(k, i) = volSpreads_[i][k]->value();
92 }
93 }
94 volSpreadInterpolation_ = FlatExtrapolator2D(QuantLib::ext::make_shared<BilinearInterpolation>(
95 optionTimes_.begin(), optionTimes_.end(), strikes_.begin(), strikes_.end(), volSpreadValues_));
96 volSpreadInterpolation_.enableExtrapolation();
97}
98
100 OptionletVolatilityStructure::update();
101 LazyObject::update();
102}
103
105 baseVol_->update();
106 update();
107}
108
109} // namespace QuantExt
SpreadedOptionletVolatility2(const Handle< OptionletVolatilityStructure > &baseVol, const std::vector< Date > &optionDates, const std::vector< Real > &strikes, const std::vector< std::vector< Handle< Quote > > > &volSpreads)
Volatility volatilityImpl(Time optionTime, Rate strike) const override
Handle< OptionletVolatilityStructure > baseVol_
std::vector< std::vector< Handle< Quote > > > volSpreads_
QuantLib::ext::shared_ptr< SmileSection > smileSectionImpl(Time optionTime) const override
BusinessDayConvention businessDayConvention() const override
Optionlet volatility with overlayed bilinearly interpolated spread surface.
smile section with linear interpolated vol spreads
vector< Real > strikes