QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
fdm2dblackscholesop.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2010 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
24#include <ql/processes/blackscholesprocess.hpp>
25#include <ql/methods/finitedifferences/meshers/fdmmesher.hpp>
26#include <ql/methods/finitedifferences/operators/fdmlinearoplayout.hpp>
27#include <ql/methods/finitedifferences/operators/fdm2dblackscholesop.hpp>
28#include <ql/methods/finitedifferences/operators/secondordermixedderivativeop.hpp>
29#include <boost/numeric/ublas/matrix.hpp>
30
31namespace QuantLib {
32
34 const ext::shared_ptr<FdmMesher>& mesher,
35 const ext::shared_ptr<GeneralizedBlackScholesProcess>& p1,
36 const ext::shared_ptr<GeneralizedBlackScholesProcess>& p2,
37 Real correlation,
38 Time /*maturity*/,
39 bool localVol,
40 Real illegalLocalVolOverwrite)
41 : mesher_(mesher),
42 p1_(p1),
43 p2_(p2),
44
45 localVol1_((localVol) ? p1->localVolatility().currentLink()
46 : ext::shared_ptr<LocalVolTermStructure>()),
47 localVol2_((localVol) ? p2->localVolatility().currentLink()
48 : ext::shared_ptr<LocalVolTermStructure>()),
49
50 x_((localVol) ? Array(Exp(mesher->locations(0))) : Array()),
51 y_((localVol) ? Array(Exp(mesher->locations(1))) : Array()),
52
53 opX_(mesher, p1, p1->x0(), localVol, illegalLocalVolOverwrite, 0),
54 opY_(mesher, p2, p2->x0(), localVol, illegalLocalVolOverwrite, 1),
55
56 corrMapT_(0, 1, mesher),
57 corrMapTemplate_(SecondOrderMixedDerivativeOp(0, 1, mesher)
58 .mult(Array(mesher->layout()->size(), correlation))),
59
60 illegalLocalVolOverwrite_(illegalLocalVolOverwrite) {
61 }
62
64 return 2;
65 }
66
68 opX_.setTime(t1, t2);
69 opY_.setTime(t1, t2);
70
71 if (localVol1_ != nullptr) {
72 Array vol1(mesher_->layout()->size()), vol2(mesher_->layout()->size());
73 for (const auto& iter : *mesher_->layout()) {
74 const Size i = iter.index();
75
76 if (illegalLocalVolOverwrite_ < 0.0) {
77 vol1[i] = localVol1_->localVol(0.5*(t1+t2), x_[i], true);
78 vol2[i] = localVol2_->localVol(0.5*(t1+t2), y_[i], true);
79 }
80 else {
81 try {
82 vol1[i] = localVol1_->localVol(0.5*(t1+t2), x_[i],true);
83 } catch (Error&) {
85 }
86 try {
87 vol2[i] = localVol2_->localVol(0.5*(t1+t2), y_[i],true);
88 } catch (Error&) {
90 }
91
92 }
93 }
94 corrMapT_ = corrMapTemplate_.mult(vol1*vol2);
95 } else {
96 const Real vol1 = p1_
97 ->blackVolatility()->blackForwardVol(t1, t2, p1_->x0());
98
99 const Real vol2 = p2_
100 ->blackVolatility()->blackForwardVol(t1, t2, p2_->x0());
101
103 .mult(Array(mesher_->layout()->size(), vol1*vol2));
104 }
105
106 currentForwardRate_ = p1_->riskFreeRate()
107 ->forwardRate(t1, t2, Continuous).rate();
108 }
109
111 return opX_.apply(x) + opY_.apply(x) + apply_mixed(x);
112 }
113
115 return corrMapT_.apply(x) + currentForwardRate_*x;
116 }
117
119 Size direction, const Array& x) const {
120 if (direction == 0) {
121 return opX_.apply(x);
122 }
123 else if (direction == 1) {
124 return opY_.apply(x);
125 }
126 else {
127 QL_FAIL("direction is too large");
128 }
129 }
130
132 const Array& x, Real s) const {
133 if (direction == 0) {
134 return opX_.solve_splitting(direction, x, s);
135 }
136 else if (direction == 1) {
137 return opY_.solve_splitting(direction, x, s);
138 }
139 else
140 QL_FAIL("direction is too large");
141 }
142
144 Real dt) const {
145 return solve_splitting(0, r, dt);
146 }
147
148 std::vector<SparseMatrix> Fdm2dBlackScholesOp::toMatrixDecomp() const {
149 return {
150 opX_.toMatrix(),
151 opY_.toMatrix(),
153 currentForwardRate_*boost::numeric::ublas::identity_matrix<Real>(
154 mesher_->layout()->size())
155 };
156 }
157
158}
1-D array used in linear algebra.
Definition: array.hpp:52
Base error class.
Definition: errors.hpp:39
const ext::shared_ptr< LocalVolTermStructure > localVol2_
Fdm2dBlackScholesOp(const ext::shared_ptr< FdmMesher > &mesher, const ext::shared_ptr< GeneralizedBlackScholesProcess > &p1, const ext::shared_ptr< GeneralizedBlackScholesProcess > &p2, Real correlation, Time maturity, bool localVol=false, Real illegalLocalVolOverwrite=-Null< Real >())
Array solve_splitting(Size direction, const Array &x, Real s) const override
const NinePointLinearOp corrMapTemplate_
Array preconditioner(const Array &r, Real s) const override
std::vector< SparseMatrix > toMatrixDecomp() const override
const ext::shared_ptr< GeneralizedBlackScholesProcess > p1_
Array apply_mixed(const Array &x) const override
void setTime(Time t1, Time t2) override
Time is required.
Array apply(const Array &x) const override
Array apply_direction(Size direction, const Array &x) const override
const ext::shared_ptr< FdmMesher > mesher_
const ext::shared_ptr< GeneralizedBlackScholesProcess > p2_
const ext::shared_ptr< LocalVolTermStructure > localVol1_
void setTime(Time t1, Time t2) override
Time is required.
Array solve_splitting(Size direction, const Array &r, Real s) const override
Array apply(const Array &r) const override
SparseMatrix toMatrix() const override
SparseMatrix toMatrix() const override
Array apply(const Array &r) const override
NinePointLinearOp mult(const Array &u) const
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
Definition: any.hpp:35
Array Exp(const Array &v)
Definition: array.hpp:875