25#include <ql/experimental/finitedifferences/fdmexpextouinnervaluecalculator.hpp>
26#include <ql/experimental/finitedifferences/fdmklugeextousolver.hpp>
27#include <ql/experimental/finitedifferences/fdmvppstepconditionfactory.hpp>
28#include <ql/experimental/finitedifferences/fdsimpleklugeextouvppengine.hpp>
29#include <ql/experimental/processes/extendedornsteinuhlenbeckprocess.hpp>
30#include <ql/experimental/processes/extouwithjumpsprocess.hpp>
31#include <ql/experimental/processes/klugeextouprocess.hpp>
32#include <ql/instruments/basketoption.hpp>
33#include <ql/instruments/vanillaswingoption.hpp>
34#include <ql/methods/finitedifferences/meshers/exponentialjump1dmesher.hpp>
35#include <ql/methods/finitedifferences/meshers/fdm1dmesher.hpp>
36#include <ql/methods/finitedifferences/meshers/fdmmeshercomposite.hpp>
37#include <ql/methods/finitedifferences/meshers/fdmsimpleprocess1dmesher.hpp>
38#include <ql/methods/finitedifferences/meshers/uniform1dmesher.hpp>
39#include <ql/methods/finitedifferences/operators/fdmlinearoplayout.hpp>
40#include <ql/methods/finitedifferences/solvers/fdmsolverdesc.hpp>
41#include <ql/methods/finitedifferences/stepconditions/fdmstepconditioncomposite.hpp>
42#include <ql/termstructures/yieldtermstructure.hpp>
49 class FdmSparkSpreadInnerValue :
public FdmInnerValueCalculator {
52 FdmSparkSpreadInnerValue(ext::shared_ptr<BasketPayoff> basketPayoff,
53 ext::shared_ptr<FdmInnerValueCalculator> fuelPrice,
54 ext::shared_ptr<FdmInnerValueCalculator> powerPrice)
55 : basketPayoff_(
std::move(basketPayoff)), fuelPrice_(
std::move(fuelPrice)),
56 powerPrice_(
std::move(powerPrice)) {}
58 Real innerValue(
const FdmLinearOpIterator& iter,
Time t)
override {
60 s[0] = powerPrice_->innerValue(iter, t);
61 s[1] = fuelPrice_->innerValue(iter, t);
63 return (*basketPayoff_)(s);
65 Real avgInnerValue(
const FdmLinearOpIterator& iter,
Time t)
override {
66 return innerValue(iter, t);
70 const ext::shared_ptr<BasketPayoff> basketPayoff_;
71 const ext::shared_ptr<FdmInnerValueCalculator> fuelPrice_;
72 const ext::shared_ptr<FdmInnerValueCalculator> powerPrice_;
78 ext::shared_ptr<KlugeExtOUProcess> process,
79 ext::shared_ptr<YieldTermStructure> rTS,
80 ext::shared_ptr<Shape> fuelShape,
81 ext::shared_ptr<Shape> powerShape,
88 : process_(
std::move(process)), rTS_(
std::move(rTS)), fuelCostAddon_(fuelCostAddon),
89 fuelShape_(
std::move(fuelShape)), powerShape_(
std::move(powerShape)), tGrid_(tGrid),
90 xGrid_(xGrid), yGrid_(yGrid), gGrid_(gGrid), schemeDesc_(schemeDesc) {}
94 ext::shared_ptr<SwingExercise> swingExercise(
97 QL_REQUIRE(swingExercise,
"Swing exercise supported only");
102 const std::vector<Time> exerciseTimes
103 = swingExercise->exerciseTimes(
rTS_->dayCounter(),
104 rTS_->referenceDate());
107 const Time maturity = exerciseTimes.back();
108 const ext::shared_ptr<ExtOUWithJumpsProcess> klugeProcess
111 const ext::shared_ptr<StochasticProcess1D> klugeOUProcess
112 = klugeProcess->getExtendedOrnsteinUhlenbeckProcess();
114 const ext::shared_ptr<Fdm1dMesher> xMesher(
117 const ext::shared_ptr<Fdm1dMesher> yMesher(
119 klugeProcess->beta(),
120 klugeProcess->jumpIntensity(),
121 klugeProcess->eta(), 1e-3));
123 const ext::shared_ptr<Fdm1dMesher> gMesher(
125 process_->getExtOUProcess(),maturity));
127 const ext::shared_ptr<Fdm1dMesher> exerciseMesher(
130 const ext::shared_ptr<FdmMesher> mesher (
134 const ext::shared_ptr<FdmInnerValueCalculator> zeroInnerValue(
137 const ext::shared_ptr<Payoff> zeroStrikeCall(
140 const ext::shared_ptr<FdmInnerValueCalculator> fuelPrice(
144 const ext::shared_ptr<FdmInnerValueCalculator> powerPrice(
147 const ext::shared_ptr<FdmInnerValueCalculator> sparkSpread(
148 new FdmSparkSpreadInnerValue(
150 fuelPrice, powerPrice));
153 std::list<std::vector<Time> > stoppingTimes;
154 std::list<ext::shared_ptr<StepCondition<Array> > > stepConditions;
157 stoppingTimes.push_back(exerciseTimes);
160 const ext::shared_ptr<FdmVPPStepCondition> stepCondition(
162 fuelPrice, sparkSpread));
164 stepConditions.push_back(stepCondition);
166 const ext::shared_ptr<FdmStepConditionComposite> conditions(
174 zeroInnerValue, maturity,
tGrid_, 0 };
176 const ext::shared_ptr<FdmKlugeExtOUSolver<4> > solver(
180 std::vector<Real> x(4);
181 x[0] =
process_->initialValues()[0];
182 x[1] =
process_->initialValues()[1];
183 x[2] =
process_->initialValues()[2];
185 const Real tol = 1e-8;
186 const Real maxExerciseValue = exerciseMesher->locations().back();
187 const Real minExerciseValue = exerciseMesher->locations().front();
192 x[3] = std::max(minExerciseValue + tol,
193 std::min(exerciseMesher->location(i),
194 maxExerciseValue - tol));
195 results[i] = solver->valueAt(x);
1-D array used in linear algebra.
void calculate() const override
const ext::shared_ptr< KlugeExtOUProcess > process_
FdSimpleKlugeExtOUVPPEngine(ext::shared_ptr< KlugeExtOUProcess > process, ext::shared_ptr< YieldTermStructure > rTS, ext::shared_ptr< Shape > fuelShape, ext::shared_ptr< Shape > powerShape, Real fuelCostAddon, Size tGrid=1, Size xGrid=50, Size yGrid=10, Size gGrid=20, const FdmSchemeDesc &schemeDesc=FdmSchemeDesc::Hundsdorfer())
const ext::shared_ptr< Shape > powerShape_
const Real fuelCostAddon_
const ext::shared_ptr< YieldTermStructure > rTS_
const ext::shared_ptr< Shape > fuelShape_
const FdmSchemeDesc schemeDesc_
ext::shared_ptr< Fdm1dMesher > stateMesher() const
ext::shared_ptr< FdmVPPStepCondition > build(const FdmVPPStepConditionMesher &mesh, Real fuelCostAddon, const ext::shared_ptr< FdmInnerValueCalculator > &fuel, const ext::shared_ptr< FdmInnerValueCalculator > &spark) const
VanillaVPPOption::results results_
VanillaVPPOption::arguments arguments_
Shared handle to an observable.
ext::shared_ptr< Exercise > exercise
ext::shared_ptr< Payoff > payoff
Real Time
continuous quantity with 1-year units
std::size_t Size
size of a container
OperatorTraits< FdmLinearOp >::bc_set FdmBoundaryConditionSet