Coverage Report

Created: 2025-08-11 06:28

/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
}