Skip to content

Commit c781a0b

Browse files
pcaspersjenkins
authored andcommitted
Merge remote-tracking branch 'origin/master' into QPR-11618
1 parent 053fbf6 commit c781a0b

6 files changed

Lines changed: 257 additions & 0 deletions

File tree

QuantExt/qle/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ methods/fdmblackscholesmesher.cpp
167167
methods/fdmblackscholesop.cpp
168168
methods/fdmdefaultableequityjumpdiffusionfokkerplanckop.cpp
169169
methods/fdmdefaultableequityjumpdiffusionop.cpp
170+
methods/fdmlgmop.cpp
170171
methods/fdmquantohelper.cpp
171172
methods/multipathgeneratorbase.cpp
172173
methods/multipathvariategenerator.cpp
@@ -209,6 +210,7 @@ models/jyimpliedzeroinflationtermstructure.cpp
209210
models/lgm.cpp
210211
models/lgmcalibrationinfo.cpp
211212
models/lgmconvolutionsolver2.cpp
213+
models/lgmfdsolver.cpp
212214
models/lgmimplieddefaulttermstructure.cpp
213215
models/lgmimpliedyieldtermstructure.cpp
214216
models/lgmvectorised.cpp
@@ -642,6 +644,7 @@ methods/fdmblackscholesmesher.hpp
642644
methods/fdmblackscholesop.hpp
643645
methods/fdmdefaultableequityjumpdiffusionfokkerplanckop.hpp
644646
methods/fdmdefaultableequityjumpdiffusionop.hpp
647+
methods/fdmlgmop.hpp
645648
methods/fdmquantohelper.hpp
646649
methods/multipathgeneratorbase.hpp
647650
methods/multipathvariategenerator.hpp
@@ -712,6 +715,7 @@ models/jyimpliedzeroinflationtermstructure.hpp
712715
models/lgm.hpp
713716
models/lgmcalibrationinfo.hpp
714717
models/lgmconvolutionsolver2.hpp
718+
models/lgmfdsolver.hpp
715719
models/lgmimplieddefaulttermstructure.hpp
716720
models/lgmimpliedyieldtermstructure.hpp
717721
models/lgmvectorised.hpp

QuantExt/qle/methods/fdmlgmop.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
Copyright (C) 2024 Quaternion Risk Management Ltd
3+
All rights reserved.
4+
5+
This file is part of ORE, a free-software/open-source library
6+
for transparent pricing and risk analysis - http://opensourcerisk.org
7+
8+
ORE is free software: you can redistribute it and/or modify it
9+
under the terms of the Modified BSD License. You should have received a
10+
copy of the license along with this program.
11+
The license is also available online at <http://opensourcerisk.org>
12+
13+
This program is distributed on the basis that it will form a useful
14+
contribution to risk analytics and model standardisation, but WITHOUT
15+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16+
FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17+
*/
18+
19+
#include <qle/methods/fdmlgmop.hpp>
20+
21+
#include <ql/methods/finitedifferences/meshers/fdmmesher.hpp>
22+
#include <ql/methods/finitedifferences/operators/fdmlinearoplayout.hpp>
23+
#include <ql/methods/finitedifferences/operators/secondderivativeop.hpp>
24+
25+
namespace QuantExt {
26+
27+
FdmLgmOp::FdmLgmOp(const ext::shared_ptr<FdmMesher>& mesher, const ext::shared_ptr<StochasticProcess1D>& process)
28+
: mesher_(mesher), process_(process), dxMap_(FirstDerivativeOp(0, mesher)), dxxMap_(SecondDerivativeOp(0, mesher)),
29+
mapT_(0, mesher) {}
30+
31+
void FdmLgmOp::setTime(Time t1, Time t2) {
32+
Real v = process_->variance(t1, 0.0, t2 - t1) / (t2 - t1);
33+
mapT_.axpyb(Array(), dxMap_, dxxMap_.mult(0.5 * Array(mesher_->layout()->size(), v)), Array(1, 0));
34+
}
35+
36+
Size FdmLgmOp::size() const { return 1u; }
37+
38+
Array FdmLgmOp::apply(const Array& u) const { return mapT_.apply(u); }
39+
40+
Array FdmLgmOp::apply_direction(Size direction, const Array& r) const {
41+
if (direction == 0)
42+
return mapT_.apply(r);
43+
else {
44+
Array retVal(r.size(), 0.0);
45+
return retVal;
46+
}
47+
}
48+
49+
Array FdmLgmOp::apply_mixed(const Array& r) const {
50+
Array retVal(r.size(), 0.0);
51+
return retVal;
52+
}
53+
54+
Array FdmLgmOp::solve_splitting(Size direction, const Array& r, Real dt) const {
55+
if (direction == 0)
56+
return mapT_.solve_splitting(r, dt, 1.0);
57+
else {
58+
Array retVal(r);
59+
return retVal;
60+
}
61+
}
62+
63+
Array FdmLgmOp::preconditioner(const Array& r, Real dt) const { return solve_splitting(0, r, dt); }
64+
65+
#if !defined(QL_NO_UBLAS_SUPPORT)
66+
std::vector<QuantLib::SparseMatrix> FdmLgmOp::toMatrixDecomp() const {
67+
std::vector<QuantLib::SparseMatrix> retVal(1, mapT_.toMatrix());
68+
return retVal;
69+
}
70+
#endif
71+
} // namespace QuantExt

QuantExt/qle/methods/fdmlgmop.hpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
Copyright (C) 2024 Quaternion Risk Management Ltd
3+
All rights reserved.
4+
5+
This file is part of ORE, a free-software/open-source library
6+
for transparent pricing and risk analysis - http://opensourcerisk.org
7+
8+
ORE is free software: you can redistribute it and/or modify it
9+
under the terms of the Modified BSD License. You should have received a
10+
copy of the license along with this program.
11+
The license is also available online at <http://opensourcerisk.org>
12+
13+
This program is distributed on the basis that it will form a useful
14+
contribution to risk analytics and model standardisation, but WITHOUT
15+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16+
FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17+
*/
18+
19+
/*! \file fdmlgmop.hpp
20+
\brief finite difference operator LGM model
21+
22+
*/
23+
24+
#pragma once
25+
26+
#include <ql/methods/finitedifferences/operators/fdmlinearopcomposite.hpp>
27+
#include <ql/methods/finitedifferences/operators/firstderivativeop.hpp>
28+
#include <ql/methods/finitedifferences/operators/triplebandlinearop.hpp>
29+
#include <ql/stochasticprocess.hpp>
30+
31+
namespace QuantExt {
32+
using namespace QuantLib;
33+
34+
class FdmLgmOp : public FdmLinearOpComposite {
35+
public:
36+
FdmLgmOp(const ext::shared_ptr<FdmMesher>& mesher, const ext::shared_ptr<StochasticProcess1D>& process);
37+
38+
Size size() const override;
39+
void setTime(Time t1, Time t2) override;
40+
41+
Array apply(const Array& r) const override;
42+
Array apply_mixed(const Array& r) const override;
43+
Array apply_direction(Size direction, const Array& r) const override;
44+
Array solve_splitting(Size direction, const Array& r, Real s) const override;
45+
Array preconditioner(const Array& r, Real s) const override;
46+
47+
#if !defined(QL_NO_UBLAS_SUPPORT)
48+
std::vector<QuantLib::SparseMatrix> toMatrixDecomp() const override;
49+
#endif
50+
private:
51+
ext::shared_ptr<FdmMesher> mesher_;
52+
ext::shared_ptr<StochasticProcess1D> process_;
53+
FirstDerivativeOp dxMap_;
54+
TripleBandLinearOp dxxMap_;
55+
TripleBandLinearOp mapT_;
56+
};
57+
} // namespace QuantExt
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
Copyright (C) 2024 Quaternion Risk Management Ltd
3+
All rights reserved.
4+
5+
This file is part of ORE, a free-software/open-source library
6+
for transparent pricing and risk analysis - http://opensourcerisk.org
7+
8+
ORE is free software: you can redistribute it and/or modify it
9+
under the terms of the Modified BSD License. You should have received a
10+
copy of the license along with this program.
11+
The license is also available online at <http://opensourcerisk.org>
12+
13+
This program is distributed on the basis that it will form a useful
14+
contribution to risk analytics and model standardisation, but WITHOUT
15+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16+
FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17+
*/
18+
19+
#include <qle/models/lgmfdsolver.hpp>
20+
#include <qle/methods/fdmlgmop.hpp>
21+
22+
#include <ql/methods/finitedifferences/meshers/fdmmeshercomposite.hpp>
23+
#include <ql/methods/finitedifferences/meshers/fdmsimpleprocess1dmesher.hpp>
24+
25+
26+
namespace QuantExt {
27+
28+
LgmFdSolver::LgmFdSolver(const boost::shared_ptr<LinearGaussMarkovModel>& model, const Real maxTime,
29+
const Size stateGridPoints, const Size timeStepsPerYear, const Real mesherEpsilon)
30+
: model_(model), maxTime_(maxTime), stateGridPoints_(stateGridPoints), timeStepsPerYear_(timeStepsPerYear),
31+
mesherEpsilon_(mesherEpsilon) {
32+
mesher_ = boost::make_shared<FdmMesherComposite>(boost::make_shared<FdmSimpleProcess1dMesher>(
33+
stateGridPoints, boost::dynamic_pointer_cast<StochasticProcess1D>(model->stateProcess()), maxTime_,
34+
timeStepsPerYear_, mesherEpsilon_));
35+
mesherLocations_ = RandomVariable(mesher_->locations(0));
36+
operator_ = boost::make_shared<QuantExt::FdmLgmOp>(
37+
mesher_, boost::dynamic_pointer_cast<StochasticProcess1D>(model->stateProcess()));
38+
solver_ = boost::make_shared<FdmBackwardSolver>(
39+
operator_, std::vector<boost::shared_ptr<BoundaryCondition<FdmLinearOp>>>(), nullptr, FdmSchemeDesc::Douglas());
40+
}
41+
42+
Size LgmFdSolver::gridSize() const { return stateGridPoints_; }
43+
44+
RandomVariable LgmFdSolver::stateGrid() const { return mesherLocations_; }
45+
46+
const boost::shared_ptr<LinearGaussMarkovModel>& LgmFdSolver::model() const { return model_; }
47+
48+
RandomVariable LgmFdSolver::rollback(const RandomVariable& v, const Real t1, const Real t0) const {
49+
Size steps = std::max<Size>(1, static_cast<Size>(static_cast<double>(timeStepsPerYear_) * (t1 - t0) + 0.5));
50+
Array workingArray(v.size());
51+
v.copyToArray(workingArray);
52+
solver_->rollback(workingArray, t1, t0, steps, 0);
53+
return RandomVariable(workingArray);
54+
}
55+
56+
} // namespace QuantExt
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
Copyright (C) 2024 Quaternion Risk Management Ltd
3+
All rights reserved.
4+
5+
This file is part of ORE, a free-software/open-source library
6+
for transparent pricing and risk analysis - http://opensourcerisk.org
7+
8+
ORE is free software: you can redistribute it and/or modify it
9+
under the terms of the Modified BSD License. You should have received a
10+
copy of the license along with this program.
11+
The license is also available online at <http://opensourcerisk.org>
12+
13+
This program is distributed on the basis that it will form a useful
14+
contribution to risk analytics and model standardisation, but WITHOUT
15+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16+
FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17+
*/
18+
19+
/*! \file lgmfdsolverx.hpp
20+
\brief numeric fd solver for LGM model
21+
22+
\ingroup models
23+
*/
24+
25+
#pragma once
26+
27+
#include <qle/math/randomvariable.hpp>
28+
#include <qle/models/lgm.hpp>
29+
30+
#include <ql/methods/finitedifferences/meshers/fdmmesher.hpp>
31+
#include <ql/methods/finitedifferences/solvers/fdmbackwardsolver.hpp>
32+
33+
namespace QuantExt {
34+
35+
//! Numerical FD solver for the LGM model
36+
class LgmFdSolver {
37+
public:
38+
LgmFdSolver(const boost::shared_ptr<LinearGaussMarkovModel>& model, const Real maxTime,
39+
const Size stateGridPoints = 64, const Size timeStepsPerYear = 24, const Real mesherEpsilon = 1E-4);
40+
41+
/* get grid size */
42+
Size gridSize() const;
43+
44+
/* get discretised states grid */
45+
RandomVariable stateGrid() const;
46+
47+
/* roll back an deflated NPV array from t1 to t0 */
48+
RandomVariable rollback(const RandomVariable& v, const Real t1, const Real t0) const;
49+
50+
/* the underlying model */
51+
const boost::shared_ptr<LinearGaussMarkovModel>& model() const;
52+
53+
private:
54+
boost::shared_ptr<LinearGaussMarkovModel> model_;
55+
Real maxTime_;
56+
Size stateGridPoints_;
57+
Size timeStepsPerYear_;
58+
Real mesherEpsilon_;
59+
60+
mutable boost::shared_ptr<FdmMesher> mesher_; // the mesher for the FD solver
61+
mutable boost::shared_ptr<FdmLinearOpComposite> operator_; // the operator
62+
mutable boost::shared_ptr<FdmBackwardSolver> solver_; // the sovler
63+
64+
RandomVariable mesherLocations_;
65+
};
66+
67+
} // namespace QuantExt

QuantExt/qle/quantext.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@
252252
#include <qle/methods/fdmblackscholesop.hpp>
253253
#include <qle/methods/fdmdefaultableequityjumpdiffusionfokkerplanckop.hpp>
254254
#include <qle/methods/fdmdefaultableequityjumpdiffusionop.hpp>
255+
#include <qle/methods/fdmlgmop.hpp>
255256
#include <qle/methods/fdmquantohelper.hpp>
256257
#include <qle/methods/multipathgeneratorbase.hpp>
257258
#include <qle/methods/multipathvariategenerator.hpp>
@@ -322,6 +323,7 @@
322323
#include <qle/models/lgm.hpp>
323324
#include <qle/models/lgmcalibrationinfo.hpp>
324325
#include <qle/models/lgmconvolutionsolver2.hpp>
326+
#include <qle/models/lgmfdsolver.hpp>
325327
#include <qle/models/lgmimplieddefaulttermstructure.hpp>
326328
#include <qle/models/lgmimpliedyieldtermstructure.hpp>
327329
#include <qle/models/lgmvectorised.hpp>

0 commit comments

Comments
 (0)