QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
analytichestonengine.hpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2004, 2005, 2008 Klaus Spanderen
5 Copyright (C) 2007 StatPro Italia srl
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21/*! \file analytichestonengine.hpp
22 \brief analytic Heston-model engine
23*/
24
25#ifndef quantlib_analytic_heston_engine_hpp
26#define quantlib_analytic_heston_engine_hpp
27
28#include <ql/utilities/null.hpp>
34#include <ql/functional.hpp>
35#include <complex>
36
37namespace QuantLib {
38
39 //! analytic Heston-model engine based on Fourier transform
40
41 /*! Integration detail:
42 Two algebraically equivalent formulations of the complex
43 logarithm of the Heston model exist. Gatherals [2005]
44 (also Duffie, Pan and Singleton [2000], and Schoutens,
45 Simons and Tistaert[2004]) version does not cause
46 discoutinuities whereas the original version (e.g. Heston [1993])
47 needs some sort of "branch correction" to work properly.
48 Gatheral's version does also work with adaptive integration
49 routines and should be preferred over the original Heston version.
50 */
51
52 /*! References:
53
54 Heston, Steven L., 1993. A Closed-Form Solution for Options
55 with Stochastic Volatility with Applications to Bond and
56 Currency Options. The review of Financial Studies, Volume 6,
57 Issue 2, 327-343.
58
59 A. Sepp, Pricing European-Style Options under Jump Diffusion
60 Processes with Stochastic Volatility: Applications of Fourier
61 Transform (<http://math.ut.ee/~spartak/papers/stochjumpvols.pdf>)
62
63 R. Lord and C. Kahl, Why the rotation count algorithm works,
64 http://papers.ssrn.com/sol3/papers.cfm?abstract_id=921335
65
66 H. Albrecher, P. Mayer, W.Schoutens and J. Tistaert,
67 The Little Heston Trap, http://www.schoutens.be/HestonTrap.pdf
68
69 J. Gatheral, The Volatility Surface: A Practitioner's Guide,
70 Wiley Finance
71
72 F. Le Floc'h, Fourier Integration and Stochastic Volatility
73 Calibration,
74 https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2362968
75
76 L. Andersen, and V. Piterbarg, 2010,
77 Interest Rate Modeling, Volume I: Foundations and Vanilla Models,
78 Atlantic Financial Press London.
79
80 L. Andersen and M. Lake, 2018
81 Robust High-Precision Option Pricing by Fourier Transforms:
82 Contour Deformations and Double-Exponential Quadrature,
83 https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3231626
84
85 \ingroup vanillaengines
86
87 \test the correctness of the returned value is tested by
88 reproducing results available in web/literature
89 and comparison with Black pricing.
90 */
92 : public GenericModelEngine<HestonModel,
93 VanillaOption::arguments,
94 VanillaOption::results> {
95 public:
96 class Integration;
97 class OptimalAlpha;
98 class AP_Helper;
99
101 // Gatheral form of characteristic function w/o control variate
103 // old branch correction form of the characteristic function w/o control variate
105 // Gatheral form with Andersen-Piterbarg control variate
107 // same as AndersenPiterbarg, but a slightly better control variate
109 // Gatheral form with asymptotic expansion of the characteristic function as control variate
110 // https://hpcquantlib.wordpress.com/2020/08/30/a-novel-control-variate-for-the-heston-model
112 // angled contour shift integral with control variate
114 // angled contour shift integral w/o control variate
116 // auto selection of best control variate algorithm from above
118 };
119
120 // Simple to use constructor: Using adaptive
121 // Gauss-Lobatto integration and Gatheral's version of complex log.
122 // Be aware: using a too large number for maxEvaluations might result
123 // in a stack overflow as the Lobatto integration is a recursive
124 // algorithm.
125 AnalyticHestonEngine(const ext::shared_ptr<HestonModel>& model,
126 Real relTolerance, Size maxEvaluations);
127
128 // Constructor using Laguerre integration
129 // and Gatheral's version of complex log.
130 AnalyticHestonEngine(const ext::shared_ptr<HestonModel>& model,
131 Size integrationOrder = 144);
132
133 // Constructor giving full control
134 // over the Fourier integration algorithm
135 AnalyticHestonEngine(const ext::shared_ptr<HestonModel>& model,
136 ComplexLogFormula cpxLog, const Integration& itg,
137 Real andersenPiterbargEpsilon = 1e-25,
138 Real alpha = -0.5);
139
140 void calculate() const override;
141
142 // normalized characteristic function
143 std::complex<Real> chF(const std::complex<Real>& z, Time t) const;
144 std::complex<Real> lnChF(const std::complex<Real>& z, Time t) const;
145
147
148 [[deprecated("Use AnalyticHestonEngine::priceVanillaPayoff instead.")]]
149 static void doCalculation(Real riskFreeDiscount,
150 Real dividendDiscount,
151 Real spotPrice,
152 Real strikePrice,
153 Real term,
154 Real kappa,
155 Real theta,
156 Real sigma,
157 Real v0,
158 Real rho,
159 const TypePayoff& type,
160 const Integration& integration,
161 ComplexLogFormula cpxLog,
162 const AnalyticHestonEngine* enginePtr,
163 Real& value,
164 Size& evaluations);
165
167 const ext::shared_ptr<PlainVanillaPayoff>& payoff,
168 const Date& maturity) const;
169
171 const ext::shared_ptr<PlainVanillaPayoff>& payoff, Time maturity) const;
172
175
176 protected:
177 // call back for extended stochastic volatility
178 // plus jump diffusion engines like bates model
179 virtual std::complex<Real> addOnTerm(Real phi,
180 Time t,
181 Size j) const;
182
183 private:
184 class Fj_Helper;
185
187 const ext::shared_ptr<PlainVanillaPayoff>& payoff,
188 Time maturity, Real fwd) const;
189
190
193 const ext::shared_ptr<Integration> integration_;
195 };
196
197
199 public:
200 // non adaptive integration algorithms based on Gaussian quadrature
201 static Integration gaussLaguerre (Size integrationOrder = 128);
202 static Integration gaussLegendre (Size integrationOrder = 128);
203 static Integration gaussChebyshev (Size integrationOrder = 128);
204 static Integration gaussChebyshev2nd(Size integrationOrder = 128);
205
206 // Gatheral's version has to be used for an adaptive integration
207 // algorithm .Be aware: using a too large number for maxEvaluations might
208 // result in a stack overflow as the these integrations are based on
209 // recursive algorithms.
210 static Integration gaussLobatto(Real relTolerance, Real absTolerance,
211 Size maxEvaluations = 1000,
212 bool useConvergenceEstimate = false);
213
214 // usually these routines have a poor convergence behavior.
215 static Integration gaussKronrod(Real absTolerance,
216 Size maxEvaluations = 1000);
217 static Integration simpson(Real absTolerance,
218 Size maxEvaluations = 1000);
219 static Integration trapezoid(Real absTolerance,
220 Size maxEvaluations = 1000);
221 static Integration discreteSimpson(Size evaluation = 1000);
222 static Integration discreteTrapezoid(Size evaluation = 1000);
223 static Integration expSinh(Real relTolerance = 1e-8);
224
226 Real c_inf, Real epsilon, Real v0, Real t);
227
228 Real calculate(Real c_inf,
229 const ext::function<Real(Real)>& f,
230 const ext::function<Real()>& maxBound = {},
231 Real scaling = 1.0) const;
232
233 Real calculate(Real c_inf,
234 const ext::function<Real(Real)>& f,
235 Real maxBound) const;
236
238 bool isAdaptiveIntegration() const;
239
240 private:
247
248 Integration(Algorithm intAlgo, ext::shared_ptr<GaussianQuadrature> quadrature);
249
250 Integration(Algorithm intAlgo, ext::shared_ptr<Integrator> integrator);
251
253 const ext::shared_ptr<Integrator> integrator_;
254 const ext::shared_ptr<GaussianQuadrature> gaussianQuadrature_;
255 };
256
258 public:
259 AP_Helper(Time term, Real fwd, Real strike,
260 ComplexLogFormula cpxLog,
261 const AnalyticHestonEngine* enginePtr,
262 Real alpha = -0.5);
263
264 Real operator()(Real u) const;
266
267 private:
268 const Time term_;
274 std::complex<Real> phi_, psi_;
275 };
276
277
279 public:
281 Time t,
282 const AnalyticHestonEngine* enginePtr);
283
284 Real operator()(Real strike) const;
285 std::pair<Real, Real> alphaGreaterZero(Real strike) const;
286 std::pair<Real, Real> alphaSmallerMinusOne(Real strike) const;
287
289 Real M(Real k) const;
290 Real k(Real x, Integer sgn) const;
291 Real alphaMin(Real strike) const;
292 Real alphaMax(Real strike) const;
293
294 private:
295 std::pair<Real, Real> findMinima(Real lower, Real upper, Real strike) const;
296
298
299 const Real eps_;
300
303 mutable Size evaluations_ = 0;
304 };
305
306
307 inline std::complex<Real> AnalyticHestonEngine::addOnTerm(
308 Real, Time, Size) const {
309 return std::complex<Real>(0,0);
310 }
311}
312
313#endif
const AnalyticHestonEngine *const enginePtr_
static Real andersenPiterbargIntegrationLimit(Real c_inf, Real epsilon, Real v0, Real t)
static Integration discreteSimpson(Size evaluation=1000)
static Integration gaussChebyshev2nd(Size integrationOrder=128)
static Integration simpson(Real absTolerance, Size maxEvaluations=1000)
const ext::shared_ptr< GaussianQuadrature > gaussianQuadrature_
static Integration gaussLegendre(Size integrationOrder=128)
static Integration gaussLobatto(Real relTolerance, Real absTolerance, Size maxEvaluations=1000, bool useConvergenceEstimate=false)
static Integration gaussChebyshev(Size integrationOrder=128)
static Integration expSinh(Real relTolerance=1e-8)
static Integration trapezoid(Real absTolerance, Size maxEvaluations=1000)
static Integration gaussLaguerre(Size integrationOrder=128)
static Integration gaussKronrod(Real absTolerance, Size maxEvaluations=1000)
const ext::shared_ptr< Integrator > integrator_
static Integration discreteTrapezoid(Size evaluation=1000)
std::pair< Real, Real > alphaGreaterZero(Real strike) const
std::pair< Real, Real > alphaSmallerMinusOne(Real strike) const
std::pair< Real, Real > findMinima(Real lower, Real upper, Real strike) const
const AnalyticHestonEngine *const enginePtr_
analytic Heston-model engine based on Fourier transform
std::complex< Real > lnChF(const std::complex< Real > &z, Time t) const
static void doCalculation(Real riskFreeDiscount, Real dividendDiscount, Real spotPrice, Real strikePrice, Real term, Real kappa, Real theta, Real sigma, Real v0, Real rho, const TypePayoff &type, const Integration &integration, ComplexLogFormula cpxLog, const AnalyticHestonEngine *enginePtr, Real &value, Size &evaluations)
Real priceVanillaPayoff(const ext::shared_ptr< PlainVanillaPayoff > &payoff, const Date &maturity) const
const ext::shared_ptr< Integration > integration_
std::complex< Real > chF(const std::complex< Real > &z, Time t) const
virtual std::complex< Real > addOnTerm(Real phi, Time t, Size j) const
static ComplexLogFormula optimalControlVariate(Time t, Real v0, Real kappa, Real theta, Real sigma, Real rho)
Concrete date class.
Definition: date.hpp:125
Base class for some pricing engine on a particular model.
Intermediate class for put/call payoffs.
Definition: payoffs.hpp:49
const DefaultType & t
Maps function, bind and cref to either the boost or std implementation.
Integral of a 1-dimensional function using the Gauss quadratures.
Generic option engine based on a model.
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
QL_INTEGER Integer
integer number
Definition: types.hpp:35
std::size_t Size
size of a container
Definition: types.hpp:58
Heston model for the stochastic volatility of an asset.
Real kappa
Real theta
Real v0
Real rho
Real sigma
Integrators base class definition.
ext::shared_ptr< QuantLib::Payoff > payoff
Definition: any.hpp:35
null values
Real alpha
Definition: sabr.cpp:200
Vanilla option on a single asset.