QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
analytich1hwengine.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2012 Klaus Spanderen
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#include <ql/math/distributions/gammadistribution.hpp>
25#include <ql/pricingengines/vanilla/analytich1hwengine.hpp>
26
27namespace QuantLib {
28 // integration helper class
29 class AnalyticH1HWEngine::Fj_Helper {
30
31 public:
32 Fj_Helper(const Handle<HestonModel>& hestonModel,
33 const ext::shared_ptr<HullWhite>& hullWhiteModel,
34 Real rho_xr, Time term, Real strike, Size j);
35
36 std::complex<Real> operator()(Real u) const;
37
38 private:
39 Real c(Time t) const;
40 Real lambda(Time t) const;
41 Real Lambda(Time t) const;
42 Real LambdaApprox(Time t) const;
43
44 const Size j_;
45 const Real lambda_, eta_;
46 const Real v0_, kappa_, theta_, gamma_;
47 const Real d_;
48 const Real rhoSr_;
49 const Time term_;
50 };
51
52 AnalyticH1HWEngine::Fj_Helper::Fj_Helper(
53 const Handle<HestonModel>& hestonModel,
54 const ext::shared_ptr<HullWhite>& hullWhiteModel,
55 Real rhoSr, Time term, Real, Size j)
56 : j_ (j),
57 lambda_(hullWhiteModel->a()),
58 eta_ (hullWhiteModel->sigma()),
59 v0_ (hestonModel->v0()),
60 kappa_ (hestonModel->kappa()),
61 theta_ (hestonModel->theta()),
62 gamma_ (hestonModel->sigma()),
63 d_ (4.0*kappa_*theta_/(gamma_*gamma_)),
64 rhoSr_ (rhoSr),
65 term_ (term) {
66 }
67
68 Real AnalyticH1HWEngine::Fj_Helper::c(Time t) const {
69 return gamma_*gamma_/(4*kappa_)*(1.0-std::exp(-kappa_*t));
70 }
71
72 Real AnalyticH1HWEngine::Fj_Helper::lambda(Time t) const {
73 return 4.0*kappa_*v0_*std::exp(-kappa_*t)
74 /(gamma_*gamma_*(1.0-std::exp(-kappa_*t)));
75 }
76
77 Real AnalyticH1HWEngine::Fj_Helper::LambdaApprox(Time t) const {
78 return std::sqrt( c(t)*(lambda(t)-1.0)
79 + c(t)*d_*(1.0 + 1.0/(2.0*(d_+lambda(t)))));
80 }
81
82 Real AnalyticH1HWEngine::Fj_Helper::Lambda(Time t) const {
83 const GammaFunction g = GammaFunction();
84 const Size maxIter = 1000;
85 const Real lambdaT = lambda(t);
86
87 Size i=0;
88 Real retVal = 0.0, s;
89
90 do {
91 Real k = static_cast<Real>(i);
92 s=std::exp(k*std::log(0.5*lambdaT) + g.logValue(0.5*(1+d_)+k)
93 - g.logValue(k+1) - g.logValue(0.5*d_+k));
94 retVal += s;
95 } while (s > std::numeric_limits<float>::epsilon() && ++i < maxIter);
96
97 QL_REQUIRE(i < maxIter, "can not calculate Lambda");
98
99 retVal *= std::sqrt(2*c(t)) * std::exp(-0.5*lambdaT);
100 return retVal;
101 }
102
103 std::complex<Real> AnalyticH1HWEngine::Fj_Helper::operator()(Real u) const {
104
105 const Real gamma2 = gamma_*gamma_;
106
107 Real a, b, c;
108 if (8.0*kappa_*theta_/gamma2 > 1.0) {
109 a = std::sqrt(theta_-gamma2/(8.0*kappa_));
110 b = std::sqrt(v0_) - a;
111 c =-std::log((LambdaApprox(1.0)-a)/b);
112 }
113 else {
114 a = std::sqrt(gamma2/(2.0*kappa_))
115 *std::exp( GammaFunction().logValue(0.5*(d_+1.0))
116 - GammaFunction().logValue(0.5*d_));
117
118 const Time t1 = 0.0;
119 const Time t2 = 1.0/kappa_;
120
121 const Real Lambda_t1 = std::sqrt(v0_);
122 const Real Lambda_t2 = Lambda(t2);
123
124 c = std::log((Lambda_t2-a)/(Lambda_t1-a))/(t1-t2);
125 b = std::exp(c*t1)*(Lambda_t1-a);
126 }
127
128 const std::complex<Real> I4 =
129 -1.0 / lambda_ * std::complex<Real>(u * u, ((j_ == 1U) ? -u : u)) *
130 (b / c * (1.0 - std::exp(-c * term_)) + a * term_ +
131 a / lambda_ * (std::exp(-lambda_ * term_) - 1.0) +
132 b / (c - lambda_) * std::exp(-c * term_) * (1.0 - std::exp(-term_ * (lambda_ - c))));
133
134 return eta_*rhoSr_*I4;
135 }
136
137
138 AnalyticH1HWEngine::AnalyticH1HWEngine(
139 const ext::shared_ptr<HestonModel>& model,
140 const ext::shared_ptr<HullWhite>& hullWhiteModel,
141 Real rhoSr, Size integrationOrder)
142 : AnalyticHestonHullWhiteEngine(model, hullWhiteModel, integrationOrder),
143 rhoSr_(rhoSr) {
144 QL_REQUIRE(rhoSr_ >= 0.0, "Fourier integration is not stable if "
145 "the equity interest rate correlation is negative");
146 }
147
149 const ext::shared_ptr<HestonModel>& model,
150 const ext::shared_ptr<HullWhite>& hullWhiteModel,
151 Real rhoSr, Real relTolerance, Size maxEvaluations)
152 : AnalyticHestonHullWhiteEngine(model, hullWhiteModel,
153 relTolerance, maxEvaluations),
154 rhoSr_(rhoSr) {
155 }
156
157 std::complex<Real> AnalyticH1HWEngine::addOnTerm(Real u, Time t, Size j)
158 const {
160 + Fj_Helper(model_, hullWhiteModel_, rhoSr_, t, 0.0, j)(u);
161 }
162}
163
AnalyticH1HWEngine(const ext::shared_ptr< HestonModel > &model, const ext::shared_ptr< HullWhite > &hullWhiteModel, Real rhoSr, Size integrationOrder=144)
std::complex< Real > addOnTerm(Real phi, Time t, Size j) const override
Analytic Heston engine incl. stochastic interest rates.
std::complex< Real > addOnTerm(Real phi, Time t, Size j) const override
const ext::shared_ptr< HullWhite > hullWhiteModel_
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