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