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 
BatesEngine(const ext::shared_ptr<BatesModel> & model,Size integrationOrder)26     BatesEngine::BatesEngine(const ext::shared_ptr<BatesModel> & model,
27                              Size integrationOrder)
28     : AnalyticHestonEngine(model, integrationOrder) { }
29 
BatesEngine(const ext::shared_ptr<BatesModel> & model,Real relTolerance,Size maxEvaluations)30     BatesEngine::BatesEngine(const ext::shared_ptr<BatesModel>& model,
31                              Real relTolerance, Size maxEvaluations)
32     : AnalyticHestonEngine(model, relTolerance, maxEvaluations) { }
33 
addOnTerm(Real phi,Time t,Size j) const34     std::complex<Real> BatesEngine::addOnTerm(
35                                             Real phi, Time t, Size j) const {
36 
37         ext::shared_ptr<BatesModel> batesModel =
38                             ext::dynamic_pointer_cast<BatesModel>(*model_);
39 
40         const Real nu_     = batesModel->nu();
41         const Real delta2_ = 0.5*batesModel->delta()*batesModel->delta();
42         const Real lambda_ = batesModel->lambda();
43         const Real i       = (j == 1)? 1.0 : 0.0;
44         const std::complex<Real> g(i, phi);
45 
46         //it can throw: to be fixed
47         return t*lambda_*(std::exp(nu_*g + delta2_*g*g) - 1.0
48                           -g*(std::exp(nu_+delta2_) - 1.0));
49     }
50 
51 
BatesDetJumpEngine(const ext::shared_ptr<BatesDetJumpModel> & model,Size integrationOrder)52     BatesDetJumpEngine::BatesDetJumpEngine(
53         const ext::shared_ptr<BatesDetJumpModel>& model,
54         Size integrationOrder)
55     : BatesEngine(model, integrationOrder) { }
56 
BatesDetJumpEngine(const ext::shared_ptr<BatesDetJumpModel> & model,Real relTolerance,Size maxEvaluations)57     BatesDetJumpEngine::BatesDetJumpEngine(
58         const ext::shared_ptr<BatesDetJumpModel>& model,
59         Real relTolerance, Size maxEvaluations)
60     : BatesEngine(model, relTolerance, maxEvaluations) { }
61 
addOnTerm(Real phi,Time t,Size j) const62     std::complex<Real> BatesDetJumpEngine::addOnTerm(
63         Real phi, Time t, Size j) const {
64 
65         const std::complex<Real> l =
66             BatesEngine::addOnTerm(phi, t, j);
67 
68         ext::shared_ptr<BatesDetJumpModel> batesDetJumpModel =
69             ext::dynamic_pointer_cast<BatesDetJumpModel>(*model_);
70 
71         const Real lambda      = batesDetJumpModel->lambda();
72         const Real kappaLambda = batesDetJumpModel->kappaLambda();
73         const Real thetaLambda = batesDetJumpModel->thetaLambda();
74 
75         return (kappaLambda*t - 1.0 + std::exp(-kappaLambda*t))
76             * thetaLambda*l/(kappaLambda*t*lambda)
77             + (1.0 - std::exp(-kappaLambda*t))*l/(kappaLambda*t);
78     }
79 
80 
BatesDoubleExpEngine(const ext::shared_ptr<BatesDoubleExpModel> & model,Size integrationOrder)81     BatesDoubleExpEngine::BatesDoubleExpEngine(
82         const ext::shared_ptr<BatesDoubleExpModel> & model,
83         Size integrationOrder)
84     : AnalyticHestonEngine(model, integrationOrder) { }
85 
BatesDoubleExpEngine(const ext::shared_ptr<BatesDoubleExpModel> & model,Real relTolerance,Size maxEvaluations)86     BatesDoubleExpEngine::BatesDoubleExpEngine(
87         const ext::shared_ptr<BatesDoubleExpModel>& model,
88         Real relTolerance, Size maxEvaluations)
89     : AnalyticHestonEngine(model, relTolerance, maxEvaluations) { }
90 
addOnTerm(Real phi,Time t,Size j) const91     std::complex<Real> BatesDoubleExpEngine::addOnTerm(
92         Real phi, Time t, Size j) const {
93         ext::shared_ptr<BatesDoubleExpModel> batesDoubleExpModel =
94             ext::dynamic_pointer_cast<BatesDoubleExpModel>(*model_);
95 
96         const Real p_     = batesDoubleExpModel->p();
97         const Real q_     = 1.0-p_;
98         const Real nuDown_= batesDoubleExpModel->nuDown();
99         const Real nuUp_  = batesDoubleExpModel->nuUp();
100         const Real lambda_= batesDoubleExpModel->lambda();
101         const Real i      = (j == 1)? 1.0 : 0.0;
102         const std::complex<Real> g(i, phi);
103 
104         return t*lambda_*(p_/(1.0-g*nuUp_) + q_/(1.0+g*nuDown_) - 1.0
105                           - g*(p_/(1-nuUp_) + q_/(1+nuDown_)-1));
106     }
107 
BatesDoubleExpDetJumpEngine(const ext::shared_ptr<BatesDoubleExpDetJumpModel> & model,Size integrationOrder)108     BatesDoubleExpDetJumpEngine::BatesDoubleExpDetJumpEngine(
109         const ext::shared_ptr<BatesDoubleExpDetJumpModel> & model,
110         Size integrationOrder)
111     : BatesDoubleExpEngine(model, integrationOrder) { }
112 
BatesDoubleExpDetJumpEngine(const ext::shared_ptr<BatesDoubleExpDetJumpModel> & model,Real relTolerance,Size maxEvaluations)113     BatesDoubleExpDetJumpEngine::BatesDoubleExpDetJumpEngine(
114         const ext::shared_ptr<BatesDoubleExpDetJumpModel>& model,
115         Real relTolerance, Size maxEvaluations)
116     : BatesDoubleExpEngine(model, relTolerance, maxEvaluations) { }
117 
addOnTerm(Real phi,Time t,Size j) const118     std::complex<Real> BatesDoubleExpDetJumpEngine::addOnTerm(
119         Real phi, Time t, Size j) const {
120         const std::complex<Real> l =
121             BatesDoubleExpEngine::addOnTerm(phi, t, j);
122 
123         ext::shared_ptr<BatesDoubleExpDetJumpModel> doubleExpDetJumpModel
124             = ext::dynamic_pointer_cast<BatesDoubleExpDetJumpModel>(*model_);
125 
126         const Real lambda      = doubleExpDetJumpModel->lambda();
127         const Real kappaLambda = doubleExpDetJumpModel->kappaLambda();
128         const Real thetaLambda = doubleExpDetJumpModel->thetaLambda();
129 
130         return (kappaLambda*t - 1.0 + std::exp(-kappaLambda*t))
131             * thetaLambda*l/(kappaLambda*t*lambda)
132             + (1.0 - std::exp(-kappaLambda*t))*l/(kappaLambda*t);
133     }
134 
135 }
136