21#include <ql/math/functional.hpp>
22#include <ql/math/integrals/gausslobattointegral.hpp>
23#include <ql/methods/finitedifferences/utilities/bsmrndcalculator.hpp>
24#include <ql/methods/finitedifferences/utilities/hestonrndcalculator.hpp>
25#include <ql/processes/blackscholesprocess.hpp>
26#include <ql/processes/hestonprocess.hpp>
27#include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
28#include <ql/time/calendars/nullcalendar.hpp>
36 Real v0, kappa, theta, sigma, rho;
39 HestonParams getHestonParams(
40 const ext::shared_ptr<HestonProcess>& process) {
41 const HestonParams p = { process->v0(), process->kappa(),
42 process->theta(), process->sigma(),
47 std::complex<Real> gamma(
const HestonParams& p,
Real p_x) {
48 return std::complex<Real>(p.kappa, p.rho*p.sigma*p_x);
51 std::complex<Real> omega(
const HestonParams& p,
Real p_x) {
52 const std::complex<Real>
g = gamma(p, p_x);
54 + p.sigma*p.sigma*std::complex<Real>(p_x*p_x, -p_x));
59 CpxPv_Helper(
const HestonParams& p,
Real x,
Time t)
60 : p_(p), t_(t), x_(x),
61 c_inf_(
std::min(10.0,
std::max(0.0001,
63 *(p_.v0 + p_.kappa*p_.theta*t)) {}
66 return std::real(transformPhi(x));
75 return std::real(phi(u_x)
76 /((p_x*c_inf_)*std::complex<Real>(0.0, u_x)));
80 std::complex<Real> transformPhi(
Real x)
const {
82 return std::complex<Real>(0.0, 0.0);
85 const Real u_x = -std::log(x)/c_inf_;
86 return phi(u_x)/(x*c_inf_);
89 std::complex<Real> phi(
Real p_x)
const {
90 const Real sigma2 = p_.sigma*p_.sigma;
91 const std::complex<Real>
g = gamma(p_, p_x);
92 const std::complex<Real> o = omega(p_, p_x);
93 const std::complex<Real> gamma = (
g-o)/(g+o);
95 return 2.0*std::exp(std::complex<Real>(0.0, p_x*x_)
96 - p_.v0*std::complex<Real>(p_x*p_x, -p_x)
97 /(g+o*(1.0+std::exp(-o*t_))/(1.0-std::exp(-o*t_)))
98 +p_.kappa*p_.theta/sigma2*(
99 (g-o)*t_ - 2.0*std::log((1.0-gamma*std::exp(-o*t_))
103 const HestonParams p_;
105 const Real x_, c_inf_;
112 Size maxIntegrationIterations)
113 : hestonProcess_(
std::move(hestonProcess)), x0_(
std::log(hestonProcess_->s0()->value())),
114 integrationEps_(integrationEps), maxIntegrationIterations_(maxIntegrationIterations) {}
120 return x -
x0_ + std::log(dr/dq);
134 [&](
Real p_x){
return helper.p0(p_x); },
135 0.0, 1.0)/M_TWOPI + 0.5;
144 = std::sqrt(theta + (v0-theta)*(1-std::exp(-kappa*t))/(t*kappa));
146 const ext::shared_ptr<BlackScholesMertonProcess> bsmProcess(
147 ext::make_shared<BlackScholesMertonProcess>(
152 ext::make_shared<BlackConstantVol>(
Real invcdf(Real q, Time t) const override
Integral of a one-dimensional function.
Shared handle to an observable.
HestonRNDCalculator(ext::shared_ptr< HestonProcess > hestonProcess, Real integrationEps=1e-6, Size maxIntegrationIterations=10000UL)
Real x_t(Real x, Time t) const
const Real integrationEps_
Real invcdf(Real q, Time t) const override
Real pdf(Real x, Time t) const override
Real cdf(Real x, Time t) const override
const Size maxIntegrationIterations_
const ext::shared_ptr< HestonProcess > hestonProcess_
Calendar for reproducing theoretical calculations.
Real inverseCDF(Real p, Time t) const
Real Time
continuous quantity with 1-year units
Real DiscountFactor
discount factor between dates
Real Volatility
volatility
std::size_t Size
size of a container