Coverage Report

Created: 2026-09-28 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/experimental/finitedifferences/fdklugeextouspreadengine.cpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2011 Klaus Spanderen
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
 <https://www.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
21
#include <ql/exercise.hpp>
22
#include <ql/experimental/finitedifferences/fdklugeextouspreadengine.hpp>
23
#include <ql/experimental/finitedifferences/fdmklugeextousolver.hpp>
24
#include <ql/experimental/finitedifferences/fdmspreadpayoffinnervalue.hpp>
25
#include <ql/experimental/processes/extendedornsteinuhlenbeckprocess.hpp>
26
#include <ql/experimental/processes/extouwithjumpsprocess.hpp>
27
#include <ql/experimental/processes/klugeextouprocess.hpp>
28
#include <ql/methods/finitedifferences/meshers/exponentialjump1dmesher.hpp>
29
#include <ql/methods/finitedifferences/meshers/fdmmeshercomposite.hpp>
30
#include <ql/methods/finitedifferences/meshers/fdmsimpleprocess1dmesher.hpp>
31
#include <ql/methods/finitedifferences/operators/fdmlinearoplayout.hpp>
32
#include <ql/methods/finitedifferences/stepconditions/fdmamericanstepcondition.hpp>
33
#include <ql/methods/finitedifferences/stepconditions/fdmbermudanstepcondition.hpp>
34
#include <ql/methods/finitedifferences/stepconditions/fdmstepconditioncomposite.hpp>
35
#include <ql/termstructures/yieldtermstructure.hpp>
36
#include <utility>
37
38
namespace QuantLib {
39
40
    FdKlugeExtOUSpreadEngine::FdKlugeExtOUSpreadEngine(
41
        ext::shared_ptr<KlugeExtOUProcess> klugeOUProcess,
42
        ext::shared_ptr<YieldTermStructure> rTS,
43
        Size tGrid,
44
        Size xGrid,
45
        Size yGrid,
46
        Size uGrid,
47
        ext::shared_ptr<GasShape> gasShape,
48
        ext::shared_ptr<PowerShape> powerShape,
49
        const FdmSchemeDesc& schemeDesc)
50
0
    : klugeOUProcess_(std::move(klugeOUProcess)), rTS_(std::move(rTS)), tGrid_(tGrid),
51
0
      xGrid_(xGrid), yGrid_(yGrid), uGrid_(uGrid), gasShape_(std::move(gasShape)),
52
0
      powerShape_(std::move(powerShape)), schemeDesc_(schemeDesc) {}
53
54
0
    void FdKlugeExtOUSpreadEngine::calculate() const {
55
        // 1. Mesher
56
0
        const Time maturity
57
0
            = rTS_->dayCounter().yearFraction(rTS_->referenceDate(),
58
0
                                              arguments_.exercise->lastDate());
59
0
        const ext::shared_ptr<ExtOUWithJumpsProcess> klugeProcess
60
0
                                          = klugeOUProcess_->getKlugeProcess();
61
0
        const ext::shared_ptr<StochasticProcess1D> ouProcess
62
0
                        = klugeProcess->getExtendedOrnsteinUhlenbeckProcess();
63
0
        const ext::shared_ptr<Fdm1dMesher> xMesher(
64
0
            new FdmSimpleProcess1dMesher(xGrid_, ouProcess,maturity));
65
66
0
        const ext::shared_ptr<Fdm1dMesher> yMesher(
67
0
            new ExponentialJump1dMesher(yGrid_,
68
0
                                        klugeProcess->beta(),
69
0
                                        klugeProcess->jumpIntensity(),
70
0
                                        klugeProcess->eta()));
71
72
0
        const ext::shared_ptr<Fdm1dMesher> uMesher(
73
0
            new FdmSimpleProcess1dMesher(uGrid_,
74
0
                                         klugeOUProcess_->getExtOUProcess(),
75
0
                                         maturity));
76
77
0
        const ext::shared_ptr<FdmMesher> mesher(
78
0
            new FdmMesherComposite(xMesher, yMesher, uMesher));
79
80
        // 2. Calculator
81
0
        ext::shared_ptr<BasketPayoff> basketPayoff =
82
0
            ext::dynamic_pointer_cast<BasketPayoff>(arguments_.payoff);
83
0
        QL_REQUIRE(basketPayoff," basket payoff expected");
84
85
0
        const ext::shared_ptr<Payoff> zeroStrikeCall(
86
0
            new PlainVanillaPayoff(Option::Call, 0.0));
87
88
0
        const ext::shared_ptr<FdmInnerValueCalculator> gasPrice(
89
0
            new FdmExpExtOUInnerValueCalculator(zeroStrikeCall,
90
0
                                                mesher, gasShape_, 2));
91
92
0
        const ext::shared_ptr<FdmInnerValueCalculator> powerPrice(
93
0
            new FdmExtOUJumpModelInnerValue(zeroStrikeCall,mesher,powerShape_));
94
95
0
        const ext::shared_ptr<FdmInnerValueCalculator> calculator(
96
0
            new FdmSpreadPayoffInnerValue(basketPayoff, powerPrice, gasPrice));
97
98
        // 3. Step conditions
99
0
        const ext::shared_ptr<FdmStepConditionComposite> conditions =
100
0
            FdmStepConditionComposite::vanillaComposite(
101
0
                                DividendSchedule(), arguments_.exercise,
102
0
                                mesher, calculator,
103
0
                                rTS_->referenceDate(), rTS_->dayCounter());
104
105
        // 4. Boundary conditions
106
0
        const FdmBoundaryConditionSet boundaries;
107
108
        // 5. set-up solver
109
0
        FdmSolverDesc solverDesc = { mesher, boundaries, conditions,
110
0
                                     calculator, maturity, tGrid_, 0 };
111
112
0
        const ext::shared_ptr<FdmKlugeExtOUSolver<3> > solver(
113
0
            new FdmKlugeExtOUSolver<3>(
114
0
                Handle<KlugeExtOUProcess>(klugeOUProcess_),
115
0
                rTS_, solverDesc, schemeDesc_));
116
117
0
        std::vector<Real> x(3);
118
0
        x[0] = klugeOUProcess_->initialValues()[0];
119
0
        x[1] = klugeOUProcess_->initialValues()[1];
120
0
        x[2] = klugeOUProcess_->initialValues()[2];
121
122
0
        results_.value = solver->valueAt(x);
123
0
    }
124
}