/src/quantlib/ql/pricingengines/vanilla/batesengine.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | |
3 | | /* |
4 | | Copyright (C) 2005 Klaus Spanderen |
5 | | Copyright (C) 2007 StatPro Italia srl |
6 | | |
7 | | This file is part of QuantLib, a free-software/open-source library |
8 | | for financial quantitative analysts and developers - http://quantlib.org/ |
9 | | |
10 | | QuantLib is free software: you can redistribute it and/or modify it |
11 | | under the terms of the QuantLib license. You should have received a |
12 | | copy of the license along with this program; if not, please email |
13 | | <quantlib-dev@lists.sf.net>. The license is also available online at |
14 | | <http://quantlib.org/license.shtml>. |
15 | | |
16 | | This program is distributed in the hope that it will be useful, but WITHOUT |
17 | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
18 | | FOR A PARTICULAR PURPOSE. See the license for more details. |
19 | | */ |
20 | | |
21 | | #include <ql/pricingengines/vanilla/batesengine.hpp> |
22 | | #include <ql/instruments/payoffs.hpp> |
23 | | |
24 | | namespace QuantLib { |
25 | | |
26 | | BatesEngine::BatesEngine(const ext::shared_ptr<BatesModel> & model, |
27 | | Size integrationOrder) |
28 | 0 | : AnalyticHestonEngine( |
29 | 0 | model, AnalyticHestonEngine::Gatheral, |
30 | 0 | AnalyticHestonEngine::Integration::gaussLaguerre(integrationOrder)) { } |
31 | | |
32 | | BatesEngine::BatesEngine(const ext::shared_ptr<BatesModel>& model, |
33 | | Real relTolerance, Size maxEvaluations) |
34 | 0 | : AnalyticHestonEngine( |
35 | 0 | model, AnalyticHestonEngine::Gatheral, |
36 | 0 | AnalyticHestonEngine::Integration::gaussLobatto( |
37 | 0 | relTolerance, Null<Real>(), maxEvaluations)) { } |
38 | | |
39 | | std::complex<Real> BatesEngine::addOnTerm( |
40 | 0 | Real phi, Time t, Size j) const { |
41 | | |
42 | 0 | ext::shared_ptr<BatesModel> batesModel = |
43 | 0 | ext::dynamic_pointer_cast<BatesModel>(*model_); |
44 | |
|
45 | 0 | const Real nu_ = batesModel->nu(); |
46 | 0 | const Real delta2_ = 0.5*batesModel->delta()*batesModel->delta(); |
47 | 0 | const Real lambda_ = batesModel->lambda(); |
48 | 0 | const Real i = (j == 1)? 1.0 : 0.0; |
49 | 0 | const std::complex<Real> g(i, phi); |
50 | | |
51 | | //it can throw: to be fixed |
52 | 0 | return t*lambda_*(std::exp(nu_*g + delta2_*g*g) - 1.0 |
53 | 0 | -g*(std::exp(nu_+delta2_) - 1.0)); |
54 | 0 | } |
55 | | |
56 | | |
57 | | BatesDetJumpEngine::BatesDetJumpEngine( |
58 | | const ext::shared_ptr<BatesDetJumpModel>& model, |
59 | | Size integrationOrder) |
60 | 0 | : BatesEngine(model, integrationOrder) { } |
61 | | |
62 | | BatesDetJumpEngine::BatesDetJumpEngine( |
63 | | const ext::shared_ptr<BatesDetJumpModel>& model, |
64 | | Real relTolerance, Size maxEvaluations) |
65 | 0 | : BatesEngine(model, relTolerance, maxEvaluations) { } |
66 | | |
67 | | std::complex<Real> BatesDetJumpEngine::addOnTerm( |
68 | 0 | Real phi, Time t, Size j) const { |
69 | |
|
70 | 0 | const std::complex<Real> l = |
71 | 0 | BatesEngine::addOnTerm(phi, t, j); |
72 | |
|
73 | 0 | ext::shared_ptr<BatesDetJumpModel> batesDetJumpModel = |
74 | 0 | ext::dynamic_pointer_cast<BatesDetJumpModel>(*model_); |
75 | |
|
76 | 0 | const Real lambda = batesDetJumpModel->lambda(); |
77 | 0 | const Real kappaLambda = batesDetJumpModel->kappaLambda(); |
78 | 0 | const Real thetaLambda = batesDetJumpModel->thetaLambda(); |
79 | |
|
80 | 0 | return (kappaLambda*t - 1.0 + std::exp(-kappaLambda*t)) |
81 | 0 | * thetaLambda*l/(kappaLambda*t*lambda) |
82 | 0 | + (1.0 - std::exp(-kappaLambda*t))*l/(kappaLambda*t); |
83 | 0 | } |
84 | | |
85 | | |
86 | | BatesDoubleExpEngine::BatesDoubleExpEngine( |
87 | | const ext::shared_ptr<BatesDoubleExpModel> & model, |
88 | | Size integrationOrder) |
89 | 0 | : AnalyticHestonEngine( |
90 | 0 | model, AnalyticHestonEngine::Gatheral, |
91 | 0 | AnalyticHestonEngine::Integration::gaussLaguerre(integrationOrder)) { } |
92 | | |
93 | | BatesDoubleExpEngine::BatesDoubleExpEngine( |
94 | | const ext::shared_ptr<BatesDoubleExpModel>& model, |
95 | | Real relTolerance, Size maxEvaluations) |
96 | 0 | : AnalyticHestonEngine( |
97 | 0 | model, AnalyticHestonEngine::Gatheral, |
98 | 0 | AnalyticHestonEngine::Integration::gaussLobatto( |
99 | 0 | relTolerance, Null<Real>(), maxEvaluations)) { } |
100 | | |
101 | | std::complex<Real> BatesDoubleExpEngine::addOnTerm( |
102 | 0 | Real phi, Time t, Size j) const { |
103 | 0 | ext::shared_ptr<BatesDoubleExpModel> batesDoubleExpModel = |
104 | 0 | ext::dynamic_pointer_cast<BatesDoubleExpModel>(*model_); |
105 | |
|
106 | 0 | const Real p_ = batesDoubleExpModel->p(); |
107 | 0 | const Real q_ = 1.0-p_; |
108 | 0 | const Real nuDown_= batesDoubleExpModel->nuDown(); |
109 | 0 | const Real nuUp_ = batesDoubleExpModel->nuUp(); |
110 | 0 | const Real lambda_= batesDoubleExpModel->lambda(); |
111 | 0 | const Real i = (j == 1)? 1.0 : 0.0; |
112 | 0 | const std::complex<Real> g(i, phi); |
113 | |
|
114 | 0 | return t*lambda_*(p_/(1.0-g*nuUp_) + q_/(1.0+g*nuDown_) - 1.0 |
115 | 0 | - g*(p_/(1-nuUp_) + q_/(1+nuDown_)-1)); |
116 | 0 | } |
117 | | |
118 | | BatesDoubleExpDetJumpEngine::BatesDoubleExpDetJumpEngine( |
119 | | const ext::shared_ptr<BatesDoubleExpDetJumpModel> & model, |
120 | | Size integrationOrder) |
121 | 0 | : BatesDoubleExpEngine(model, integrationOrder) { } |
122 | | |
123 | | BatesDoubleExpDetJumpEngine::BatesDoubleExpDetJumpEngine( |
124 | | const ext::shared_ptr<BatesDoubleExpDetJumpModel>& model, |
125 | | Real relTolerance, Size maxEvaluations) |
126 | 0 | : BatesDoubleExpEngine(model, relTolerance, maxEvaluations) { } |
127 | | |
128 | | std::complex<Real> BatesDoubleExpDetJumpEngine::addOnTerm( |
129 | 0 | Real phi, Time t, Size j) const { |
130 | 0 | const std::complex<Real> l = |
131 | 0 | BatesDoubleExpEngine::addOnTerm(phi, t, j); |
132 | |
|
133 | 0 | ext::shared_ptr<BatesDoubleExpDetJumpModel> doubleExpDetJumpModel |
134 | 0 | = ext::dynamic_pointer_cast<BatesDoubleExpDetJumpModel>(*model_); |
135 | |
|
136 | 0 | const Real lambda = doubleExpDetJumpModel->lambda(); |
137 | 0 | const Real kappaLambda = doubleExpDetJumpModel->kappaLambda(); |
138 | 0 | const Real thetaLambda = doubleExpDetJumpModel->thetaLambda(); |
139 | |
|
140 | 0 | return (kappaLambda*t - 1.0 + std::exp(-kappaLambda*t)) |
141 | 0 | * thetaLambda*l/(kappaLambda*t*lambda) |
142 | 0 | + (1.0 - std::exp(-kappaLambda*t))*l/(kappaLambda*t); |
143 | 0 | } |
144 | | |
145 | | } |