21#include <ql/instruments/payoffs.hpp>
22#include <ql/math/functional.hpp>
23#include <ql/math/comparison.hpp>
24#include <ql/methods/finitedifferences/meshers/fdmmesher.hpp>
25#include <ql/methods/finitedifferences/operators/fdmlinearoplayout.hpp>
26#include <ql/methods/finitedifferences/operators/secondderivativeop.hpp>
31 const ext::shared_ptr<GeneralizedBlackScholesProcess>& bsProcess, Real strike,
32 bool localVol, Real illegalLocalVolOverwrite, Size direction,
33 const ext::shared_ptr<FdmQuantoHelper>& quantoHelper,
const bool discounting,
34 const bool ensureNonNegativeForwardVariance)
35 : mesher_(mesher), rTS_(bsProcess->riskFreeRate().currentLink()), qTS_(bsProcess->dividendYield().currentLink()),
36 volTS_(bsProcess->blackVolatility().currentLink()),
37 localVol_((localVol) ? bsProcess->localVolatility().currentLink() : ext::shared_ptr<LocalVolTermStructure>()),
38 x_((localVol) ? Array(Exp(mesher->locations(direction))) : Array()), dxMap_(FirstDerivativeOp(direction, mesher)),
39 dxxMap_(SecondDerivativeOp(direction, mesher)), mapT_(direction, mesher), strike_(strike),
40 illegalLocalVolOverwrite_(illegalLocalVolOverwrite), direction_(direction), quantoHelper_(quantoHelper),
41 initialValue_(bsProcess->x0()), discounting_(discounting),
42 ensureNonNegativeForwardVariance_(ensureNonNegativeForwardVariance) {}
45 const Rate r =
rTS_->forwardRate(t1, t2, Continuous).rate();
46 const Rate q =
qTS_->forwardRate(t1, t2, Continuous).rate();
50 const ext::shared_ptr<FdmLinearOpLayout> layout =
mesher_->layout();
51 const FdmLinearOpIterator endIter = layout->end();
53 Array v(layout->size());
54 for (FdmLinearOpIterator iter = layout->begin(); iter != endIter; ++iter) {
55 const Size i = iter.index();
58 v[i] = squared(
localVol_->localVol(0.5 * (t1 + t2),
x_[i],
true));
61 v[i] = squared(
localVol_->localVol(0.5 * (t1 + t2),
x_[i],
true));
70 dxxMap_.mult(0.5 * v), Array(1, -discountRate));
89 mapT_.axpyb(Array(1, r - q - 0.5 * v) -
quantoHelper_->quantoAdjustment(Array(1, std::sqrt(v)), t1, t2),
93 Array(1, -discountRate));
104 return mapT_.apply(r);
106 Array retVal(r.size(), 0.0);
112 Array retVal(r.size(), 0.0);
118 return mapT_.solve_splitting(r, dt, 1.0);
129#if !defined(QL_NO_UBLAS_SUPPORT)
131 std::vector<QuantLib::SparseMatrix> retVal(1,
mapT_.toMatrix());
const bool ensureNonNegativeForwardVariance_
Size size() const override
Array apply_direction(Size direction, const Array &r) const override
Array preconditioner(const Array &r, Real s) const override
std::vector< QuantLib::SparseMatrix > toMatrixDecomp() const override
const TripleBandLinearOp dxxMap_
const ext::shared_ptr< FdmQuantoHelper > quantoHelper_
void setTime(Time t1, Time t2) override
FdmBlackScholesOp(const ext::shared_ptr< FdmMesher > &mesher, const ext::shared_ptr< GeneralizedBlackScholesProcess > &process, Real strike=Null< Real >(), bool localVol=false, Real illegalLocalVolOverwrite=-Null< Real >(), Size direction=0, const ext::shared_ptr< FdmQuantoHelper > &quantoHelper=ext::shared_ptr< FdmQuantoHelper >(), const bool discounting=true, const bool ensureNonNegativeForwardVariance=false)
Array apply_mixed(const Array &r) const override
const ext::shared_ptr< YieldTermStructure > qTS_
const FirstDerivativeOp dxMap_
const ext::shared_ptr< FdmMesher > mesher_
Array solve_splitting(Size direction, const Array &r, Real s) const override
const ext::shared_ptr< YieldTermStructure > rTS_
const ext::shared_ptr< BlackVolTermStructure > volTS_
Array apply(const Array &r) const override
const ext::shared_ptr< LocalVolTermStructure > localVol_
const Real illegalLocalVolOverwrite_
extended version of the QuantLib class, see the documentation for details
Filter close_enough(const RandomVariable &x, const RandomVariable &y)