Coverage Report

Created: 2025-08-05 06:45

/src/quantlib/ql/stochasticprocess.hpp
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) 2003 Ferdinando Ametrano
5
 Copyright (C) 2001, 2002, 2003 Sadruddin Rejeb
6
 Copyright (C) 2004, 2005 StatPro Italia srl
7
8
 This file is part of QuantLib, a free-software/open-source library
9
 for financial quantitative analysts and developers - http://quantlib.org/
10
11
 QuantLib is free software: you can redistribute it and/or modify it
12
 under the terms of the QuantLib license.  You should have received a
13
 copy of the license along with this program; if not, please email
14
 <quantlib-dev@lists.sf.net>. The license is also available online at
15
 <http://quantlib.org/license.shtml>.
16
17
 This program is distributed in the hope that it will be useful, but WITHOUT
18
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 FOR A PARTICULAR PURPOSE.  See the license for more details.
20
*/
21
22
/*! \file stochasticprocess.hpp
23
    \brief stochastic processes
24
*/
25
26
#ifndef quantlib_stochastic_process_hpp
27
#define quantlib_stochastic_process_hpp
28
29
#include <ql/time/date.hpp>
30
#include <ql/patterns/observable.hpp>
31
#include <ql/math/matrix.hpp>
32
33
namespace QuantLib {
34
35
    //! multi-dimensional stochastic process class.
36
    /*! This class describes a stochastic process governed by
37
        \f[
38
        d\mathrm{x}_t = \mu(t, x_t)\mathrm{d}t
39
                      + \sigma(t, \mathrm{x}_t) \cdot d\mathrm{W}_t.
40
        \f]
41
    */
42
    class StochasticProcess : public Observer, public Observable {
43
      public:
44
        //! discretization of a stochastic process over a given time interval
45
        class discretization {
46
          public:
47
1.00k
            virtual ~discretization() = default;
48
            virtual Array drift(const StochasticProcess&,
49
                                Time t0,
50
                                const Array& x0,
51
                                Time dt) const = 0;
52
            virtual Matrix diffusion(const StochasticProcess&,
53
                                     Time t0,
54
                                     const Array& x0,
55
                                     Time dt) const = 0;
56
            virtual Matrix covariance(const StochasticProcess&,
57
                                      Time t0,
58
                                      const Array& x0,
59
                                      Time dt) const = 0;
60
        };
61
1.00k
        ~StochasticProcess() override = default;
62
        //! \name Stochastic process interface
63
        //@{
64
        //! returns the number of dimensions of the stochastic process
65
        virtual Size size() const = 0;
66
        //! returns the number of independent factors of the process
67
        virtual Size factors() const;
68
        //! returns the initial values of the state variables
69
        virtual Array initialValues() const = 0;
70
        /*! \brief returns the drift part of the equation, i.e.,
71
                   \f$ \mu(t, \mathrm{x}_t) \f$
72
        */
73
        virtual Array drift(Time t,
74
                            const Array& x) const = 0;
75
        /*! \brief returns the diffusion part of the equation, i.e.
76
                   \f$ \sigma(t, \mathrm{x}_t) \f$
77
        */
78
        virtual Matrix diffusion(Time t,
79
                                 const Array& x) const = 0;
80
        /*! returns the expectation
81
            \f$ E(\mathrm{x}_{t_0 + \Delta t}
82
                | \mathrm{x}_{t_0} = \mathrm{x}_0) \f$
83
            of the process after a time interval \f$ \Delta t \f$
84
            according to the given discretization. This method can be
85
            overridden in derived classes which want to hard-code a
86
            particular discretization.
87
        */
88
        virtual Array expectation(Time t0,
89
                                  const Array& x0,
90
                                  Time dt) const;
91
        /*! returns the standard deviation
92
            \f$ S(\mathrm{x}_{t_0 + \Delta t}
93
                | \mathrm{x}_{t_0} = \mathrm{x}_0) \f$
94
            of the process after a time interval \f$ \Delta t \f$
95
            according to the given discretization. This method can be
96
            overridden in derived classes which want to hard-code a
97
            particular discretization.
98
        */
99
        virtual Matrix stdDeviation(Time t0,
100
                                    const Array& x0,
101
                                    Time dt) const;
102
        /*! returns the covariance
103
            \f$ V(\mathrm{x}_{t_0 + \Delta t}
104
                | \mathrm{x}_{t_0} = \mathrm{x}_0) \f$
105
            of the process after a time interval \f$ \Delta t \f$
106
            according to the given discretization. This method can be
107
            overridden in derived classes which want to hard-code a
108
            particular discretization.
109
        */
110
        virtual Matrix covariance(Time t0,
111
                                  const Array& x0,
112
                                  Time dt) const;
113
        /*! returns the asset value after a time interval \f$ \Delta t
114
            \f$ according to the given discretization. By default, it
115
            returns
116
            \f[
117
            E(\mathrm{x}_0,t_0,\Delta t) +
118
            S(\mathrm{x}_0,t_0,\Delta t) \cdot \Delta \mathrm{w}
119
            \f]
120
            where \f$ E \f$ is the expectation and \f$ S \f$ the
121
            standard deviation.
122
        */
123
        virtual Array evolve(Time t0,
124
                             const Array& x0,
125
                             Time dt,
126
                             const Array& dw) const;
127
        /*! applies a change to the asset value. By default, it
128
            returns \f$ \mathrm{x} + \Delta \mathrm{x} \f$.
129
        */
130
        virtual Array apply(const Array& x0,
131
                            const Array& dx) const;
132
        //@}
133
134
        //! \name utilities
135
        //@{
136
        /*! returns the time value corresponding to the given date
137
            in the reference system of the stochastic process.
138
139
            \note As a number of processes might not need this
140
                  functionality, a default implementation is given
141
                  which raises an exception.
142
        */
143
        virtual Time time(const Date&) const;
144
        //@}
145
146
        //! \name Observer interface
147
        //@{
148
        void update() override;
149
        //@}
150
      protected:
151
1.00k
        StochasticProcess() = default;
152
        explicit StochasticProcess(ext::shared_ptr<discretization>);
153
        ext::shared_ptr<discretization> discretization_;
154
    };
155
156
157
    //! 1-dimensional stochastic process
158
    /*! This class describes a stochastic process governed by
159
        \f[
160
            dx_t = \mu(t, x_t)dt + \sigma(t, x_t)dW_t.
161
        \f]
162
    */
163
    class StochasticProcess1D : public StochasticProcess {
164
      public:
165
        //! discretization of a 1-D stochastic process
166
        class discretization {
167
          public:
168
1.00k
            virtual ~discretization() = default;
169
            virtual Real drift(const StochasticProcess1D&,
170
                               Time t0, Real x0, Time dt) const = 0;
171
            virtual Real diffusion(const StochasticProcess1D&,
172
                                   Time t0, Real x0, Time dt) const = 0;
173
            virtual Real variance(const StochasticProcess1D&,
174
                                  Time t0, Real x0, Time dt) const = 0;
175
        };
176
        //! \name 1-D stochastic process interface
177
        //@{
178
        //! returns the initial value of the state variable
179
        virtual Real x0() const = 0;
180
        //! returns the drift part of the equation, i.e. \f$ \mu(t, x_t) \f$
181
        virtual Real drift(Time t, Real x) const = 0;
182
        /*! \brief returns the diffusion part of the equation, i.e.
183
            \f$ \sigma(t, x_t) \f$
184
        */
185
        virtual Real diffusion(Time t, Real x) const = 0;
186
        /*! returns the expectation
187
            \f$ E(x_{t_0 + \Delta t} | x_{t_0} = x_0) \f$
188
            of the process after a time interval \f$ \Delta t \f$
189
            according to the given discretization. This method can be
190
            overridden in derived classes which want to hard-code a
191
            particular discretization.
192
        */
193
        virtual Real expectation(Time t0, Real x0, Time dt) const;
194
        /*! returns the standard deviation
195
            \f$ S(x_{t_0 + \Delta t} | x_{t_0} = x_0) \f$
196
            of the process after a time interval \f$ \Delta t \f$
197
            according to the given discretization. This method can be
198
            overridden in derived classes which want to hard-code a
199
            particular discretization.
200
        */
201
        virtual Real stdDeviation(Time t0, Real x0, Time dt) const;
202
        /*! returns the variance
203
            \f$ V(x_{t_0 + \Delta t} | x_{t_0} = x_0) \f$
204
            of the process after a time interval \f$ \Delta t \f$
205
            according to the given discretization. This method can be
206
            overridden in derived classes which want to hard-code a
207
            particular discretization.
208
        */
209
        virtual Real variance(Time t0, Real x0, Time dt) const;
210
        /*! returns the asset value after a time interval \f$ \Delta t
211
            \f$ according to the given discretization. By default, it
212
            returns
213
            \f[
214
            E(x_0,t_0,\Delta t) + S(x_0,t_0,\Delta t) \cdot \Delta w
215
            \f]
216
            where \f$ E \f$ is the expectation and \f$ S \f$ the
217
            standard deviation.
218
        */
219
        virtual Real evolve(Time t0, Real x0, Time dt, Real dw) const;
220
        /*! applies a change to the asset value. By default, it
221
            returns \f$ x + \Delta x \f$.
222
        */
223
        virtual Real apply(Real x0, Real dx) const;
224
        //@}
225
      protected:
226
0
        StochasticProcess1D() = default;
227
        explicit StochasticProcess1D(ext::shared_ptr<discretization>);
228
        ext::shared_ptr<discretization> discretization_;
229
      private:
230
        // StochasticProcess interface implementation
231
        Size size() const override;
232
        Array initialValues() const override;
233
        Array drift(Time t, const Array& x) const override;
234
        Matrix diffusion(Time t, const Array& x) const override;
235
        Array expectation(Time t0, const Array& x0, Time dt) const override;
236
        Matrix stdDeviation(Time t0, const Array& x0, Time dt) const override;
237
        Matrix covariance(Time t0, const Array& x0, Time dt) const override;
238
        Array evolve(Time t0, const Array& x0, Time dt, const Array& dw) const override;
239
        Array apply(const Array& x0, const Array& dx) const override;
240
    };
241
242
243
    // inline definitions
244
245
0
    inline Size StochasticProcess1D::size() const {
246
0
        return 1;
247
0
    }
248
249
0
    inline Array StochasticProcess1D::initialValues() const {
250
0
        Array a(1, x0());
251
0
        return a;
252
0
    }
253
254
0
    inline Array StochasticProcess1D::drift(Time t, const Array& x) const {
255
0
        #if defined(QL_EXTRA_SAFETY_CHECKS)
256
0
        QL_REQUIRE(x.size() == 1, "1-D array required");
257
0
        #endif
258
0
        Array a(1, drift(t, x[0]));
259
0
        return a;
260
0
    }
261
262
0
    inline Matrix StochasticProcess1D::diffusion(Time t, const Array& x) const {
263
0
        #if defined(QL_EXTRA_SAFETY_CHECKS)
264
0
        QL_REQUIRE(x.size() == 1, "1-D array required");
265
0
        #endif
266
0
        Matrix m(1, 1, diffusion(t, x[0]));
267
0
        return m;
268
0
    }
269
270
    inline Array StochasticProcess1D::expectation(
271
0
                                    Time t0, const Array& x0, Time dt) const {
272
0
        #if defined(QL_EXTRA_SAFETY_CHECKS)
273
0
        QL_REQUIRE(x0.size() == 1, "1-D array required");
274
0
        #endif
275
0
        Array a(1, expectation(t0, x0[0], dt));
276
0
        return a;
277
0
    }
278
279
    inline Matrix StochasticProcess1D::stdDeviation(
280
0
                                    Time t0, const Array& x0, Time dt) const {
281
0
        #if defined(QL_EXTRA_SAFETY_CHECKS)
282
0
        QL_REQUIRE(x0.size() == 1, "1-D array required");
283
0
        #endif
284
0
        Matrix m(1, 1, stdDeviation(t0, x0[0], dt));
285
0
        return m;
286
0
    }
287
288
    inline Matrix StochasticProcess1D::covariance(
289
0
                                    Time t0, const Array& x0, Time dt) const {
290
0
        #if defined(QL_EXTRA_SAFETY_CHECKS)
291
0
        QL_REQUIRE(x0.size() == 1, "1-D array required");
292
0
        #endif
293
0
        Matrix m(1, 1, variance(t0, x0[0], dt));
294
0
        return m;
295
0
    }
296
297
    inline Array StochasticProcess1D::evolve(Time t0, const Array& x0,
298
0
                                             Time dt, const Array& dw) const {
299
0
        #if defined(QL_EXTRA_SAFETY_CHECKS)
300
0
        QL_REQUIRE(x0.size() == 1, "1-D array required");
301
0
        QL_REQUIRE(dw.size() == 1, "1-D array required");
302
0
        #endif
303
0
        Array a(1, evolve(t0,x0[0],dt,dw[0]));
304
0
        return a;
305
0
    }
306
307
    inline Array StochasticProcess1D::apply(const Array& x0,
308
0
                                            const Array& dx) const {
309
0
        #if defined(QL_EXTRA_SAFETY_CHECKS)
310
0
        QL_REQUIRE(x0.size() == 1, "1-D array required");
311
0
        QL_REQUIRE(dx.size() == 1, "1-D array required");
312
0
        #endif
313
0
        Array a(1, apply(x0[0],dx[0]));
314
0
        return a;
315
0
    }
316
317
}
318
319
320
#endif