QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
sabrvolsurface.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2007 Ferdinando Ametrano
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
20#include <ql/experimental/volatility/sabrvolsurface.hpp>
21#include <ql/math/interpolations/linearinterpolation.hpp>
22#include <ql/math/interpolations/sabrinterpolation.hpp>
23#include <ql/quotes/simplequote.hpp>
24#include <ql/termstructures/volatility/smilesection.hpp>
25#include <ql/utilities/dataformatters.hpp>
26#include <utility>
27
28namespace QuantLib {
29
30 SabrVolSurface::SabrVolSurface(const ext::shared_ptr<InterestRateIndex>& index,
32 const std::vector<Period>& optionTenors,
33 std::vector<Spread> atmRateSpreads,
34 std::vector<std::vector<Handle<Quote> > > volSpreads)
35 : InterestRateVolSurface(index), atmCurve_(std::move(atmCurve)), optionTenors_(optionTenors),
36 optionTimes_(optionTenors.size()), optionDates_(optionTenors.size()),
37 atmRateSpreads_(std::move(atmRateSpreads)), volSpreads_(std::move(volSpreads)) {
38
40
41 // Creation of reference smile sections
42
43 // Hard coded
44 isAlphaFixed_ = false;
45 isBetaFixed_ = false;
46 isNuFixed_ = false;
47 isRhoFixed_ = false;
48 vegaWeighted_ = true;
49
50 sabrGuesses_.resize(optionTenors_.size());
51
52 for (Size i=0; i<optionTenors_.size(); ++i) {
53
56
57 // Hard coded
58 sabrGuesses_[i][0] = 0.025; // alpha
59 sabrGuesses_[i][1] = 0.5; // beta
60 sabrGuesses_[i][2] = 0.3; // rho
61 sabrGuesses_[i][3] = 0.0; // nu
62 }
64 }
65
66 std::array<Real, 4> SabrVolSurface::sabrGuesses(const Date& d) const {
67
68 // the guesses for sabr parameters are assumed to be piecewise constant
69 if (d<=optionDates_[0]) return sabrGuesses_[0];
70 Size i=0;
71 while (i<optionDates_.size()-1 && d<optionDates_[i])
72 ++i;
73 return sabrGuesses_[i];
74 }
75
76 void SabrVolSurface::updateSabrGuesses(const Date& d, std::array<Real, 4> newGuesses) const {
77
78 Size i=0;
79 while (i<optionDates_.size() && d<=optionDates_[i])
80 ++i;
81 sabrGuesses_[i][0] = newGuesses[0];
82 sabrGuesses_[i][1] = newGuesses[1];
83 sabrGuesses_[i][2] = newGuesses[2];
84 sabrGuesses_[i][3] = newGuesses[3];
85
86 }
87
88 std::vector<Volatility> SabrVolSurface::volatilitySpreads(const Date& d) const {
89
90 Size nOptionsTimes = optionTimes_.size();
91 Size nAtmRateSpreads = atmRateSpreads_.size();
92 std::vector<Volatility> interpolatedVols(nAtmRateSpreads);
93
94 std::vector<Volatility> vols(nOptionsTimes); // the volspread at a given strike
95 for (Size i=0; i<nAtmRateSpreads; ++i) {
96 for (Size j=0; j<nOptionsTimes; ++j) {
97 vols[j] = (**volSpreads_[j][i]).value();
98 }
99 LinearInterpolation interpolator(optionTimes_.begin(), optionTimes_.end(),
100 vols.begin());
101 interpolatedVols[i] = interpolator(timeFromReference(d),true);
102 }
103 return interpolatedVols;
104 }
105
106
109 for (Size i=0; i<optionTenors_.size(); ++i) {
112 }
114
115 }
116
117 ext::shared_ptr<SmileSection>
119
120 auto n = BigInteger(t * 365.0);
121 Date d = referenceDate()+n*Days;
122 // interpolating on ref smile sections
123 std::vector<Volatility> volSpreads = volatilitySpreads(d);
124
125 // calculate sabr fit
126 std::array<Real, 4> sabrParameters1 = sabrGuesses(d);
127
128 ext::shared_ptr<SabrInterpolatedSmileSection> tmp(new
130 index_->fixing(d,true), atmRateSpreads_, true,
131 atmCurve_->atmVol(d), volSpreads,
132 sabrParameters1[0], sabrParameters1[1],
133 sabrParameters1[2], sabrParameters1[3],
137 const ext::shared_ptr<EndCriteria>& endCriteria,
138 const ext::shared_ptr<OptimizationMethod>& method,
139 const DayCounter& dc*/));
140
141 // update guess
142
143 return tmp;
144
145 }
146
148
149 for (Size i=0; i<optionTenors_.size(); ++i) {
150 for (Size j=0; j<atmRateSpreads_.size(); ++j) {
152 }
153 }
154 }
155
157
158 Size nStrikes = atmRateSpreads_.size();
159 QL_REQUIRE(nStrikes>1, "too few strikes (" << nStrikes << ")");
160 for (Size i=1; i<nStrikes; ++i)
161 QL_REQUIRE(atmRateSpreads_[i-1]<atmRateSpreads_[i],
162 "non increasing strike spreads: " <<
163 io::ordinal(i) << " is " << atmRateSpreads_[i-1] << ", " <<
164 io::ordinal(i+1) << " is " << atmRateSpreads_[i]);
165 for (Size i=0; i<volSpreads_.size(); i++)
166 QL_REQUIRE(atmRateSpreads_.size()==volSpreads_[i].size(),
167 "mismatch between number of strikes (" << atmRateSpreads_.size() <<
168 ") and number of columns (" << volSpreads_[i].size() <<
169 ") in the " << io::ordinal(i+1) << " row");
170 }
171
173 auto* v1 = dynamic_cast<Visitor<SabrVolSurface>*>(&v);
174 if (v1 != nullptr)
175 v1->visit(*this);
176 else
178 }
179
180}
degenerate base class for the Acyclic Visitor pattern
Definition: visitor.hpp:33
Concrete date class.
Definition: date.hpp:125
Shared handle to an observable.
Definition: handle.hpp:41
Interest rate volatility (smile) surface.
ext::shared_ptr< InterestRateIndex > index_
void accept(AcyclicVisitor &) override
Date optionDateFromTenor(const Period &) const
period/date conversion
Linear interpolation between discrete points
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
std::vector< Date > optionDates_
Handle< BlackAtmVolCurve > atmCurve_
std::vector< std::array< Real, 4 > > sabrGuesses_
std::array< Real, 4 > sabrGuesses(const Date &) const
const Date & referenceDate() const override
the date at which discount = 1.0 and/or variance = 0.0
void accept(AcyclicVisitor &) override
std::vector< Volatility > volatilitySpreads(const Period &) const
std::vector< Time > optionTimes_
std::vector< Spread > atmRateSpreads_
SabrVolSurface(const ext::shared_ptr< InterestRateIndex > &, Handle< BlackAtmVolCurve >, const std::vector< Period > &optionTenors, std::vector< Spread > atmRateSpreads, std::vector< std::vector< Handle< Quote > > > volSpreads)
std::vector< Period > optionTenors_
std::vector< std::vector< Handle< Quote > > > volSpreads_
ext::shared_ptr< SmileSection > smileSectionImpl(Time) const override
void updateSabrGuesses(const Date &d, std::array< Real, 4 > newGuesses) const
void update() override
Time timeFromReference(const Date &date) const
date/time conversion
Visitor for a specific class
Definition: visitor.hpp:40
virtual void visit(T &)=0
detail::ordinal_holder ordinal(Size)
outputs naturals as 1st, 2nd, 3rd...
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_BIG_INTEGER BigInteger
large integer number
Definition: types.hpp:39
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
STL namespace.