25 class AnalyticContinuousGeometricAveragePriceAsianHestonEngine::Integrand {
29 const AnalyticContinuousGeometricAveragePriceAsianHestonEngine*
const parent_;
31 std::complex<Real> i_;
37 const AnalyticContinuousGeometricAveragePriceAsianHestonEngine*
const parent,
39 :
T_(
T), K_(K), logK_(
std::log(K)), cutoff_(cutoff), parent_(parent),
40 xiRightLimit_(xiRightLimit), i_(
std::complex<
Real>(0.0, 1.0)) {}
43 Real xiDash = (0.5+1e-8+0.5*xi) * xiRightLimit_;
45 std::complex<Real> inner1 = parent_->Phi(1.0 + xiDash*i_, 0, T_, t_, cutoff_);
46 std::complex<Real> inner2 = - K_*parent_->Phi(xiDash*i_, 0, T_, t_, cutoff_);
48 return 0.5*xiRightLimit_*std::real((inner1 + inner2) * std::exp(-xiDash*logK_*i_) / (xiDash*i_));
52 class AnalyticContinuousGeometricAveragePriceAsianHestonEngine::DcfIntegrand {
55 const Handle<YieldTermStructure> riskFreeRate_;
56 const Handle<YieldTermStructure> dividendYield_;
60 Handle<YieldTermStructure> riskFreeRate,
61 Handle<YieldTermStructure> dividendYield)
62 :
t_(
t),
T_(
T), riskFreeRate_(
std::move(riskFreeRate)),
63 dividendYield_(
std::move(dividendYield)) {
64 denominator_ = std::log(riskFreeRate_->discount(t_)) - std::log(dividendYield_->discount(t_));
68 Real uDash = (0.5+1e-8+0.5*u) * (T_ - t_) +
t_;
69 return 0.5*(
T_ -
t_)*(-std::log(riskFreeRate_->discount(uDash))
70 + std::log(dividendYield_->discount(uDash)) + denominator_);
77 ext::shared_ptr<HestonProcess> process,
Size summationCutoff,
Real xiRightLimit)
78 : process_(
std::move(process)), summationCutoff_(summationCutoff), xiRightLimit_(xiRightLimit),
99 const std::complex<Real>&
s,
const std::complex<Real>& w,
Real T)
const {
104 const std::complex<Real>&
s,
const std::complex<Real>& w,
Real T)
const {
109 const std::complex<Real>&
s,
const std::complex<Real>& w,
Real T)
const {
114 const std::complex<Real>&
s,
const std::complex<Real>& w)
const {
119 const std::complex<Real>& z2,
120 const std::complex<Real>& z3,
121 const std::complex<Real>& z4,
124 std::complex<Real> result;
137 std::complex<Real> fMinusN[4];
141 for (
int offset=1; offset<5; offset++) {
142 int location =
n-offset;
143 std::map<int, std::complex<Real> >::const_iterator position =
fLookupTable_.find(location);
145 std::complex<Real> value = position->second;
146 fMinusN[offset-1] = value;
148 fMinusN[offset-1] =
f(z1, z2, z3, z4, location, tau);
152 result = prefactor * (z1*tau*tau*fMinusN[3] + z2*tau*fMinusN[2] + (z3 - 0.5*
kappa_*
kappa_/(
sigma_*
sigma_))*fMinusN[1]);
161 std::pair<std::complex<Real>, std::complex<Real> >
163 const std::complex<Real>& z1,
164 const std::complex<Real>& z2,
165 const std::complex<Real>& z3,
166 const std::complex<Real>& z4,
169 std::complex<Real> temp = 0.0;
170 std::complex<Real> runningSum1 = 0.0;
171 std::complex<Real> runningSum2 = 0.0;
173 for (
Size i=0; i<cutoff; i++) {
174 temp =
f(z1, z2, z3, z4, i, tau);
176 runningSum2 += temp*
Real(i)/tau;
179 std::pair<std::complex<Real>, std::complex<Real> > result(runningSum1, runningSum2);
185 const std::complex<Real>&
s,
186 const std::complex<Real>& w,
192 std::complex<Real> z1 =
z1_f(
s, w,
T);
193 std::complex<Real> z2 =
z2_f(
s, w,
T);
194 std::complex<Real> z3 =
z3_f(
s, w,
T);
195 std::complex<Real> z4 =
z4_f(
s, w);
199 std::pair<std::complex<Real>, std::complex<Real> > temp =
F_F_tilde(z1, z2, z3, z4, tau, cutoff);
201 std::complex<Real>
F, F_tilde;
203 F_tilde = temp.second;
210 "not a geometric average option");
212 "not an European Option");
214 ext::shared_ptr<PlainVanillaPayoff>
payoff =
215 ext::dynamic_pointer_cast<PlainVanillaPayoff>(
arguments_.payoff);
222 QL_REQUIRE(expiryTime >= 0.0,
"Expiry Date cannot be in the past");
228 Time startTime = 0.0;
235 Real logS0 = std::log(
s0_->value());
256 switch (
payoff->optionType()){
258 value = expiryDcf * (term1 + term2);
261 value = expiryDcf * (-term1 + term2);
264 QL_FAIL(
"unknown option type");
Analytic engine for continuous geometric average price Asian in the Heston model.
ext::shared_ptr< HestonProcess > process_
std::complex< Real > f(const std::complex< Real > &z1, const std::complex< Real > &z2, const std::complex< Real > &z3, const std::complex< Real > &z4, int n, Real tau) const
std::complex< Real > z3_f(const std::complex< Real > &s, const std::complex< Real > &w, Real T) const
std::complex< Real > z4_f(const std::complex< Real > &s, const std::complex< Real > &w) const
void calculate() const override
std::pair< std::complex< Real >, std::complex< Real > > F_F_tilde(const std::complex< Real > &z1, const std::complex< Real > &z2, const std::complex< Real > &z3, const std::complex< Real > &z4, Real tau, Size cutoff=50) const
GaussLegendreIntegration integrator_
std::map< int, std::complex< Real > > fLookupTable_
std::complex< Real > z2_f(const std::complex< Real > &s, const std::complex< Real > &w, Real T) const
std::complex< Real > z1_f(const std::complex< Real > &s, const std::complex< Real > &w, Real T) const
Handle< YieldTermStructure > dividendYield_
std::complex< Real > Phi(const std::complex< Real > &s, const std::complex< Real > &w, Real T, Real t=0.0, Size cutoff=50) const
AnalyticContinuousGeometricAveragePriceAsianHestonEngine(ext::shared_ptr< HestonProcess > process, Size summationCutoff=50, Real xiRightLimit=100.0)
Handle< YieldTermStructure > riskFreeRate_
Average::Type averageType
ContinuousAveragingAsianOption::results results_
ContinuousAveragingAsianOption::arguments arguments_
std::map< std::string, ext::any > additionalResults
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
#define QL_FAIL(message)
throw an error (possibly with file and line information)
Real Time
continuous quantity with 1-year units
std::size_t Size
size of a container
ext::shared_ptr< QuantLib::Payoff > payoff