QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
noarbsabrinterpolation.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_noarbsabr_interpolation_hpp
25#define quantlib_noarbsabr_interpolation_hpp
26
27#include <ql/experimental/volatility/noarbsabrsmilesection.hpp>
28#include <ql/math/interpolations/sabrinterpolation.hpp>
29#include <utility>
30
31namespace QuantLib {
32
33namespace detail {
34
35// we can directly use the smile section as the wrapper
37
39 Size dimension() { return 4; }
40 Real eps() { return 0.000001; }
41 void defaultValues(std::vector<Real> &params,
42 std::vector<bool> &paramIsFixed, const Real &forward,
43 const Real expiryTime, const std::vector<Real> &addParams) {
44 SABRSpecs().defaultValues(params, paramIsFixed, forward, expiryTime, addParams);
45 // check if alpha / beta is admissable, otherwise adjust
46 // if possible (i.e. not fixed, otherwise an exception will
47 // be thrown from the model constructor anyway)
48 Real sigmaI = params[0] * std::pow(forward, params[1] - 1.0);
50 if (!paramIsFixed[0])
51 params[0] = detail::NoArbSabrModel::sigmaI_min * (1.0 + eps()) /
52 std::pow(forward, params[1] - 1.0);
53 else {
54 if (!paramIsFixed[1])
55 params[1] = 1.0 +
57 (1.0 + eps()) / params[0]) /
58 std::log(forward);
59 }
60 }
62 if (!paramIsFixed[0])
63 params[0] = detail::NoArbSabrModel::sigmaI_max * (1.0 - eps()) /
64 std::pow(forward, params[1] - 1.0);
65 else {
66 if (!paramIsFixed[1])
67 params[1] = 1.0 +
69 (1.0 - eps()) / params[0]) /
70 std::log(forward);
71 }
72 }
73 }
74 void guess(Array &values, const std::vector<bool> &paramIsFixed,
75 const Real &forward, const Real expiryTime,
76 const std::vector<Real> &r, const std::vector<Real> &) {
77 Size j = 0;
78 if (!paramIsFixed[1])
82 r[j++];
83 if (!paramIsFixed[0]) {
87 r[j++];
88 sigmaI *= (1.0 - eps());
89 sigmaI += eps() / 2.0;
90 values[0] = sigmaI / std::pow(forward, values[1] - 1.0);
91 }
92 if (!paramIsFixed[2])
96 r[j++];
97 if (!paramIsFixed[3])
101 r[j++];
102 }
103 Array inverse(const Array &y, const std::vector<bool> &paramIsFixed,
104 const std::vector<Real> &params, const Real forward) {
105 Array x(4);
106 x[1] = std::tan((y[1] - detail::NoArbSabrModel::beta_min) /
109 M_PI +
110 M_PI / 2.0);
111 x[0] = std::tan((y[0] * std::pow(forward, y[1] - 1.0) -
115 M_PI -
116 M_PI / 2.0);
117 x[2] = std::tan((y[2] - detail::NoArbSabrModel::nu_min) /
120 M_PI +
121 M_PI / 2.0);
122 x[3] = std::tan((y[3] - detail::NoArbSabrModel::rho_min) /
125 M_PI +
126 M_PI / 2.0);
127 return x;
128 }
129 Array direct(const Array &x, const std::vector<bool> &paramIsFixed,
130 const std::vector<Real> &params, const Real forward) {
131 Array y(4);
132 if (paramIsFixed[1])
133 y[1] = params[1];
134 else
138 (std::atan(x[1]) + M_PI / 2.0) / M_PI;
139 // we compute alpha from sigmaI using beta
140 // if alpha is fixed we have to check if beta is admissable
141 // and adjust if need be
142 if (paramIsFixed[0]) {
143 y[0] = params[0];
144 Real sigmaI = y[0] * std::pow(forward, y[1] - 1.0);
146 y[1] = (1.0 +
148 (1.0 + eps()) / y[0]) /
149 std::log(forward));
150 }
152 y[1] = (1.0 +
154 (1.0 - eps()) / y[0]) /
155 std::log(forward));
156 }
157 } else {
161 (std::atan(x[0]) + M_PI / 2.0) / M_PI;
162 y[0] = sigmaI / std::pow(forward, y[1] - 1.0);
163 }
164 if (paramIsFixed[2])
165 y[2] = params[2];
166 else
170 (std::atan(x[2]) + M_PI / 2.0) / M_PI;
171 if (paramIsFixed[3])
172 y[3] = params[3];
173 else
177 (std::atan(x[3]) + M_PI / 2.0) / M_PI;
178 return y;
179 }
180 Real weight(const Real strike, const Real forward, const Real stdDev,
181 const std::vector<Real> &addParams) {
182 return blackFormulaStdDevDerivative(strike, forward, stdDev, 1.0);
183 }
185 ext::shared_ptr<type> instance(const Time t, const Real &forward,
186 const std::vector<Real> &params,
187 const std::vector<Real> &) {
188 return ext::make_shared<type>(t, forward, params);
189 }
190};
191}
192
195 public:
196 template <class I1, class I2>
198 const I1 &xBegin, // x = strikes
199 const I1 &xEnd,
200 const I2 &yBegin, // y = volatilities
201 Time t, // option expiry
203 bool alphaIsFixed, bool betaIsFixed, bool nuIsFixed, bool rhoIsFixed,
204 bool vegaWeighted = true,
205 const ext::shared_ptr<EndCriteria> &endCriteria =
206 ext::shared_ptr<EndCriteria>(),
207 const ext::shared_ptr<OptimizationMethod> &optMethod =
208 ext::shared_ptr<OptimizationMethod>(),
209 const Real errorAccept = 0.0020, const bool useMaxError = false,
210 const Size maxGuesses = 50, const Real shift = 0.0) {
211
212 QL_REQUIRE(shift==0.0,"NoArbSabrInterpolation for non zero shift not implemented");
213 impl_ = ext::shared_ptr<Interpolation::Impl>(
215 xBegin, xEnd, yBegin, t, forward,
216 {alpha, beta, nu, rho},
217 {alphaIsFixed, betaIsFixed, nuIsFixed, rhoIsFixed},
218 vegaWeighted, endCriteria, optMethod, errorAccept, useMaxError,
219 maxGuesses));
220 }
221 Real expiry() const { return coeffs().t_; }
222 Real forward() const { return coeffs().forward_; }
223 Real alpha() const { return coeffs().params_[0]; }
224 Real beta() const { return coeffs().params_[1]; }
225 Real nu() const { return coeffs().params_[2]; }
226 Real rho() const { return coeffs().params_[3]; }
227 Real rmsError() const { return coeffs().error_; }
228 Real maxError() const { return coeffs().maxError_; }
229 const std::vector<Real> &interpolationWeights() const {
230 return coeffs().weights_;
231 }
232 EndCriteria::Type endCriteria() { return coeffs().XABREndCriteria_; }
233
234 private:
236 return *dynamic_cast<detail::XABRCoeffHolder<detail::NoArbSabrSpecs>*>(impl_.get());
237 }
238};
239
242 public:
244 Real forward,
245 Real alpha,
246 Real beta,
247 Real nu,
248 Real rho,
249 bool alphaIsFixed,
250 bool betaIsFixed,
251 bool nuIsFixed,
252 bool rhoIsFixed,
253 bool vegaWeighted = false,
254 ext::shared_ptr<EndCriteria> endCriteria = ext::shared_ptr<EndCriteria>(),
255 ext::shared_ptr<OptimizationMethod> optMethod = ext::shared_ptr<OptimizationMethod>(),
256 const Real errorAccept = 0.0020,
257 const bool useMaxError = false,
258 const Size maxGuesses = 50)
259 : t_(t), forward_(forward), alpha_(alpha), beta_(beta), nu_(nu), rho_(rho),
260 alphaIsFixed_(alphaIsFixed), betaIsFixed_(betaIsFixed), nuIsFixed_(nuIsFixed),
261 rhoIsFixed_(rhoIsFixed), vegaWeighted_(vegaWeighted), endCriteria_(std::move(endCriteria)),
262 optMethod_(std::move(optMethod)), errorAccept_(errorAccept), useMaxError_(useMaxError),
263 maxGuesses_(maxGuesses) {}
264 template <class I1, class I2>
265 Interpolation interpolate(const I1 &xBegin, const I1 &xEnd,
266 const I2 &yBegin) const {
268 xBegin, xEnd, yBegin, t_, forward_, alpha_, beta_, nu_, rho_,
271 }
272 static const bool global = true;
273
274 private:
280 const ext::shared_ptr<EndCriteria> endCriteria_;
281 const ext::shared_ptr<OptimizationMethod> optMethod_;
283 const bool useMaxError_;
285};
286}
287
288#endif
1-D array used in linear algebra.
Definition: array.hpp:52
base class for 1-D interpolations.
ext::shared_ptr< Impl > impl_
no arbtrage sabr interpolation factory and traits
const ext::shared_ptr< OptimizationMethod > optMethod_
const ext::shared_ptr< EndCriteria > endCriteria_
Interpolation interpolate(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin) const
NoArbSabr(Time t, Real forward, Real alpha, Real beta, Real nu, Real rho, bool alphaIsFixed, bool betaIsFixed, bool nuIsFixed, bool rhoIsFixed, 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)
no arbitrage sabr smile interpolation between discrete volatility points.
NoArbSabrInterpolation(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin, Time t, const Real &forward, Real alpha, Real beta, Real nu, Real rho, bool alphaIsFixed, bool betaIsFixed, bool nuIsFixed, bool rhoIsFixed, 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 Real shift=0.0)
const std::vector< Real > & interpolationWeights() const
const detail::XABRCoeffHolder< detail::NoArbSabrSpecs > & coeffs() 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
NoArbSabrSmileSection NoArbSabrWrapper
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 > &paramIsFixed, const std::vector< Real > &params, const Real forward)
Real weight(const Real strike, const Real forward, const Real stdDev, const std::vector< Real > &addParams)
Array direct(const Array &x, const std::vector< bool > &paramIsFixed, const std::vector< Real > &params, const Real forward)
ext::shared_ptr< type > instance(const Time t, const Real &forward, const std::vector< Real > &params, const std::vector< Real > &)
void defaultValues(std::vector< Real > &params, std::vector< bool > &paramIsFixed, const Real &forward, const Real expiryTime, const std::vector< Real > &addParams)
void guess(Array &values, const std::vector< bool > &paramIsFixed, const Real &forward, const Real expiryTime, const std::vector< Real > &r, const std::vector< Real > &)
void defaultValues(std::vector< Real > &params, std::vector< bool > &, const Real &forward, const Real expiryTime, const std::vector< Real > &addParams)