1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2020 Lew Wei Hao
5 Copyright (C) 2021 Magnus Mencke
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 coxingersollrossprocess.hpp
22 \brief CoxIngersollRoss process
23*/
24
25#ifndef quantlib_coxingersollross_process_hpp
26#define quantlib_coxingersollross_process_hpp
27
28#include <ql/stochasticprocess.hpp>
29#include <ql/math/distributions/normaldistribution.hpp>
30
31namespace QuantLib {
32
33 //! CoxIngersollRoss process class
34 /*! This class describes the CoxIngersollRoss process governed by
35 \f[
36 dx(t) = k (\theta - x(t)) dt + \sigma \sqrt{x(t)} dW(t).
37 \f]
38
39 The process is discretized using the Quadratic Exponential scheme.
40 For details see Leif Andersen,
41 Efficient Simulation of the Heston Stochastic Volatility Model.
42
43 \ingroup processes
44 */
45 class CoxIngersollRossProcess : public StochasticProcess1D {
46 public:
47
48 CoxIngersollRossProcess(Real speed,
49 Volatility vol,
50 Real x0 = 0.0,
51 Real level = 0.0);
52 //@{
53 Real drift(Time t, Real x) const override;
54 Real diffusion(Time t, Real x) const override;
55 Real expectation(Time t0, Real x0, Time dt) const override;
56 Real stdDeviation(Time t0, Real x0, Time dt) const override;
57 //@}
58 Real x0() const override;
59 Real speed() const;
60 Real volatility() const;
61 Real level() const;
62 Real variance(Time t0, Real x0, Time dt) const override;
63 Real evolve (Time t0,
64 Real x0,
65 Time dt,
66 Real dw) const override;
67 private:
68 Real x0_, speed_, level_;
69 Volatility volatility_;
70 };
71
72 // inline
73
74 inline Real CoxIngersollRossProcess::x0() const {
75 return x0_;
76 }
77
78 inline Real CoxIngersollRossProcess::speed() const {
79 return speed_;
80 }
81
82 inline Real CoxIngersollRossProcess::volatility() const {
83 return volatility_;
84 }
85
86 inline Real CoxIngersollRossProcess::level() const {
87 return level_;
88 }
89
90 inline Real CoxIngersollRossProcess::drift(Time, Real x) const {
91 return speed_ * (level_ - x);
92 }
93
94 inline Real CoxIngersollRossProcess::diffusion(Time, Real) const {
95 return volatility_;
96 }
97
98 inline Real CoxIngersollRossProcess::expectation(Time, Real x0,
99 Time dt) const {
100 return level_ + (x0 - level_) * std::exp(x: -speed_*dt);
101 }
102
103 inline Real CoxIngersollRossProcess::stdDeviation(Time t, Real x0,
104 Time dt) const {
105 return std::sqrt(x: variance(t0: t,x0,dt));
106 }
107
108 inline Real CoxIngersollRossProcess::evolve (Time t0,
109 Real x0,
110 Time dt,
111 Real dw) const {
112 Real result;
113
114 const Real ex = std::exp(x: -speed_*dt);
115
116 const Real m = level_+(x0-level_)*ex;
117 const Real s2 = x0*volatility_*volatility_*ex/speed_*(1-ex)
118 + level_*volatility_*volatility_/(2*speed_)*(1-ex)*(1-ex);
119 const Real psi = s2/(m*m);
120
121 if (psi <= 1.5) {
122 const Real b2 = 2/psi-1+std::sqrt(x: 2/psi*(2/psi-1));
123 const Real b = std::sqrt(x: b2);
124 const Real a = m/(1+b2);
125
126 result = a*(b+dw)*(b+dw);
127 }
128 else {
129 const Real p = (psi-1)/(psi+1);
130 const Real beta = (1-p)/m;
131
132 const Real u = CumulativeNormalDistribution()(dw);
133
134 result = ((u <= p) ? 0.0 : Real(std::log(x: (1-p)/(1-u))/beta));
135 }
136
137 return result;
138 }
139
140}
141
142#endif
143

source code of quantlib/ql/processes/coxingersollrossprocess.hpp