QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
fdmhestonop.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2008 Andreas Gaida
5 Copyright (C) 2008 Ralph Schreyer
6 Copyright (C) 2008, 2014, 2015 Klaus Spanderen
7 Copyright (C) 2015 Johannes Göttker-Schnetmann
8
9 This file is part of QuantLib, a free-software/open-source library
10 for financial quantitative analysts and developers - http://quantlib.org/
11
12 QuantLib is free software: you can redistribute it and/or modify it
13 under the terms of the QuantLib license. You should have received a
14 copy of the license along with this program; if not, please email
15 <quantlib-dev@lists.sf.net>. The license is also available online at
16 <http://quantlib.org/license.shtml>.
17
18 This program is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20 FOR A PARTICULAR PURPOSE. See the license for more details.
21*/
22
23#include <ql/methods/finitedifferences/meshers/fdmmesher.hpp>
24#include <ql/methods/finitedifferences/operators/fdmhestonop.hpp>
25#include <ql/methods/finitedifferences/operators/fdmlinearoplayout.hpp>
26#include <ql/methods/finitedifferences/operators/secondderivativeop.hpp>
27#include <ql/methods/finitedifferences/operators/secondordermixedderivativeop.hpp>
28#include <utility>
29
30namespace QuantLib {
31
32 FdmHestonEquityPart::FdmHestonEquityPart(const ext::shared_ptr<FdmMesher>& mesher,
33 ext::shared_ptr<YieldTermStructure> rTS,
34 ext::shared_ptr<YieldTermStructure> qTS,
35 ext::shared_ptr<FdmQuantoHelper> quantoHelper,
36 ext::shared_ptr<LocalVolTermStructure> leverageFct)
37 : varianceValues_(0.5 * mesher->locations(1)), dxMap_(FirstDerivativeOp(0, mesher)),
38 dxxMap_(SecondDerivativeOp(0, mesher).mult(0.5 * mesher->locations(1))), mapT_(0, mesher),
39 mesher_(mesher), rTS_(std::move(rTS)), qTS_(std::move(qTS)),
40 quantoHelper_(std::move(quantoHelper)), leverageFct_(std::move(leverageFct)) {
41
42 // on the boundary s_min and s_max the second derivative
43 // d^2V/dS^2 is zero and due to Ito's Lemma the variance term
44 // in the drift should vanish.
45 for (const auto& iter : *mesher_->layout()) {
46 if ( iter.coordinates()[0] == 0
47 || iter.coordinates()[0] == mesher_->layout()->dim()[0]-1) {
48 varianceValues_[iter.index()] = 0.0;
49 }
50 }
52 }
53
55 const Rate r = rTS_->forwardRate(t1, t2, Continuous).rate();
56 const Rate q = qTS_->forwardRate(t1, t2, Continuous).rate();
57
58 L_ = getLeverageFctSlice(t1, t2);
59 const Array Lsquare = L_*L_;
60
61 if (quantoHelper_ != nullptr) {
62 mapT_.axpyb(r - q - varianceValues_*Lsquare
63 - quantoHelper_->quantoAdjustment(
64 volatilityValues_*L_, t1, t2),
65 dxMap_, dxxMap_.mult(Lsquare), Array(1, -0.5*r));
66 } else {
67 mapT_.axpyb(r - q - varianceValues_*Lsquare, dxMap_,
68 dxxMap_.mult(Lsquare), Array(1, -0.5*r));
69 }
70 }
71
73
74 Array v(mesher_->layout()->size(), 1.0);
75
76 if (!leverageFct_) {
77 return v;
78 }
79 const Real t = 0.5*(t1+t2);
80 const Time time = std::min(leverageFct_->maxTime(), t);
81
82 for (const auto& iter : *mesher_->layout()) {
83 const Size nx = iter.coordinates()[0];
84
85 if (iter.coordinates()[1] == 0) {
86 const Real x = std::exp(mesher_->location(iter, 0));
87 const Real spot = std::min(leverageFct_->maxStrike(),
88 std::max(leverageFct_->minStrike(), x));
89 v[nx] = std::max(0.01, leverageFct_->localVol(time, spot, true));
90 }
91 else {
92 v[iter.index()] = v[nx];
93 }
94 }
95 return v;
96 }
97
98
100 return mapT_;
101 }
102
103 FdmHestonVariancePart::FdmHestonVariancePart(const ext::shared_ptr<FdmMesher>& mesher,
104 ext::shared_ptr<YieldTermStructure> rTS,
105 Real mixedSigma,
106 Real kappa,
107 Real theta)
108 : dyMap_(SecondDerivativeOp(1, mesher)
109 .mult(0.5 * mixedSigma * mixedSigma * mesher->locations(1))
110 .add(FirstDerivativeOp(1, mesher).mult(kappa * (theta - mesher->locations(1))))),
111 mapT_(1, mesher), rTS_(std::move(rTS)) {}
112
114 const Rate r = rTS_->forwardRate(t1, t2, Continuous).rate();
115 mapT_.axpyb(Array(), dyMap_, dyMap_, Array(1,-0.5*r));
116 }
117
119 return mapT_;
120 }
121
123 const ext::shared_ptr<FdmMesher>& mesher,
124 const ext::shared_ptr<HestonProcess> & hestonProcess,
125 const ext::shared_ptr<FdmQuantoHelper>& quantoHelper,
126 const ext::shared_ptr<LocalVolTermStructure>& leverageFct,
127 const Real mixingFactor)
128 : correlationMap_(SecondOrderMixedDerivativeOp(0, 1, mesher)
129 .mult(hestonProcess->rho()*hestonProcess->sigma()
130 *mixingFactor
131 *mesher->locations(1))),
132 dyMap_(mesher, hestonProcess->riskFreeRate().currentLink(),
133 hestonProcess->sigma()*mixingFactor,
134 hestonProcess->kappa(),
135 hestonProcess->theta()),
136 dxMap_(mesher,
137 hestonProcess->riskFreeRate().currentLink(),
138 hestonProcess->dividendYield().currentLink(),
139 quantoHelper, leverageFct) {
140 }
141
142
144 dxMap_.setTime(t1, t2);
145 dyMap_.setTime(t1, t2);
146 }
147
149 return 2;
150 }
151
153 return dyMap_.getMap().apply(u) + dxMap_.getMap().apply(u)
155 }
156
158 const Array& r) const {
159 if (direction == 0)
160 return dxMap_.getMap().apply(r);
161 else if (direction == 1)
162 return dyMap_.getMap().apply(r);
163 else
164 QL_FAIL("direction too large");
165 }
166
168 return dxMap_.getL()*correlationMap_.apply(r);
169 }
170
172 const Array& r, Real a) const {
173
174 if (direction == 0) {
175 return dxMap_.getMap().solve_splitting(r, a, 1.0);
176 }
177 else if (direction == 1) {
178 return dyMap_.getMap().solve_splitting(r, a, 1.0);
179 }
180 else
181 QL_FAIL("direction too large");
182 }
183
185 return solve_splitting(1, solve_splitting(0, r, dt), dt) ;
186 }
187
188 std::vector<SparseMatrix> FdmHestonOp::toMatrixDecomp() const {
189 return {
193 };
194 }
195
196}
1-D array used in linear algebra.
Definition: array.hpp:52
void setTime(Time t1, Time t2)
Definition: fdmhestonop.cpp:54
const Array & getL() const
Definition: fdmhestonop.hpp:51
const TripleBandLinearOp & getMap() const
Definition: fdmhestonop.cpp:99
FdmHestonEquityPart(const ext::shared_ptr< FdmMesher > &mesher, ext::shared_ptr< YieldTermStructure > rTS, ext::shared_ptr< YieldTermStructure > qTS, ext::shared_ptr< FdmQuantoHelper > quantoHelper, ext::shared_ptr< LocalVolTermStructure > leverageFct=ext::shared_ptr< LocalVolTermStructure >())
Definition: fdmhestonop.cpp:32
const TripleBandLinearOp dxxMap_
Definition: fdmhestonop.hpp:58
const ext::shared_ptr< FdmQuantoHelper > quantoHelper_
Definition: fdmhestonop.hpp:63
const ext::shared_ptr< LocalVolTermStructure > leverageFct_
Definition: fdmhestonop.hpp:64
TripleBandLinearOp mapT_
Definition: fdmhestonop.hpp:59
const ext::shared_ptr< YieldTermStructure > qTS_
Definition: fdmhestonop.hpp:62
const FirstDerivativeOp dxMap_
Definition: fdmhestonop.hpp:57
const ext::shared_ptr< FdmMesher > mesher_
Definition: fdmhestonop.hpp:61
Array getLeverageFctSlice(Time t1, Time t2) const
Definition: fdmhestonop.cpp:72
const ext::shared_ptr< YieldTermStructure > rTS_
Definition: fdmhestonop.hpp:62
Size size() const override
FdmHestonEquityPart dxMap_
FdmHestonVariancePart dyMap_
Array apply_direction(Size direction, const Array &r) const override
Array preconditioner(const Array &r, Real s) const override
std::vector< SparseMatrix > toMatrixDecomp() const override
void setTime(Time t1, Time t2) override
Time is required.
Array apply_mixed(const Array &r) const override
NinePointLinearOp correlationMap_
Array solve_splitting(Size direction, const Array &r, Real s) const override
FdmHestonOp(const ext::shared_ptr< FdmMesher > &mesher, const ext::shared_ptr< HestonProcess > &hestonProcess, const ext::shared_ptr< FdmQuantoHelper > &quantoHelper=ext::shared_ptr< FdmQuantoHelper >(), const ext::shared_ptr< LocalVolTermStructure > &leverageFct=ext::shared_ptr< LocalVolTermStructure >(), Real mixingFactor=1.0)
Array apply(const Array &r) const override
void setTime(Time t1, Time t2)
const TripleBandLinearOp & getMap() const
const TripleBandLinearOp dyMap_
Definition: fdmhestonop.hpp:79
FdmHestonVariancePart(const ext::shared_ptr< FdmMesher > &mesher, ext::shared_ptr< YieldTermStructure > rTS, Real mixedSigma, Real kappa, Real theta)
const ext::shared_ptr< YieldTermStructure > rTS_
Definition: fdmhestonop.hpp:82
SparseMatrix toMatrix() const override
Array apply(const Array &r) const override
SparseMatrix toMatrix() const override
Array solve_splitting(const Array &r, Real a, Real b=1.0) const
void axpyb(const Array &a, const TripleBandLinearOp &x, const TripleBandLinearOp &y, const Array &b)
TripleBandLinearOp mult(const Array &u) const
Array apply(const Array &r) const override
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
Array Sqrt(const Array &v)
Definition: array.hpp:847
STL namespace.