1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 /*
4  Copyright (C) 2008 Andreas Gaida
5  Copyright (C) 2008, 2009 Ralph Schreyer
6  Copyright (C) 2008, 2009, 2011, 2014, 2015 Klaus Spanderen
7  Copyright (C) 2015 Johannes Göttker-Schnetmann
8 
9  This file is part of QuantLib, a free-software/open-source library
10  for financial quantitative analysts and developers - http://quantlib.org/
11 
12  QuantLib is free software: you can redistribute it and/or modify it
13  under the terms of the QuantLib license.  You should have received a
14  copy of the license along with this program; if not, please email
15  <quantlib-dev@lists.sf.net>. The license is also available online at
16  <http://quantlib.org/license.shtml>.
17 
18  This program is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20  FOR A PARTICULAR PURPOSE.  See the license for more details.
21 */
22 
23 #include <ql/processes/hestonprocess.hpp>
24 #include <ql/methods/finitedifferences/operators/fdmhestonop.hpp>
25 #include <ql/methods/finitedifferences/solvers/fdm2dimsolver.hpp>
26 #include <ql/methods/finitedifferences/solvers/fdmhestonsolver.hpp>
27 
28 namespace QuantLib {
29 
FdmHestonSolver(const Handle<HestonProcess> & process,const FdmSolverDesc & solverDesc,const FdmSchemeDesc & schemeDesc,const Handle<FdmQuantoHelper> & quantoHelper,const ext::shared_ptr<LocalVolTermStructure> & leverageFct,const Real mixingFactor)30     FdmHestonSolver::FdmHestonSolver(
31         const Handle<HestonProcess>& process,
32         const FdmSolverDesc& solverDesc,
33         const FdmSchemeDesc& schemeDesc,
34         const Handle<FdmQuantoHelper>& quantoHelper,
35         const ext::shared_ptr<LocalVolTermStructure>& leverageFct,
36         const Real mixingFactor)
37     : process_(process),
38       solverDesc_(solverDesc),
39       schemeDesc_(schemeDesc),
40       quantoHelper_(quantoHelper),
41       leverageFct_(leverageFct),
42       mixingFactor_(mixingFactor) {
43 
44         registerWith(process_);
45         registerWith(quantoHelper_);
46     }
47 
performCalculations() const48     void FdmHestonSolver::performCalculations() const {
49         ext::shared_ptr<FdmLinearOpComposite> op(
50 			ext::make_shared<FdmHestonOp>(
51                 solverDesc_.mesher, process_.currentLink(),
52                 (!quantoHelper_.empty()) ? quantoHelper_.currentLink()
53                              : ext::shared_ptr<FdmQuantoHelper>(),
54                 leverageFct_, mixingFactor_));
55 
56         solver_ = ext::make_shared<Fdm2DimSolver>(solverDesc_, schemeDesc_, op);
57     }
58 
valueAt(Real s,Real v) const59     Real FdmHestonSolver::valueAt(Real s, Real v) const {
60         calculate();
61         return solver_->interpolateAt(std::log(s), v);
62     }
63 
deltaAt(Real s,Real v) const64     Real FdmHestonSolver::deltaAt(Real s, Real v) const {
65         calculate();
66         return solver_->derivativeX(std::log(s), v)/s;
67     }
68 
gammaAt(Real s,Real v) const69     Real FdmHestonSolver::gammaAt(Real s, Real v) const {
70         calculate();
71         const Real x = std::log(s);
72         return (solver_->derivativeXX(x, v)-solver_->derivativeX(x, v))/(s*s);
73     }
74 
meanVarianceDeltaAt(Real s,Real v) const75     Real FdmHestonSolver::meanVarianceDeltaAt(Real s, Real v) const {
76         calculate();
77 
78         const Real alpha = process_->rho()*process_->sigma()/s;
79         return deltaAt(s, v) + alpha*solver_->derivativeY(std::log(s), v);
80     }
81 
meanVarianceGammaAt(Real s,Real v) const82     Real FdmHestonSolver::meanVarianceGammaAt(Real s, Real v) const {
83         calculate();
84 
85         const Real x = std::log(s);
86         const Real alpha = process_->rho()*process_->sigma()/s;
87         return gammaAt(s, v)
88                 +  solver_->derivativeYY(x, v)*alpha*alpha
89                 +2*solver_->derivativeXY(x, v)*alpha/s;
90     }
91 
thetaAt(Real s,Real v) const92     Real FdmHestonSolver::thetaAt(Real s, Real v) const {
93         calculate();
94         return solver_->thetaAt(std::log(s), v);
95     }
96 }
97