Coverage Report

Created: 2025-08-11 06:28

/src/quantlib/ql/experimental/processes/extendedblackscholesprocess.cpp
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) 2008 Frank Hövermann
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/experimental/processes/extendedblackscholesprocess.hpp>
21
22
namespace QuantLib {
23
24
    ExtendedBlackScholesMertonProcess::ExtendedBlackScholesMertonProcess(
25
                              const Handle<Quote>& x0,
26
                              const Handle<YieldTermStructure>& dividendTS,
27
                              const Handle<YieldTermStructure>& riskFreeTS,
28
                              const Handle<BlackVolTermStructure>& blackVolTS,
29
                              const ext::shared_ptr<discretization>& d,
30
                              Discretization evolDisc)
31
0
    : GeneralizedBlackScholesProcess(x0,dividendTS,riskFreeTS,blackVolTS,d),
32
0
      discretization_(evolDisc) {}
33
34
0
    Real ExtendedBlackScholesMertonProcess::drift(Time t, Real x) const {
35
0
        Real sigma = diffusion(t,x);
36
        // we could be more anticipatory if we know the right dt
37
        // for which the drift will be used
38
0
        Time t1 = t + 0.0001;
39
0
        return riskFreeRate()->forwardRate(t,t1,Continuous,NoFrequency,true).rate()
40
0
             - dividendYield()->forwardRate(t,t1,Continuous,NoFrequency,true).rate()
41
0
             - 0.5 * sigma * sigma;
42
0
    }
43
44
0
    Real ExtendedBlackScholesMertonProcess::diffusion(Time t, Real x) const {
45
0
        return blackVolatility()->blackVol(t, x, true);
46
0
    }
47
48
    Real ExtendedBlackScholesMertonProcess::evolve(Time t0, Real x0,
49
0
                                                   Time dt, Real dw) const {
50
0
        Real predictor, sigma0, sigma1;
51
0
        Time t1;
52
0
        Rate rate0, rate1;
53
0
        Real driftterm, diffusionterm, corrector;
54
0
        switch (discretization_) {
55
0
          case Milstein:
56
            // Milstein scheme
57
0
            return apply(x0, drift(t0, x0)*dt
58
0
                           + 0.5*std::pow(diffusion(t0, x0),2)*(dw*dw-1)*dt
59
0
                           + diffusion(t0,x0)*std::sqrt(dt)*dw);
60
0
          case Euler:
61
            // Usual Euler scheme
62
0
            return apply(expectation(t0,x0,dt), stdDeviation(t0,x0,dt)*dw);
63
0
          case PredictorCorrector:
64
            // Predictor-Corrector scheme with equal weighting
65
0
            predictor =
66
0
                apply(expectation(t0,x0,dt), stdDeviation(t0,x0,dt)*dw);
67
0
            t1 = t0 + 0.0001;
68
0
            sigma0 = diffusion(t0,x0);
69
0
            sigma1 = diffusion(t0+dt,predictor);
70
0
            rate0 =
71
0
                riskFreeRate()->forwardRate(t0,t1,Continuous,NoFrequency,true).rate()
72
0
              - dividendYield()->forwardRate(t0,t1,Continuous,NoFrequency,true).rate()
73
0
              - 0.5*std::pow(sigma0,2);
74
0
            rate1 =
75
0
                riskFreeRate()->forwardRate(t0+dt,t1+dt,Continuous,
76
0
                                            NoFrequency,true).rate()
77
0
              - dividendYield()->forwardRate(t0+dt,t1+dt,
78
0
                                             Continuous,NoFrequency,true).rate()
79
0
              - 0.5*std::pow(sigma1,2);
80
0
            driftterm = 0.5*rate1+0.5*rate0;
81
0
            diffusionterm = 0.5*(sigma1+sigma0);
82
0
            corrector =
83
0
                apply(x0,driftterm*dt+diffusionterm*std::sqrt(dt)*dw);
84
0
            return corrector;
85
0
          default:
86
0
            QL_FAIL("unknown discretization scheme");
87
0
        }
88
0
    }
89
90
}