1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2015 Johannes Göttker-Schnetmann
5 Copyright (C) 2015 Klaus Spanderen
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/*! \file hestonslvprocess.cpp
22 \brief Heston stochastic local volatility process
23*/
24
25#include <ql/processes/hestonslvprocess.hpp>
26#include <ql/math/distributions/normaldistribution.hpp>
27#include <ql/methods/finitedifferences/utilities/squarerootprocessrndcalculator.hpp>
28#include <utility>
29
30namespace QuantLib {
31
32 HestonSLVProcess::HestonSLVProcess(const ext::shared_ptr<HestonProcess>& hestonProcess,
33 ext::shared_ptr<LocalVolTermStructure> leverageFct,
34 const Real mixingFactor)
35 : mixingFactor_(mixingFactor), hestonProcess_(hestonProcess),
36 leverageFct_(std::move(leverageFct)) {
37 registerWith(h: hestonProcess);
38 setParameters();
39 };
40
41 void HestonSLVProcess::update() {
42 setParameters();
43 StochasticProcess::update();
44 }
45
46 Array HestonSLVProcess::drift(Time t, const Array& x) const {
47 Array tmp(2);
48
49 const Volatility vol =
50 std::max(a: 1e-8, b: std::sqrt(x: x[1])*leverageFct_->localVol(t, underlyingLevel: x[0], extrapolate: true));
51
52 tmp[0] = riskFreeRate()->forwardRate(t1: t, t2: t, comp: Continuous).rate()
53 - dividendYield()->forwardRate(t1: t, t2: t, comp: Continuous).rate()
54 - 0.5*vol*vol;
55
56 tmp[1] = kappa_*(theta_ - x[1]);
57
58 return tmp;
59 }
60
61 Matrix HestonSLVProcess::diffusion(Time t, const Array& x) const {
62
63 const Real vol =
64 std::max(a: 1e-8, b: std::sqrt(x: x[1])*leverageFct_->localVol(t, underlyingLevel: x[0], extrapolate: true));
65
66 const Real sigma2 = mixedSigma_ * std::sqrt(x: x[1]);
67 const Real sqrhov = std::sqrt(x: 1.0 - rho_*rho_);
68
69 Matrix tmp(2,2);
70 tmp[0][0] = vol; tmp[0][1] = 0.0;
71 tmp[1][0] = rho_*sigma2; tmp[1][1] = sqrhov*sigma2;
72
73 return tmp;
74 }
75
76 Array HestonSLVProcess::evolve(
77 Time t0, const Array& x0, Time dt, const Array& dw) const {
78 Array retVal(2);
79
80 const Real ex = std::exp(x: -kappa_*dt);
81
82 const Real m = theta_+(x0[1]-theta_)*ex;
83 const Real s2 = x0[1]*mixedSigma_*mixedSigma_*ex/kappa_*(1-ex)
84 + theta_*mixedSigma_*mixedSigma_/(2*kappa_)*(1-ex)*(1-ex);
85 const Real psi = s2/(m*m);
86
87 if (psi < 1.5) {
88 const Real b2 = 2/psi-1+std::sqrt(x: 2/psi*(2/psi-1));
89 const Real b = std::sqrt(x: b2);
90 const Real a = m/(1+b2);
91
92 retVal[1] = a*(b+dw[1])*(b+dw[1]);
93 }
94 else {
95 const Real p = (psi-1)/(psi+1);
96 const Real beta = (1-p)/m;
97 const Real u = CumulativeNormalDistribution()(dw[1]);
98
99 retVal[1] = ((u <= p) ? Real(0.0) : std::log(x: (1-p)/(1-u))/beta);
100 }
101
102 const Real mu = riskFreeRate()->forwardRate(t1: t0, t2: t0+dt, comp: Continuous).rate()
103 - dividendYield()->forwardRate(t1: t0, t2: t0+dt, comp: Continuous).rate();
104
105 const Real rho1 = std::sqrt(x: 1-rho_*rho_);
106
107 const Volatility l_0 = leverageFct_->localVol(t: t0, underlyingLevel: x0[0], extrapolate: true);
108 const Real v_0 = 0.5*(x0[1]+retVal[1])*l_0*l_0;
109
110 retVal[0] = x0[0]*std::exp(x: mu*dt - 0.5*v_0*dt
111 + rho_/mixedSigma_*l_0 * (
112 retVal[1] - kappa_*theta_*dt
113 + 0.5*(x0[1]+retVal[1])*kappa_*dt - x0[1])
114 + rho1*std::sqrt(x: v_0*dt)*dw[0]);
115
116 return retVal;
117 }
118
119 void HestonSLVProcess::setParameters() {
120 v0_ = hestonProcess_->v0();
121 kappa_ = hestonProcess_->kappa();
122 theta_ = hestonProcess_->theta();
123 sigma_ = hestonProcess_->sigma();
124 rho_ = hestonProcess_->rho();
125 mixedSigma_ = mixingFactor_ * sigma_;
126 }
127
128}
129

source code of quantlib/ql/processes/hestonslvprocess.cpp

Morty Proxy This is a proxified and sanitized view of the page, visit original site.