44 ext::shared_ptr<Quote> spot,
45 ext::shared_ptr<YieldTermStructure> rTS,
46 ext::shared_ptr<YieldTermStructure> qTS,
47 const ext::shared_ptr<LocalVolTermStructure>& localVol,
53 Time gaussianStepSize)
54 : xGrid_(xGrid), tGrid_(tGrid), x0Density_(x0Density), localVolProbEps_(eps), maxIter_(maxIter),
55 gaussianStepSize_(gaussianStepSize), spot_(
std::move(spot)), localVol_(localVol),
57 timeGrid_(new
TimeGrid(localVol->maxTime(), tGrid)), xm_(tGrid),
58 pm_(new
Matrix(tGrid, xGrid)) {
66 ext::shared_ptr<YieldTermStructure> rTS,
67 ext::shared_ptr<YieldTermStructure> qTS,
68 ext::shared_ptr<LocalVolTermStructure> localVol,
69 const ext::shared_ptr<TimeGrid>& timeGrid,
74 Time gaussianStepSize)
75 : xGrid_(xGrid), tGrid_(timeGrid->size() - 1), x0Density_(x0Density), localVolProbEps_(eps),
76 maxIter_(maxIter), gaussianStepSize_(gaussianStepSize), spot_(
std::move(spot)),
77 localVol_(
std::move(localVol)),
rTS_(
std::move(rTS)), qTS_(
std::move(qTS)),
78 timeGrid_(timeGrid), xm_(tGrid_), pm_(new
Matrix(tGrid_, xGrid_)) {
90 "given time exceeds local vol time grid");
97 const Real xm = - 0.5 * stdDev * stdDev +
102 else if (t <= timeGrid_->at(1)) {
104 const Volatility stdDev = vol * std::sqrt(tMin);
105 const Real xm = - 0.5 * stdDev * stdDev +
106 std::log(
spot_->value() *
qTS_->discount(tMin)/
rTS_->discount(tMin));
111 return gaussianPDF(x)*(
timeGrid_->at(1) -
t)/deltaT
121 const Time deltaT = *lb - *llb;
135 Real xl =
xm_[idx]->locations().front();
136 Real xr =
xm_[idx]->locations().back();
143 Real addition = 0.1*(xr-xl);
146 if (x > 0.5*(xr+xl)) {
154 [&](
Real _x){
return pdf(_x,
t); }, x, xr);
164 [&](
Real _x){
return pdf(_x,
t); }, xl, x);
173 if (closeGridTime == 0.0) {
174 const Real stepSize = 0.02*(
175 xm_[0]->locations().back() -
xm_[0]->locations().front());
177 this, std::log(
spot_->value()),
184 const Array x(
xm_[idx]->locations().begin(),
185 xm_[idx]->locations().end());
188 std::transform(x.
begin(), x.
end(),
pm_->row_begin(idx), xp.
begin(), std::multiplies<>());
196 ext::shared_ptr<Fdm1dMesher>
201 QL_REQUIRE(idx <=
xm_.size(),
"inconsistent time " <<
t <<
" given");
207 return ext::make_shared<Predefined1dMesher>(
208 std::vector<Real>(
xGrid_, std::log(
spot_->value())));
225 Real xm = - 0.5 * stdDev * stdDev +
228 const Volatility stdDevOfFirstStep = vol * std::sqrt(sT);
231 Real sLowerBound = xm - normInvEps * stdDevOfFirstStep;
232 Real sUpperBound = xm + normInvEps * stdDevOfFirstStep;
234 ext::shared_ptr<Fdm1dMesher>
mesher(
243 for (
Size idx=0; idx < p.
size(); ++idx) {
244 p[idx] = gaussianPDF(x[idx]);
249 "Minimum size is greater than 10");
253 ext::shared_ptr<DouglasScheme> evolver(
255 ext::make_shared<FdmLocalVolFwdOp>(
256 ext::make_shared<FdmMesherComposite>(
mesher),
265 const Real maxLeftValue =
266 std::max(std::fabs(*std::min_element(p.
begin(), p.
begin()+
b)),
267 std::fabs(*std::max_element(p.
begin(), p.
begin()+
b)));
268 const Real maxRightValue =
269 std::max(std::fabs(*std::min_element(p.
end()-
b, p.
end())),
270 std::fabs(*std::max_element(p.
end()-
b, p.
end())));
275 const Real oldLowerBound = sLowerBound;
276 const Real oldUpperBound = sUpperBound;
280 for (
Size j=0; j < vols.
size(); ++j) {
281 vols[j] =
localVol_->localVol(
t + dt, std::exp(x[j]));
287 const Real scalingFactor = vm*std::sqrt(0.5*
timeGrid_->back());
290 sLowerBound -= scalingFactor*(oldUpperBound-oldLowerBound);
292 sUpperBound += scalingFactor*(oldUpperBound-oldLowerBound);
294 mesher = ext::shared_ptr<Fdm1dMesher>(
296 std::make_pair(xm, 0.1),
false));
300 mesher->locations().end());
303 for (
Size j=0; j < xn.
size(); ++j) {
304 if (xn[j] >= oldLowerBound && xn[j] <= oldUpperBound)
305 pn[j] = pSpline(xn[j]);
311 evolver = ext::make_shared<DouglasScheme>(0.5,
312 ext::make_shared<FdmLocalVolFwdOp>(
313 ext::make_shared<FdmMesherComposite>(
mesher),
316 evolver->setStep(dt);
325 std::copy(p.
begin(), p.
end(),
pm_->row_begin(i-1));
326 pFct_[i-1] = ext::make_shared<CubicNaturalSpline>(
327 xm_[i-1]->locations().begin(),
328 xm_[i-1]->locations().end(),
329 pm_->row_begin(i-1));
344 if ( x <
xm_[idx]->locations().front()
345 || x >
xm_[idx]->locations().back())
348 return (*
pFct_[idx])(x);
1-D array used in linear algebra.
const_iterator end() const
Size size() const
dimension of the array
const_iterator begin() const
Integral of a one-dimensional function.
Inverse cumulative normal distribution function.
virtual void calculate() const
void performCalculations() const override
std::vector< ext::shared_ptr< Interpolation > > pFct_
const ext::shared_ptr< Quote > spot_
std::vector< Size > rescaleTimeSteps_
LocalVolRNDCalculator(ext::shared_ptr< Quote > spot, ext::shared_ptr< YieldTermStructure > rTS, ext::shared_ptr< YieldTermStructure > qTS, const ext::shared_ptr< LocalVolTermStructure > &localVol, Size xGrid=101, Size tGrid=51, Real x0Density=0.1, Real localVolProbEps=1e-6, Size maxIter=10000, Time gaussianStepSize=-Null< Time >())
Array rescalePDF(const Array &x, const Array &p) const
const Real localVolProbEps_
const ext::shared_ptr< YieldTermStructure > qTS_
std::vector< Size > rescaleTimeSteps() const
ext::shared_ptr< TimeGrid > timeGrid() const
const Time gaussianStepSize_
Real pdf(Real x, Time t) const override
Real cdf(Real x, Time t) const override
const ext::shared_ptr< YieldTermStructure > rTS_
const ext::shared_ptr< TimeGrid > timeGrid_
const ext::shared_ptr< Matrix > pm_
ext::shared_ptr< Fdm1dMesher > mesher(Time t) const
std::vector< ext::shared_ptr< Fdm1dMesher > > xm_
Real invcdf(Real p, Time t) const override
Real probabilityInterpolation(Size idx, Real x) const
const ext::shared_ptr< LocalVolTermStructure > localVol_
Matrix used in linear algebra.
Normal distribution function.
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Real inverseCDF(Real p, Time t) const
std::vector< Time >::const_iterator const_iterator
One-dimensional grid mesher concentrating around critical points.
cubic interpolation between discrete points
integrals on non uniform grids
Douglas operator splitting.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
ext::function< Real(Real)> b
const ext::shared_ptr< YieldTermStructure > rTS_
local volatility linear operator for the Fokker-Planck forward equation
FdmMesher which is a composite of Fdm1dMesher.
integral of a one-dimensional function using the adaptive Gauss-Lobatto integral
Real Time
continuous quantity with 1-year units
Real Volatility
volatility
std::size_t Size
size of a container
local volatility risk neutral terminal density calculation
Local volatility term structure base class.
NormalDistribution GaussianDistribution
normal, cumulative and inverse cumulative distributions
One-dimensional mesher build from a given set of points.
purely virtual base class for market observables
Interest-rate term structure.