37 const ext::shared_ptr<HestonModel>& hestonModel,
38 ext::shared_ptr<HullWhiteProcess> hwProcess,
39 Real corrEquityShortRate,
50 hwProcess_(
std::move(hwProcess)),
51 corrEquityShortRate_(corrEquityShortRate), tGrid_(tGrid),
52 xGrid_(xGrid), vGrid_(vGrid), rGrid_(rGrid), dampingSteps_(dampingSteps),
53 schemeDesc_(schemeDesc), controlVariate_(controlVariate) {}
56 const ext::shared_ptr<HestonModel>& hestonModel,
57 ext::shared_ptr<HullWhiteProcess> hwProcess,
59 Real corrEquityShortRate,
70 hwProcess_(
std::move(hwProcess)), dividends_(
std::move(dividends)),
71 corrEquityShortRate_(corrEquityShortRate), tGrid_(tGrid),
72 xGrid_(xGrid), vGrid_(vGrid), rGrid_(rGrid), dampingSteps_(dampingSteps),
73 schemeDesc_(schemeDesc), controlVariate_(controlVariate) {}
79 if (cachedArgs2result.first.exercise->type() ==
arguments_.exercise->type() &&
80 cachedArgs2result.first.exercise->dates() ==
arguments_.exercise->dates()) {
81 ext::shared_ptr<PlainVanillaPayoff> p1 =
82 ext::dynamic_pointer_cast<PlainVanillaPayoff>(
84 ext::shared_ptr<PlainVanillaPayoff> p2 =
85 ext::dynamic_pointer_cast<PlainVanillaPayoff>(cachedArgs2result.first.payoff);
87 if ((p1 !=
nullptr) && p1->strike() == p2->strike() &&
88 p1->optionType() == p2->optionType()) {
90 "multiple strikes engine does not work with discrete dividends");
98 const ext::shared_ptr<HestonProcess> hestonProcess=
model_->process();
99 const Time maturity=hestonProcess->time(
arguments_.exercise->lastDate());
102 const Size tGridMin = 5;
103 const ext::shared_ptr<FdmHestonVarianceMesher> varianceMesher(
105 maturity,std::max(tGridMin,
tGrid_/50)));
108 const ext::shared_ptr<StrikedTypePayoff>
payoff =
109 ext::dynamic_pointer_cast<StrikedTypePayoff>(
arguments_.payoff);
112 ext::shared_ptr<Fdm1dMesher> equityMesher;
114 equityMesher = ext::shared_ptr<Fdm1dMesher>(
118 hestonProcess->s0(), hestonProcess->dividendYield(),
119 hestonProcess->riskFreeRate(),
120 varianceMesher->volaEstimate()),
121 maturity,
payoff->strike(),
123 std::pair<Real, Real>(
payoff->strike(), 0.1),
128 "multiple strikes engine does not work with discrete dividends");
129 equityMesher = ext::shared_ptr<Fdm1dMesher>(
133 hestonProcess->s0(), hestonProcess->dividendYield(),
134 hestonProcess->riskFreeRate(),
135 varianceMesher->volaEstimate()),
137 std::pair<Real, Real>(
payoff->strike(), 0.075)));
141 const ext::shared_ptr<OrnsteinUhlenbeckProcess> ouProcess(
143 const ext::shared_ptr<Fdm1dMesher> shortRateMesher(
146 const ext::shared_ptr<FdmMesher> mesher(
151 const ext::shared_ptr<FdmInnerValueCalculator> calculator(
155 const ext::shared_ptr<FdmStepConditionComposite> conditions =
159 hestonProcess->riskFreeRate()->referenceDate(),
160 hestonProcess->riskFreeRate()->dayCounter());
166 const FdmSolverDesc solverDesc = { mesher, boundaries, conditions,
167 calculator, maturity,
170 const ext::shared_ptr<FdmHestonHullWhiteSolver> solver(
176 const Real spot = hestonProcess->s0()->value();
177 const Real v0 = hestonProcess->v0();
178 results_.value = solver->valueAt(spot,
v0, 0);
179 results_.delta = solver->deltaAt(spot,
v0, 0, spot*0.01);
180 results_.gamma = solver->gammaAt(spot,
v0, 0, spot*0.01);
181 results_.theta = solver->thetaAt(spot,
v0, 0);
187 ext::make_shared<PlainVanillaPayoff>(
193 results.delta = solver->deltaAt(spot*
d,
v0, 0, spot*
d*0.01);
194 results.gamma = solver->gammaAt(spot*
d,
v0, 0, spot*
d*0.01)*
d;
199 ext::shared_ptr<PricingEngine> analyticEngine(
201 ext::shared_ptr<Exercise> exercise(
206 Real analyticNPV = option.
NPV();
208 ext::shared_ptr<FdHestonVanillaEngine> fdEngine(
212 fdEngine->enableMultipleStrikesCaching(
strikes_);
216 results_.value += analyticNPV - fdNPV;
219 ext::shared_ptr<StrikedTypePayoff>(
223 analyticNPV = controlVariateOption.
NPV();
226 fdNPV = controlVariateOption.
NPV();
240 const std::vector<Real>& strikes) {
analytic Heston-model engine
analytic Heston-model engine based on Fourier transform
const Real corrEquityShortRate_
const bool controlVariate_
std::vector< Real > strikes_
std::vector< std::pair< VanillaOption::arguments, VanillaOption::results > > cachedArgs2results_
void calculate() const override
const ext::shared_ptr< HullWhiteProcess > hwProcess_
FdHestonHullWhiteVanillaEngine(const ext::shared_ptr< HestonModel > &model, ext::shared_ptr< HullWhiteProcess > hwProcess, Real corrEquityShortRate, Size tGrid=50, Size xGrid=100, Size vGrid=40, Size rGrid=20, Size dampingSteps=0, bool controlVariate=true, const FdmSchemeDesc &schemeDesc=FdmSchemeDesc::Hundsdorfer())
DividendSchedule dividends_
void enableMultipleStrikesCaching(const std::vector< Real > &strikes)
const FdmSchemeDesc schemeDesc_
Finite-differences Heston vanilla option engine.
static ext::shared_ptr< GeneralizedBlackScholesProcess > processHelper(const Handle< Quote > &s0, const Handle< YieldTermStructure > &rTS, const Handle< YieldTermStructure > &qTS, Volatility vol)
static ext::shared_ptr< FdmStepConditionComposite > vanillaComposite(const DividendSchedule &schedule, const ext::shared_ptr< Exercise > &exercise, const ext::shared_ptr< FdmMesher > &mesher, const ext::shared_ptr< FdmInnerValueCalculator > &calculator, const Date &refDate, const DayCounter &dayCounter)
Base class for some pricing engine on a particular model.
Handle< HestonModel > model_
Shared handle to an observable.
Heston model for the stochastic volatility of an asset.
Real NPV() const
returns the net present value of the instrument.
void setPricingEngine(const ext::shared_ptr< PricingEngine > &)
set the pricing engine to be used.
template class providing a null value for a given type.
Ornstein-Uhlenbeck process class.
Vanilla option (no discrete dividends, no barriers) on a single asset.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Finite-differences Heston Hull-White vanilla option engine.
Finite-differences Heston vanilla option engine.
1-d mesher for the Black-Scholes process (in ln(S))
1-d mesher for the Black-Scholes process (in ln(S))
One-dimensional grid mesher for the variance part of the Heston model.
layer of abstraction to calculate the inner value
memory layout of a fdm linear operator
FdmMesher which is a composite of Fdm1dMesher.
One-dimensional grid mesher.
composite of fdm step conditions
Real Time
continuous quantity with 1-year units
std::size_t Size
size of a container
ext::shared_ptr< QuantLib::Payoff > payoff
std::vector< ext::shared_ptr< Dividend > > DividendSchedule
OperatorTraits< FdmLinearOp >::bc_set FdmBoundaryConditionSet