Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
blackvariancesurfacemoneyness.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2017 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#include <boost/make_shared.hpp>
19#include <ql/math/interpolations/bilinearinterpolation.hpp>
20#include <ql/math/interpolations/linearinterpolation.hpp>
21#include <ql/quotes/simplequote.hpp>
22#include <ql/termstructures/yield/forwardcurve.hpp>
23#include <ql/utilities/dataformatters.hpp>
25
26using namespace std;
27
28namespace QuantExt {
29
31 const Calendar& cal, const Handle<Quote>& spot, const std::vector<Time>& times, const std::vector<Real>& moneyness,
32 const std::vector<std::vector<Handle<Quote> > >& blackVolMatrix, const DayCounter& dayCounter, bool stickyStrike,
33 bool flatExtrapMoneyness)
34 : BlackVarianceTermStructure(0, cal, Following, dayCounter), stickyStrike_(stickyStrike), spot_(spot),
35 times_(times), moneyness_(moneyness), flatExtrapMoneyness_(flatExtrapMoneyness), quotes_(blackVolMatrix) {
36 init();
37}
38
40 const Date& referenceDate, const Calendar& cal, const Handle<Quote>& spot, const std::vector<Time>& times,
41 const std::vector<Real>& moneyness, const std::vector<std::vector<Handle<Quote> > >& blackVolMatrix,
42 const DayCounter& dayCounter, bool stickyStrike, bool flatExtrapMoneyness)
43 : BlackVarianceTermStructure(referenceDate, cal, Following, dayCounter), stickyStrike_(stickyStrike), spot_(spot),
44 times_(times), moneyness_(moneyness), flatExtrapMoneyness_(flatExtrapMoneyness), quotes_(blackVolMatrix) {
45 init();
46}
47
49 TermStructure::update();
50 LazyObject::update();
51}
52
54 for (Size j = 1; j < variances_.columns(); j++) {
55 for (Size i = 0; i < variances_.rows(); i++) {
56 Real vol = quotes_[i][j - 1]->value();
57 variances_[i][j] = times_[j] * vol * vol;
58 }
59 }
60 varianceSurface_.update();
61}
62
64
65 QL_REQUIRE(times_.size() == quotes_.front().size(), "mismatch between times vector and vol matrix columns");
66 QL_REQUIRE(moneyness_.size() == quotes_.size(), "mismatch between moneyness vector and vol matrix rows");
67
68 QL_REQUIRE(times_[0] > 0, "The first time must be greater than 0.0.");
69
70 if (stickyStrike_) {
71 // we don't want to know if the spot has changed - we take a copy here
72 spot_ = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(spot_->value()));
73 } else {
74 registerWith(spot_);
75 }
76
77 // Insert time 0.0 in times_ and initialise variances_ with 0.0.
78 times_.insert(times_.begin(), 0.0);
79 variances_ = Matrix(moneyness_.size(), times_.size(), 0.0);
80
81 // Check times_ and register with quotes
82 for (Size j = 1; j < times_.size(); j++) {
83
84 QL_REQUIRE(times_[j] > times_[j - 1], "Times must be sorted and unique but found that the "
85 << io::ordinal(j) << " time, " << times_[j]
86 << ", is not greater than the " << io::ordinal(j - 1) << " time, "
87 << times_[j - 1] << ".");
88
89 for (Size i = 0; i < moneyness_.size(); i++) {
90 registerWith(quotes_[i][j - 1]);
91 }
92 }
93
95 Bilinear().interpolate(times_.begin(), times_.end(), moneyness_.begin(), moneyness_.end(), variances_);
96
97 notifyObservers();
98}
99
101
102 calculate();
103
104 if (t == 0.0)
105 return 0.0;
106
107 return std::max(blackVarianceMoneyness(t, moneyness(t, strike)), 0.0);
108}
109
111 if (t <= times_.back())
112 return varianceSurface_(t, m, true);
113 else
114 return varianceSurface_(times_.back(), m, true) * t / times_.back();
115}
116
118 const Calendar& cal, const Handle<Quote>& spot, const std::vector<Time>& times, const std::vector<Real>& moneyness,
119 const std::vector<std::vector<Handle<Quote> > >& blackVolMatrix, const DayCounter& dayCounter, bool stickyStrike,
120 bool flatExtrapMoneyness)
121 : BlackVarianceSurfaceMoneyness(cal, spot, times, moneyness, blackVolMatrix, dayCounter, stickyStrike,
122 flatExtrapMoneyness) {}
123
125 const Date& referenceDate, const Calendar& cal, const Handle<Quote>& spot, const std::vector<Time>& times,
126 const std::vector<Real>& moneyness, const std::vector<std::vector<Handle<Quote> > >& blackVolMatrix,
127 const DayCounter& dayCounter, bool stickyStrike, bool flatExtrapMoneyness)
128 : BlackVarianceSurfaceMoneyness(referenceDate, cal, spot, times, moneyness, blackVolMatrix, dayCounter,
129 stickyStrike, flatExtrapMoneyness) {}
130
131Real BlackVarianceSurfaceMoneynessSpot::moneyness(Time, Real strike) const {
132 if (strike == Null<Real>() || strike == 0) {
133 return 1.0;
134 } else {
135 Real moneyness = strike / spot_->value();
137 if (moneyness < moneyness_.front()) {
138 moneyness = moneyness_.front();
139 } else if (moneyness > moneyness_.back()) {
140 moneyness = moneyness_.back();
141 }
142 }
143 return moneyness;
144 }
145}
146
148 const Calendar& cal, const Handle<Quote>& spot, const std::vector<Time>& times, const std::vector<Real>& moneyness,
149 const std::vector<std::vector<Handle<Quote> > >& blackVolMatrix, const DayCounter& dayCounter,
150 const Handle<YieldTermStructure>& forTS, const Handle<YieldTermStructure>& domTS, bool stickyStrike,
151 bool flatExtrapMoneyness)
152 : BlackVarianceSurfaceMoneyness(cal, spot, times, moneyness, blackVolMatrix, dayCounter, stickyStrike,
153 flatExtrapMoneyness),
154 forTS_(forTS), domTS_(domTS) {
155 init();
156}
157
159 const Date& referenceDate, const Calendar& cal, const Handle<Quote>& spot, const std::vector<Time>& times,
160 const std::vector<Real>& moneyness, const std::vector<std::vector<Handle<Quote> > >& blackVolMatrix,
161 const DayCounter& dayCounter, const Handle<YieldTermStructure>& forTS, const Handle<YieldTermStructure>& domTS,
162 bool stickyStrike, bool flatExtrapMoneyness)
163 : BlackVarianceSurfaceMoneyness(referenceDate, cal, spot, times, moneyness, blackVolMatrix, dayCounter,
164 stickyStrike, flatExtrapMoneyness),
165 forTS_(forTS), domTS_(domTS) {
166 init();
167}
168
170
171 if (!stickyStrike_) {
172 QL_REQUIRE(!forTS_.empty(), "foreign discount curve required for atmf surface");
173 QL_REQUIRE(!domTS_.empty(), "domestic discount curve required for atmf surface");
174 registerWith(forTS_);
175 registerWith(domTS_);
176 } else {
177 for (Size i = 0; i < times_.size(); i++) {
178 Time t = times_[i];
179 Real fwd = spot_->value() * forTS_->discount(t) / domTS_->discount(t);
180 forwards_.push_back(fwd);
181 }
182 forwardCurve_ = Linear().interpolate(times_.begin(), times_.end(), forwards_.begin());
183 }
184}
185
186Real BlackVarianceSurfaceMoneynessForward::moneyness(Time t, Real strike) const {
187 Real fwd;
188 Real reqMoneyness; // for flat extrapolation
189 if (strike == Null<Real>() || strike == 0)
190 return 1.0;
191 else {
192 if (stickyStrike_)
193 fwd = forwardCurve_(t, true);
194 else
195 fwd = spot_->value() * forTS_->discount(t) / domTS_->discount(t);
196 reqMoneyness = strike / fwd;
198 if ((strike / fwd) < moneyness_.front()) {
199 reqMoneyness = moneyness_.front();
200 } else if ((strike / fwd) > moneyness_.back()) {
201 reqMoneyness = moneyness_.back();
202 }
203 }
204 return reqMoneyness;
205 }
206}
207
208} // namespace QuantExt
Black volatility surface based on forward moneyness.
BlackVarianceSurfaceMoneynessForward(const Calendar &cal, const Handle< Quote > &spot, const std::vector< Time > &times, const std::vector< Real > &moneyness, const std::vector< std::vector< Handle< Quote > > > &blackVolMatrix, const DayCounter &dayCounter, const Handle< YieldTermStructure > &forTS, const Handle< YieldTermStructure > &domTS, bool stickyStrike=false, bool flatExtrapMoneyness=false)
Abstract Black volatility surface based on moneyness (moneyness defined in subclasses)
BlackVarianceSurfaceMoneyness(const Calendar &cal, const Handle< Quote > &spot, const std::vector< Time > &times, const std::vector< Real > &moneyness, const std::vector< std::vector< Handle< Quote > > > &blackVolMatrix, const DayCounter &dayCounter, bool stickyStrike, bool flatExtrapMoneyness=false)
Real blackVarianceMoneyness(Time t, Real moneyness) const
std::vector< QuantLib::Real > moneyness() const
virtual Real blackVarianceImpl(Time t, Real strike) const override
std::vector< std::vector< Handle< Quote > > > quotes_
BlackVarianceSurfaceMoneynessSpot(const Calendar &cal, const Handle< Quote > &spot, const std::vector< Time > &times, const std::vector< Real > &moneyness, const std::vector< std::vector< Handle< Quote > > > &blackVolMatrix, const DayCounter &dayCounter, bool stickyStrike=false, bool flatExtrapMoneyness=false)