24#include <ql/exercise.hpp>
25#include <ql/methods/finitedifferences/meshers/concentrating1dmesher.hpp>
26#include <ql/methods/finitedifferences/meshers/fdmcev1dmesher.hpp>
27#include <ql/methods/finitedifferences/meshers/fdmmeshercomposite.hpp>
28#include <ql/methods/finitedifferences/operators/fdmcevop.hpp>
29#include <ql/methods/finitedifferences/operators/fdmlinearoplayout.hpp>
30#include <ql/methods/finitedifferences/solvers/fdm1dimsolver.hpp>
31#include <ql/methods/finitedifferences/stepconditions/fdmstepconditioncomposite.hpp>
32#include <ql/methods/finitedifferences/utilities/fdmdiscountdirichletboundary.hpp>
33#include <ql/methods/finitedifferences/utilities/fdminnervaluecalculator.hpp>
34#include <ql/methods/finitedifferences/utilities/fdmtimedepdirichletboundary.hpp>
35#include <ql/pricingengines/vanilla/analyticcevengine.hpp>
36#include <ql/pricingengines/vanilla/fdcevvanillaengine.hpp>
37#include <ql/termstructures/yieldtermstructure.hpp>
43 class PriceAtBoundary {
45 PriceAtBoundary(
Time maturityTime,
46 ext::shared_ptr<StrikedTypePayoff> payoff,
47 ext::shared_ptr<YieldTermStructure> rTS,
48 ext::shared_ptr<CEVCalculator> calculator)
49 : maturityTime_(maturityTime), payoff_(
std::move(payoff)),
50 calculator_(
std::move(calculator)), rTS_(
std::move(rTS)) {}
53 const Time time2Expiry = std::max(1/365., maturityTime_ - t);
55 rTS_->discount(maturityTime_) / rTS_->discount(t);
57 return df * calculator_->value(
58 payoff_->optionType(), payoff_->strike(), time2Expiry);
62 const Time maturityTime_;
63 const ext::shared_ptr<StrikedTypePayoff> payoff_;
64 const ext::shared_ptr<CEVCalculator> calculator_;
65 const ext::shared_ptr<YieldTermStructure> rTS_;
79 : f0_(f0), alpha_(alpha), beta_(beta), discountCurve_(
std::move(discountCurve)), tGrid_(tGrid),
80 xGrid_(xGrid), dampingSteps_(dampingSteps), scalingFactor_(scalingFactor), eps_(eps),
81 schemeDesc_(schemeDesc) {
88 const ext::shared_ptr<StrikedTypePayoff> payoff =
89 ext::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff);
90 QL_REQUIRE(payoff,
"non-striked payoff given");
92 const ext::shared_ptr<YieldTermStructure> rTS =
97 const Date referenceDate = rTS->referenceDate();
98 const Date maturityDate = arguments_.exercise->lastDate();
101 const ext::shared_ptr<Fdm1dMesher> cevMesher =
102 ext::make_shared<FdmCEV1dMesher>(
106 std::make_pair(payoff->strike(), 0.1));
108 const Real lowerBound = cevMesher->locations().front();
109 const Real upperBound = cevMesher->locations().back();
111 const ext::shared_ptr<FdmMesher> mesher =
112 ext::make_shared<FdmMesherComposite>(cevMesher);
115 const ext::shared_ptr<FdmInnerValueCalculator> calculator =
116 ext::make_shared<FdmCellAveragingInnerValue>(payoff, mesher, 0);
119 const ext::shared_ptr<FdmStepConditionComposite> conditions =
128 const PriceAtBoundary upperBoundPrice(
129 maturityTime, payoff, rTS,
130 ext::make_shared<CEVCalculator>(upperBound,
alpha_,
beta_));
132 boundaries.push_back(ext::make_shared<FdmTimeDepDirichletBoundary>(
133 mesher, ext::function<
Real (
Real)>(upperBoundPrice),
138 const Real terminalCashFlow = (*payoff)(lowerBound);
140 boundaries.push_back(
141 ext::make_shared<FdmDiscountDirichletBoundary>(
142 mesher, rTS, maturityTime, terminalCashFlow,
148 mesher, boundaries, conditions,
152 const ext::shared_ptr<FdmLinearOpComposite> op =
153 ext::make_shared<FdmCEVOp>(
156 const ext::shared_ptr<Fdm1DimSolver> solver =
157 ext::make_shared<Fdm1DimSolver>(solverDesc,
schemeDesc_, op);
159 results_.value = solver->interpolateAt(
f0_);
160 results_.delta = solver->derivativeX(
f0_);
161 results_.gamma = solver->derivativeXX(
f0_);
162 results_.theta = solver->thetaAt(
f0_);
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.
const Handle< YieldTermStructure > discountCurve_
void calculate() const override
FdCEVVanillaEngine(Real f0, Real alpha, Real beta, Handle< YieldTermStructure > discountCurve, Size tGrid=50, Size xGrid=400, Size dampingSteps=0, Real scalingFactor=1.0, Real eps=1e-4, const FdmSchemeDesc &schemeDesc=FdmSchemeDesc::Douglas())
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.
Real Time
continuous quantity with 1-year units
Real DiscountFactor
discount factor between dates
std::size_t Size
size of a container
std::vector< ext::shared_ptr< Dividend > > DividendSchedule
OperatorTraits< FdmLinearOp >::bc_set FdmBoundaryConditionSet