QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
zabrinterpolation.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2014 Peter Caspers
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
24#ifndef quantlib_zabr_interpolation_hpp
25#define quantlib_zabr_interpolation_hpp
26
27#include <ql/experimental/volatility/zabrsmilesection.hpp>
28#include <ql/math/interpolations/xabrinterpolation.hpp>
29#include <utility>
30
31namespace QuantLib {
32
33namespace detail {
34
35template <typename Evaluation> struct ZabrSpecs {
36 Size dimension() { return 5; }
37 Real eps() { return 0.000001; }
38 void defaultValues(std::vector<Real> &params,
39 std::vector<bool> &paramIsFixed, const Real &forward,
40 const Real expiryTime, const std::vector<Real>& addParams) {
41 if (params[1] == Null<Real>())
42 params[1] = 0.5;
43 if (params[0] == Null<Real>())
44 // adapt alpha to beta level
45 params[0] =
46 0.2 *
47 (params[1] < 0.9999 ? std::pow(forward, 1.0 - params[1]) : Real(1.0));
48 if (params[2] == Null<Real>())
49 params[2] = std::sqrt(0.4);
50 if (params[3] == Null<Real>())
51 params[3] = 0.0;
52 if (params[4] == Null<Real>())
53 params[4] = 1.0;
54 }
55 void guess(Array &values, const std::vector<bool> &paramIsFixed,
56 const Real &forward, const Real expiryTime,
57 const std::vector<Real> &r, const std::vector<Real>& addParams) {
58 Size j = 0;
59 if (!paramIsFixed[1])
60 values[1] = (1.0 - 2E-6) * r[j++] + 1E-6;
61 if (!paramIsFixed[0]) {
62 values[0] = (1.0 - 2E-6) * r[j++] + 1E-6; // lognormal vol guess
63 // adapt this to beta level
64 if (values[1] < 0.999)
65 values[0] *= std::pow(forward, 1.0 - values[1]);
66 }
67 if (!paramIsFixed[2])
68 values[2] = 1.5 * r[j++] + 1E-6;
69 if (!paramIsFixed[3])
70 values[3] = (2.0 * r[j++] - 1.0) * (1.0 - 1E-6);
71 if (!paramIsFixed[4])
72 values[4] = r[j++] * 2.0;
73 }
74 Real eps1() { return .0000001; }
75 Real eps2() { return .9999; }
76 Real dilationFactor() { return 0.001; }
77 Array inverse(const Array &y, const std::vector<bool> &,
78 const std::vector<Real> &, const Real) {
79 Array x(5);
80 x[0] = y[0] < 25.0 + eps1() ? std::sqrt(y[0] - eps1())
81 : Real((y[0] - eps1() + 25.0) / 10.0);
82 x[1] = std::sqrt(-std::log(y[1]));
83 x[2] = std::tan(M_PI*(y[4]/5.0-0.5));
84 x[3] = std::asin(y[3] / eps2());
85 x[4] = std::tan(M_PI*(y[4]/1.9-0.5));
86 return x;
87 }
88 Array direct(const Array &x, const std::vector<bool> &,
89 const std::vector<Real> &, const Real) {
90 Array y(5);
91 y[0] = std::fabs(x[0]) < 5.0 ? Real(x[0] * x[0] + eps1())
92 : (10.0 * std::fabs(x[0]) - 25.0) + eps1();
93 y[1] = std::fabs(x[1]) < std::sqrt(-std::log(eps1()))
94 ? std::exp(-(x[1] * x[1]))
95 : eps1();
96 // limit nu to 5.00
97 y[2] = (std::atan(x[2])/M_PI + 0.5) * 5.0;
98 y[3] = std::fabs(x[3]) < 2.5 * M_PI
99 ? eps2() * std::sin(x[3])
100 : Real(eps2() * (x[3] > 0.0 ? 1.0 : (-1.0)));
101 // limit gamma to 1.9
102 y[4] = (std::atan(x[4])/M_PI + 0.5) * 1.9;
103 return y;
104 }
105 Real weight(const Real strike, const Real forward, const Real stdDev,
106 const std::vector<Real> &addParams) {
107 return blackFormulaStdDevDerivative(strike, forward, stdDev, 1.0);
108 }
110 ext::shared_ptr<type> instance(const Time t, const Real &forward,
111 const std::vector<Real> &params,
112 const std::vector<Real> &addParams) {
113 return ext::make_shared<type>(t, forward, params);
114 }
115};
116} // end namespace detail
117
118
120template <class Evaluation> class ZabrInterpolation : public Interpolation {
121 public:
122 template <class I1, class I2>
124 const I1 &xBegin, // x = strikes
125 const I1 &xEnd,
126 const I2 &yBegin, // y = volatilities
127 Time t, // option expiry
129 Real gamma, bool alphaIsFixed, bool betaIsFixed, bool nuIsFixed,
130 bool rhoIsFixed, bool gammaIsFixed, bool vegaWeighted = true,
131 const ext::shared_ptr<EndCriteria> &endCriteria =
132 ext::shared_ptr<EndCriteria>(),
133 const ext::shared_ptr<OptimizationMethod> &optMethod =
134 ext::shared_ptr<OptimizationMethod>(),
135 const Real errorAccept = 0.0020, const bool useMaxError = false,
136 const Size maxGuesses = 50) {
137 impl_ = ext::shared_ptr<
139 I1, I2,
141 xBegin, xEnd, yBegin, t, forward,
142 {alpha, beta, nu, rho, gamma},
143 {alphaIsFixed, betaIsFixed, nuIsFixed, rhoIsFixed, gammaIsFixed},
144 vegaWeighted, endCriteria, optMethod, errorAccept, useMaxError,
145 maxGuesses));
146 }
147 Real expiry() const { return coeffs().t_; }
148 Real forward() const { return coeffs().forward_; }
149 Real alpha() const { return coeffs().params_[0]; }
150 Real beta() const { return coeffs().params_[1]; }
151 Real nu() const { return coeffs().params_[2]; }
152 Real rho() const { return coeffs().params_[3]; }
153 Real gamma() const { return coeffs().params_[4]; }
154 Real rmsError() const { return coeffs().error_; }
155 Real maxError() const { return coeffs().maxError_; }
156 const std::vector<Real> &interpolationWeights() const {
157 return coeffs().weights_;
158 }
159 EndCriteria::Type endCriteria() { return coeffs().XABREndCriteria_; }
160
161 private:
164 }
165};
166
168template<class Evaluation> class Zabr {
169 public:
171 Real forward,
172 Real alpha,
173 Real beta,
174 Real nu,
175 Real rho,
176 Real gamma,
177 bool alphaIsFixed,
178 bool betaIsFixed,
179 bool nuIsFixed,
180 bool rhoIsFixed,
181 bool gammaIsFixed,
182 bool vegaWeighted = false,
183 ext::shared_ptr<EndCriteria> endCriteria = ext::shared_ptr<EndCriteria>(),
184 ext::shared_ptr<OptimizationMethod> optMethod = ext::shared_ptr<OptimizationMethod>(),
185 const Real errorAccept = 0.0020,
186 const bool useMaxError = false,
187 const Size maxGuesses = 50)
188 : t_(t), forward_(forward), alpha_(alpha), beta_(beta), nu_(nu), rho_(rho),
189 alphaIsFixed_(alphaIsFixed), betaIsFixed_(betaIsFixed), nuIsFixed_(nuIsFixed),
190 rhoIsFixed_(rhoIsFixed), gammaIsFixed_(gammaIsFixed), vegaWeighted_(vegaWeighted),
191 endCriteria_(std::move(endCriteria)), optMethod_(std::move(optMethod)),
192 errorAccept_(errorAccept), useMaxError_(useMaxError), maxGuesses_(maxGuesses) {}
193 template <class I1, class I2>
194 Interpolation interpolate(const I1 &xBegin, const I1 &xEnd,
195 const I2 &yBegin) const {
197 xBegin, xEnd, yBegin, t_, forward_, alpha_, beta_, nu_, rho_,
201 }
202 static const bool global = true;
203
204 private:
210 const ext::shared_ptr<EndCriteria> endCriteria_;
211 const ext::shared_ptr<OptimizationMethod> optMethod_;
213 const bool useMaxError_;
215};
216}
217
218#endif
1-D array used in linear algebra.
Definition: array.hpp:52
abstract base class for interpolation implementations
base class for 1-D interpolations.
ext::shared_ptr< Impl > impl_
template class providing a null value for a given type.
Definition: null.hpp:76
no arbtrage sabr interpolation factory and traits
static const bool global
const ext::shared_ptr< OptimizationMethod > optMethod_
const ext::shared_ptr< EndCriteria > endCriteria_
Zabr(Time t, Real forward, Real alpha, Real beta, Real nu, Real rho, Real gamma, bool alphaIsFixed, bool betaIsFixed, bool nuIsFixed, bool rhoIsFixed, bool gammaIsFixed, bool vegaWeighted=false, ext::shared_ptr< EndCriteria > endCriteria=ext::shared_ptr< EndCriteria >(), ext::shared_ptr< OptimizationMethod > optMethod=ext::shared_ptr< OptimizationMethod >(), const Real errorAccept=0.0020, const bool useMaxError=false, const Size maxGuesses=50)
Interpolation interpolate(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin) const
zabr smile interpolation between discrete volatility points.
const detail::XABRCoeffHolder< detail::ZabrSpecs< Evaluation > > & coeffs() const
ZabrInterpolation(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin, Time t, const Real &forward, Real alpha, Real beta, Real nu, Real rho, Real gamma, bool alphaIsFixed, bool betaIsFixed, bool nuIsFixed, bool rhoIsFixed, bool gammaIsFixed, bool vegaWeighted=true, const ext::shared_ptr< EndCriteria > &endCriteria=ext::shared_ptr< EndCriteria >(), const ext::shared_ptr< OptimizationMethod > &optMethod=ext::shared_ptr< OptimizationMethod >(), const Real errorAccept=0.0020, const bool useMaxError=false, const Size maxGuesses=50)
const std::vector< Real > & interpolationWeights() const
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
Real blackFormulaStdDevDerivative(Rate strike, Rate forward, Real stdDev, Real discount, Real displacement)
STL namespace.
Array inverse(const Array &y, const std::vector< bool > &, const std::vector< Real > &, const Real)
Array direct(const Array &x, const std::vector< bool > &, const std::vector< Real > &, const Real)
Real weight(const Real strike, const Real forward, const Real stdDev, const std::vector< Real > &addParams)
ZabrSmileSection< Evaluation > type
void guess(Array &values, const std::vector< bool > &paramIsFixed, const Real &forward, const Real expiryTime, const std::vector< Real > &r, const std::vector< Real > &addParams)
ext::shared_ptr< type > instance(const Time t, const Real &forward, const std::vector< Real > &params, const std::vector< Real > &addParams)
void defaultValues(std::vector< Real > &params, std::vector< bool > &paramIsFixed, const Real &forward, const Real expiryTime, const std::vector< Real > &addParams)