22#include <ql/exercise.hpp>
23#include <ql/math/distributions/normaldistribution.hpp>
24#include <ql/methods/finitedifferences/meshers/concentrating1dmesher.hpp>
25#include <ql/methods/finitedifferences/meshers/fdmcev1dmesher.hpp>
26#include <ql/methods/finitedifferences/meshers/fdmmeshercomposite.hpp>
27#include <ql/methods/finitedifferences/operators/fdmsabrop.hpp>
28#include <ql/methods/finitedifferences/solvers/fdm2dimsolver.hpp>
29#include <ql/methods/finitedifferences/stepconditions/fdmstepconditioncomposite.hpp>
30#include <ql/methods/finitedifferences/utilities/cevrndcalculator.hpp>
31#include <ql/methods/finitedifferences/utilities/fdmdiscountdirichletboundary.hpp>
32#include <ql/methods/finitedifferences/utilities/fdminnervaluecalculator.hpp>
33#include <ql/pricingengines/vanilla/fdsabrvanillaengine.hpp>
34#include <ql/termstructures/volatility/sabr.hpp>
35#include <ql/termstructures/yieldtermstructure.hpp>
53 : f0_(f0), alpha_(alpha), beta_(beta), nu_(nu), rho_(rho), rTS_(
std::move(rTS)), tGrid_(tGrid),
54 fGrid_(fGrid), xGrid_(xGrid), dampingSteps_(dampingSteps), scalingFactor_(scalingFactor),
55 eps_(eps), schemeDesc_(schemeDesc) {
59 QL_REQUIRE(beta<1.0,
"beta must be smaller than 1.0: "
60 << beta <<
" not allowed");
67 const ext::shared_ptr<StrikedTypePayoff> payoff =
68 ext::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff);
69 QL_REQUIRE(payoff,
"non-striked payoff given");
73 const Date referenceDate =
rTS_->referenceDate();
74 const Date maturityDate = arguments_.exercise->lastDate();
80 const ext::shared_ptr<Fdm1dMesher> cevMesher =
81 ext::make_shared<FdmCEV1dMesher>(
84 std::make_pair(payoff->strike(), 0.025));
87 const Real logDrift = -0.5*
nu_*
nu_*maturityTime;
91 const Real xMin = std::log(
alpha_) + logDrift - volRange;
92 const Real xMax = std::log(
alpha_) + logDrift + volRange;
94 const ext::shared_ptr<Fdm1dMesher> xMesher =
95 ext::make_shared<Concentrating1dMesher>(
96 xMin, xMax,
xGrid_, std::make_pair(std::log(
alpha_), 0.1));
98 const ext::shared_ptr<FdmMesher> mesher =
99 ext::make_shared<FdmMesherComposite>(cevMesher, xMesher);
102 const ext::shared_ptr<FdmInnerValueCalculator> calculator =
103 ext::make_shared<FdmCellAveragingInnerValue>(payoff, mesher, 0);
106 const ext::shared_ptr<FdmStepConditionComposite> conditions =
109 mesher, calculator, referenceDate, dc);
114 const Real lowerBound = cevMesher->locations().front();
115 const Real upperBound = cevMesher->locations().back();
117 boundaries.push_back(
118 ext::make_shared<FdmDiscountDirichletBoundary>(
119 mesher,
rTS_.currentLink(),
120 maturityTime, (*payoff)(upperBound),
123 boundaries.push_back(
124 ext::make_shared<FdmDiscountDirichletBoundary>(
125 mesher,
rTS_.currentLink(),
126 maturityTime, (*payoff)(lowerBound),
131 mesher, boundaries, conditions,
135 const ext::shared_ptr<FdmLinearOpComposite> op =
136 ext::make_shared<FdmSabrOp>(
137 mesher,
rTS_.currentLink(),
140 const ext::shared_ptr<Fdm2DimSolver> solver =
141 ext::make_shared<Fdm2DimSolver>(solverDesc,
schemeDesc_, op);
143 results_.value = solver->interpolateAt(
f0_, std::log(
alpha_));
Time yearFraction(const Date &, const Date &, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date()) const
Returns the period between two dates as a fraction of year.
void calculate() const override
FdSabrVanillaEngine(Real f0, Real alpha, Real beta, Real nu, Real rho, Handle< YieldTermStructure > rTS, Size tGrid=50, Size fGrid=400, Size xGrid=50, Size dampingSteps=0, Real scalingFactor=1.0, Real eps=1e-4, const FdmSchemeDesc &schemeDesc=FdmSchemeDesc::Hundsdorfer())
const Handle< YieldTermStructure > rTS_
const Real scalingFactor_
const FdmSchemeDesc schemeDesc_
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)
Shared handle to an observable.
Inverse cumulative normal distribution function.
Real Time
continuous quantity with 1-year units
std::size_t Size
size of a container
std::vector< ext::shared_ptr< Dividend > > DividendSchedule
void validateSabrParameters(Real alpha, Real beta, Real nu, Real rho)
OperatorTraits< FdmLinearOp >::bc_set FdmBoundaryConditionSet