QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
fdsimpleklugeextouvppengine.cpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2011 Klaus Spanderen
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
20/*! \file fdsimpleklugeouvppengine.cpp
21 \brief Finite Differences engine for simple vpp options
22*/
23
24
43#include <list>
44#include <utility>
45
46namespace QuantLib {
47
48 namespace {
49 class FdmSparkSpreadInnerValue : public FdmInnerValueCalculator {
50
51 public:
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)) {}
57
58 Real innerValue(const FdmLinearOpIterator& iter, Time t) override {
59 Array s(2);
60 s[0] = powerPrice_->innerValue(iter, t);
61 s[1] = fuelPrice_->innerValue(iter, t);
62
63 return (*basketPayoff_)(s);
64 }
65 Real avgInnerValue(const FdmLinearOpIterator& iter, Time t) override {
66 return innerValue(iter, t);
67 }
68
69 private:
70 const ext::shared_ptr<BasketPayoff> basketPayoff_;
71 const ext::shared_ptr<FdmInnerValueCalculator> fuelPrice_;
72 const ext::shared_ptr<FdmInnerValueCalculator> powerPrice_;
73 };
74 }
75
76
78 ext::shared_ptr<KlugeExtOUProcess> process,
79 ext::shared_ptr<YieldTermStructure> rTS,
80 ext::shared_ptr<Shape> fuelShape,
81 ext::shared_ptr<Shape> powerShape,
82 Real fuelCostAddon,
83 Size tGrid,
84 Size xGrid,
85 Size yGrid,
86 Size gGrid,
87 const FdmSchemeDesc& schemeDesc)
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) {}
91
93
94 ext::shared_ptr<SwingExercise> swingExercise(
95 ext::dynamic_pointer_cast<SwingExercise>(arguments_.exercise));
96
97 QL_REQUIRE(swingExercise, "Swing exercise supported only");
98
99 const FdmVPPStepConditionFactory stepConditionFactory(arguments_);
100
101 // 1. Exercise definition
102 const std::vector<Time> exerciseTimes
103 = swingExercise->exerciseTimes(rTS_->dayCounter(),
104 rTS_->referenceDate());
105
106 // 2. mesher set-up
107 const Time maturity = exerciseTimes.back();
108 const ext::shared_ptr<ExtOUWithJumpsProcess> klugeProcess
109 = process_->getKlugeProcess();
110
111 const ext::shared_ptr<StochasticProcess1D> klugeOUProcess
112 = klugeProcess->getExtendedOrnsteinUhlenbeckProcess();
113
114 const ext::shared_ptr<Fdm1dMesher> xMesher(
115 new FdmSimpleProcess1dMesher(xGrid_, klugeOUProcess, maturity));
116
117 const ext::shared_ptr<Fdm1dMesher> yMesher(
119 klugeProcess->beta(),
120 klugeProcess->jumpIntensity(),
121 klugeProcess->eta(), 1e-3));
122
123 const ext::shared_ptr<Fdm1dMesher> gMesher(
125 process_->getExtOUProcess(),maturity));
126
127 const ext::shared_ptr<Fdm1dMesher> exerciseMesher(
128 stepConditionFactory.stateMesher());
129
130 const ext::shared_ptr<FdmMesher> mesher (
131 new FdmMesherComposite(xMesher, yMesher, gMesher, exerciseMesher));
132
133 // 3. Calculator
134 const ext::shared_ptr<FdmInnerValueCalculator> zeroInnerValue(
135 new FdmZeroInnerValue());
136
137 const ext::shared_ptr<Payoff> zeroStrikeCall(
139
140 const ext::shared_ptr<FdmInnerValueCalculator> fuelPrice(
141 new FdmExpExtOUInnerValueCalculator(zeroStrikeCall,
142 mesher, fuelShape_, 2));
143
144 const ext::shared_ptr<FdmInnerValueCalculator> powerPrice(
145 new FdmExtOUJumpModelInnerValue(zeroStrikeCall,mesher,powerShape_));
146
147 const ext::shared_ptr<FdmInnerValueCalculator> sparkSpread(
148 new FdmSparkSpreadInnerValue(
149 ext::dynamic_pointer_cast<BasketPayoff>(arguments_.payoff),
150 fuelPrice, powerPrice));
151
152 // 4. Step conditions
153 std::list<std::vector<Time> > stoppingTimes;
154 std::list<ext::shared_ptr<StepCondition<Array> > > stepConditions;
155
156 // 4.1 Bermudan step conditions
157 stoppingTimes.push_back(exerciseTimes);
158 const FdmVPPStepConditionMesher mesh = {3U, mesher};
159
160 const ext::shared_ptr<FdmVPPStepCondition> stepCondition(
161 stepConditionFactory.build(mesh, fuelCostAddon_,
162 fuelPrice, sparkSpread));
163
164 stepConditions.push_back(stepCondition);
165
166 const ext::shared_ptr<FdmStepConditionComposite> conditions(
167 new FdmStepConditionComposite(stoppingTimes, stepConditions));
168
169 // 5. Boundary conditions
170 const FdmBoundaryConditionSet boundaries;
171
172 // 6. set-up solver
173 FdmSolverDesc solverDesc = { mesher, boundaries, conditions,
174 zeroInnerValue, maturity, tGrid_, 0 };
175
176 const ext::shared_ptr<FdmKlugeExtOUSolver<4> > solver(
178 rTS_, solverDesc, schemeDesc_));
179
180 std::vector<Real> x(4);
181 x[0] = process_->initialValues()[0];
182 x[1] = process_->initialValues()[1];
183 x[2] = process_->initialValues()[2];
184
185 const Real tol = 1e-8;
186 const Real maxExerciseValue = exerciseMesher->locations().back();
187 const Real minExerciseValue = exerciseMesher->locations().front();
188
189 Array results(exerciseMesher->size());
190 for (Size i=0; i < results.size(); ++i) {
191
192 x[3] = std::max(minExerciseValue + tol,
193 std::min(exerciseMesher->location(i),
194 maxExerciseValue - tol));
195 results[i] = solver->valueAt(x);
196 }
197 results_.value = stepCondition->maxValue(results);
198 }
199}
Basket option on a number of assets.
1-D array used in linear algebra.
Definition: array.hpp:52
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< YieldTermStructure > rTS_
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
Shared handle to an observable.
Definition: handle.hpp:41
ext::shared_ptr< Exercise > exercise
Definition: option.hpp:65
ext::shared_ptr< Payoff > payoff
Definition: option.hpp:64
Plain-vanilla payoff.
Definition: payoffs.hpp:105
const DefaultType & t
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
mesher for a exponential jump mesher with high mean reversion rate and low jump intensity
extended Ornstein-Uhlenbeck process
Ornstein Uhlenbeck process plus exp jumps (Kluge Model)
One-dimensional simple FDM mesher object working on an index.
const ext::shared_ptr< YieldTermStructure > rTS_
inner value calculator for an exponential extended Ornstein Uhlenbeck grid
Kluge/extended Ornstein-Uhlenbeck FDM solver.
memory layout of a fdm linear operator
FdmMesher which is a composite of Fdm1dMesher.
One-dimensional grid mesher.
composite of fdm step conditions
factory for VPP step conditions for FD models
const ext::shared_ptr< FdmInnerValueCalculator > fuelPrice_
const ext::shared_ptr< BasketPayoff > basketPayoff_
const ext::shared_ptr< FdmInnerValueCalculator > powerPrice_
Finite Differences engine for simple vpp options.
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
joint Kluge process an d Ornstein Uhlenbeck process
Definition: any.hpp:35
OperatorTraits< FdmLinearOp >::bc_set FdmBoundaryConditionSet
STL namespace.
One-dimensional simple uniform grid mesher.
vanilla swing option class
Interest-rate term structure.