38 const ext::shared_ptr<GeneralizedBlackScholesProcess>& process,
40 Real xMinConstraint,
Real xMaxConstraint,
42 const std::pair<Real, Real>& cPoint,
44 const ext::shared_ptr<FdmQuantoHelper>& fdmQuantoHelper,
48 const Real S = process->x0();
49 QL_REQUIRE(
S > 0.0,
"negative or null underlying given");
51 std::vector<std::pair<Time, Real> > intermediateSteps;
52 for (
const auto& i : dividendSchedule) {
53 const Time t = process->time(i->date());
54 if (t <= maturity && t >= 0.0)
55 intermediateSteps.emplace_back(process->time(i->date()), i->amount());
58 const Size intermediateTimeSteps = std::max<Size>(2,
Size(24.0*maturity));
59 for (
Size i=0; i < intermediateTimeSteps; ++i)
60 intermediateSteps.emplace_back((i + 1) * (maturity / intermediateTimeSteps), 0.0);
62 std::sort(intermediateSteps.begin(), intermediateSteps.end());
67 (fdmQuantoHelper) !=
nullptr ?
69 process->dividendYield(), process->riskFreeRate(),
72 fdmQuantoHelper->exchRateATMlevel_, fdmQuantoHelper->equityFxCorrelation_)) :
73 process->dividendYield();
75 Time lastDivTime = 0.0;
76 Real fwd =
S + spotAdjustment;
77 Real mi = fwd, ma = fwd;
79 for (
auto& intermediateStep : intermediateSteps) {
80 const Time divTime = intermediateStep.first;
81 const Real divAmount = intermediateStep.second;
83 fwd = fwd / rTS->discount(divTime) * rTS->discount(lastDivTime)
84 * qTS->discount(divTime) / qTS->discount(lastDivTime);
86 mi = std::min(mi, fwd); ma = std::max(ma, fwd);
90 mi = std::min(mi, fwd); ma = std::max(ma, fwd);
92 lastDivTime = divTime;
98 = process->blackVolatility()->blackVol(maturity, strike)
101 Real xMin = std::log(mi) - sigmaSqrtT*normInvEps*scaleFactor;
102 Real xMax = std::log(ma) + sigmaSqrtT*normInvEps*scaleFactor;
105 xMin = xMinConstraint;
108 xMax = xMaxConstraint;
111 ext::shared_ptr<Fdm1dMesher> helper;
113 && std::log(cPoint.first) >=xMin && std::log(cPoint.first) <=xMax) {
115 helper = ext::shared_ptr<Fdm1dMesher>(
117 std::pair<Real,Real>(std::log(cPoint.first),
121 helper = ext::shared_ptr<Fdm1dMesher>(
128 dplus_[i] = helper->dplus(i);
129 dminus_[i] = helper->dminus(i);
133 ext::shared_ptr<GeneralizedBlackScholesProcess>
139 return ext::make_shared<GeneralizedBlackScholesProcess>(
143 ext::shared_ptr<BlackVolTermStructure>(
147 rTS->dayCounter()))));
Black constant volatility, no time dependence, no strike dependence.
Constant Black volatility, no time-strike dependence.
std::vector< Real > locations_
std::vector< Real > dplus_
std::vector< Real > dminus_
FdmBlackScholesMesher(Size size, const ext::shared_ptr< GeneralizedBlackScholesProcess > &process, Time maturity, Real strike, Real xMinConstraint=Null< Real >(), Real xMaxConstraint=Null< Real >(), Real eps=0.0001, Real scaleFactor=1.5, const std::pair< Real, Real > &cPoint={ Null< Real >(), Null< Real >() }, const DividendSchedule ÷ndSchedule={}, const ext::shared_ptr< FdmQuantoHelper > &fdmQuantoHelper={}, Real spotAdjustment=0.0)
static ext::shared_ptr< GeneralizedBlackScholesProcess > processHelper(const Handle< Quote > &s0, const Handle< YieldTermStructure > &rTS, const Handle< YieldTermStructure > &qTS, Volatility vol)
Shared handle to an observable.
Inverse cumulative normal distribution function.
template class providing a null value for a given type.
One-dimensional grid mesher concentrating around critical points.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
1-d mesher for the Black-Scholes process (in ln(S))
helper class storing market data needed for the quanto adjustment.
Real Time
continuous quantity with 1-year units
Real Volatility
volatility
std::size_t Size
size of a container
std::vector< ext::shared_ptr< Dividend > > DividendSchedule
normal, cumulative and inverse cumulative distributions
Interest-rate term structure.