29 class AnalyticH1HWEngine::Fj_Helper {
32 Fj_Helper(
const Handle<HestonModel>& hestonModel,
33 const ext::shared_ptr<HullWhite>& hullWhiteModel,
36 std::complex<Real> operator()(
Real u)
const;
45 const Real lambda_, eta_;
52 AnalyticH1HWEngine::Fj_Helper::Fj_Helper(
53 const Handle<HestonModel>& hestonModel,
54 const ext::shared_ptr<HullWhite>& hullWhiteModel,
57 lambda_(hullWhiteModel->a()),
58 eta_ (hullWhiteModel->
sigma()),
59 v0_ (hestonModel->
v0()),
62 gamma_ (hestonModel->
sigma()),
68 Real AnalyticH1HWEngine::Fj_Helper::c(Time
t)
const {
72 Real AnalyticH1HWEngine::Fj_Helper::lambda(Time
t)
const {
74 /(gamma_*gamma_*(1.0-std::exp(-
kappa_*
t)));
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)))));
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);
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));
95 }
while (
s > std::numeric_limits<float>::epsilon() && ++i < maxIter);
97 QL_REQUIRE(i < maxIter,
"can not calculate Lambda");
99 retVal *= std::sqrt(2*c(
t)) * std::exp(-0.5*lambdaT);
103 std::complex<Real> AnalyticH1HWEngine::Fj_Helper::operator()(Real u)
const {
105 const Real gamma2 = gamma_*gamma_;
110 b = std::sqrt(v0_) - a;
111 c =-std::log((LambdaApprox(1.0)-a)/
b);
114 a = std::sqrt(gamma2/(2.0*
kappa_))
115 *std::exp( GammaFunction().logValue(0.5*(
d_+1.0))
116 - GammaFunction().logValue(0.5*
d_));
121 const Real Lambda_t1 = std::sqrt(v0_);
122 const Real Lambda_t2 = Lambda(t2);
124 c = std::log((Lambda_t2-a)/(Lambda_t1-a))/(t1-t2);
125 b = std::exp(c*t1)*(Lambda_t1-a);
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))));
134 return eta_*rhoSr_*I4;
138 AnalyticH1HWEngine::AnalyticH1HWEngine(
139 const ext::shared_ptr<HestonModel>& model,
140 const ext::shared_ptr<HullWhite>& hullWhiteModel,
145 "the equity interest rate correlation is negative");
149 const ext::shared_ptr<HestonModel>& model,
150 const ext::shared_ptr<HullWhite>& hullWhiteModel,
153 relTolerance, maxEvaluations),
analytic Heston-Hull-White engine based on the H1-HW approximation
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_
Handle< HestonModel > model_
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
ext::function< Real(Real)> b
Real Time
continuous quantity with 1-year units
std::size_t Size
size of a container