1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2013 Peter Caspers
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
20#include <ql/processes/mfstateprocess.hpp>
21
22namespace QuantLib {
23
24 MfStateProcess::MfStateProcess(Real reversion, const Array& times, const Array& vols)
25 : reversion_(reversion), times_(times), vols_(vols) {
26 if (reversion_ < QL_EPSILON && -reversion_ < QL_EPSILON)
27 reversionZero_ = true;
28 QL_REQUIRE(times.size() == vols.size() - 1,
29 "number of volatilities ("
30 << vols.size() << ") compared to number of times ("
31 << times_.size() << " must be bigger by one");
32 for (int i = 0; i < ((int)times.size()) - 1; i++)
33 QL_REQUIRE(times[i] < times[i + 1], "times must be increasing ("
34 << times[i] << "@" << i
35 << " , " << times[i + 1]
36 << "@" << i + 1 << ")");
37 for (Size i = 0; i < vols.size(); i++)
38 QL_REQUIRE(vols[i] >= 0.0, "volatilities must be non negative ("
39 << vols[i] << "@" << i << ")");
40 }
41
42 Real MfStateProcess::x0() const { return 0.0; }
43
44 Real MfStateProcess::drift(Time, Real) const { return 0.0; }
45
46 Real MfStateProcess::diffusion(Time t, Real) const {
47 Size i =
48 std::upper_bound(first: times_.begin(), last: times_.end(), val: t) - times_.begin();
49 return vols_[i];
50 }
51
52 Real MfStateProcess::expectation(Time, Real x0, Time dt) const {
53 return x0;
54 }
55
56 Real MfStateProcess::stdDeviation(Time t, Real x0, Time dt) const {
57 return std::sqrt(x: variance(t0: t, x0, dt));
58 }
59
60 Real MfStateProcess::variance(Time t, Real, Time dt) const {
61
62 if (dt < QL_EPSILON)
63 return 0.0;
64 if (times_.empty())
65 return reversionZero_ ? dt
66 : 1.0 / (2.0 * reversion_) *
67 (std::exp(x: 2.0 * reversion_ * (t + dt)) -
68 std::exp(x: 2.0 * reversion_ * t));
69
70 Size i =
71 std::upper_bound(first: times_.begin(), last: times_.end(), val: t) - times_.begin();
72 Size j = std::upper_bound(first: times_.begin(), last: times_.end(), val: t + dt) -
73 times_.begin();
74
75 Real v = 0.0;
76
77 for (Size k = i; k < j; k++) {
78 if (reversionZero_)
79 v += vols_[k] * vols_[k] *
80 (times_[k] - std::max(a: k > 0 ? times_[k - 1] : 0.0, b: t));
81 else
82 v += 1.0 / (2.0 * reversion_) * vols_[k] * vols_[k] *
83 (std::exp(x: 2.0 * reversion_ * times_[k]) -
84 std::exp(x: 2.0 * reversion_ *
85 std::max(a: k > 0 ? times_[k - 1] : 0.0, b: t)));
86 }
87
88 if (reversionZero_)
89 v += vols_[j] * vols_[j] *
90 (t + dt - std::max(a: j > 0 ? times_[j - 1] : 0.0, b: t));
91 else
92 v += 1.0 / (2.0 * reversion_) * vols_[j] * vols_[j] *
93 (std::exp(x: 2.0 * reversion_ * (t + dt)) -
94 std::exp(x: 2.0 * reversion_ *
95 (std::max(a: j > 0 ? times_[j - 1] : 0.0, b: t))));
96
97 return v;
98 }
99}
100

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

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