Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
cirppconstantfellerparametrization.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2020 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 cirppconstantfellerparametrization.hpp
20 \brief constant CIR ++ parametrization
21 \ingroup models
22*/
23
24#ifndef quantext_cirpp_constant_feller_parametrization_hpp
25#define quantext_cirpp_constant_feller_parametrization_hpp
26
28
29#include <ql/errors.hpp>
30
31namespace QuantExt {
32
33//! CIR++ Constant Parametrization
34/*! \ingroup models
35 */
36template <class TS> class CirppConstantWithFellerParametrization : public CirppParametrization<TS> {
37public:
38 // sigma^2 is set to 2 \kappa \theta / fellerFactor (relaxed = false)
39 // resp. 4 \kappa \theta / fellerFactor (relaxed = true)
40 CirppConstantWithFellerParametrization(const Currency& currency, const Handle<TS>& termStructure,
41 const Real kappa, const Real theta, const Real sigma, const Real y0,
42 const bool shifted, bool relaxed = false,
43 const Real fellerFactor = 2.0,
44 const std::string& name = std::string());
45
46 Real kappa(const Time t) const override;
47 Real theta(const Time t) const override;
48 Real sigma(const Time t) const override;
49 Real y0(const Time t) const override;
50
51 const QuantLib::ext::shared_ptr<Parameter> parameter(const Size) const override;
52 const bool relaxed() const;
53
54protected:
55 Real direct(const Size i, const Real x) const override;
56 Real inverse(const Size j, const Real y) const override;
57
58private:
59 const QuantLib::ext::shared_ptr<PseudoParameter> kappa_, theta_, sigma_, y0_;
61 const Real fellerFactor_;
62};
63
64// implementation
65
66template <class TS>
68 const Currency& currency, const Handle<TS>& termStructure, const Real kappa, const Real theta, const Real sigma,
69 const Real y0, const bool shifted, bool relaxed, const Real fellerFactor, const std::string& name)
70 : CirppParametrization<TS>(currency, termStructure, shifted, name),
71 kappa_(QuantLib::ext::make_shared<PseudoParameter>(1)),
72 theta_(QuantLib::ext::make_shared<PseudoParameter>(1)), sigma_(QuantLib::ext::make_shared<PseudoParameter>(1)),
73 y0_(QuantLib::ext::make_shared<PseudoParameter>(1)), relaxed_(relaxed), fellerFactor_(fellerFactor) {
74 QL_REQUIRE((relaxed_ ? 4.0 : 2.0) * kappa * theta > sigma * sigma,
75 "CirppConstantWithFellerParametrization: Feller constraint violated (kappa="
76 << kappa << ", theta=" << theta << ", sigma=" << sigma << " (relaxed=" << std::boolalpha << relaxed_
77 << ")");
78 QL_REQUIRE(fellerFactor_ > 1.0, "CirppConstantWithFellerParametrization: Feller factor ("
79 << fellerFactor_ << ") should be greater than 1.0");
80 kappa_->setParam(0, inverse(0, kappa));
81 theta_->setParam(0, inverse(1, theta));
82 sigma_->setParam(0, inverse(2, sigma));
83 y0_->setParam(0, inverse(3, y0));
84}
85
86template <class TS>
87inline Real CirppConstantWithFellerParametrization<TS>::direct(const Size i, const Real x) const {
88 constexpr Real eps = 1E-10;
89 switch (i) {
90 case 0:
91 case 1:
92 case 3:
93 return x * x + eps;
94 case 2: {
95 const Real fellerBound =
96 std::sqrt((relaxed_ ? 4.0 : 2.0) * direct(0, kappa_->params()[0]) * direct(1, theta_->params()[0]));
97 // return fellerBound * (std::atan(x) + M_PI_2 + eps) / (M_PI - 2.0 * eps); // "free sigma"
98 return fellerBound / std::sqrt(fellerFactor_); // tie sigma to kappa/theta on feller boundary
99 }
100 default:
101 QL_FAIL("Index is not defined!");
102 }
103}
104
105template <class TS>
106inline Real CirppConstantWithFellerParametrization<TS>::inverse(const Size i, const Real y) const {
107 constexpr Real eps = 1E-10;
108 switch (i) {
109 case 0:
110 case 1:
111 case 3:
112 return std::sqrt(y - eps);
113 case 2: {
114 const Real fellerBound =
115 std::sqrt((relaxed_ ? 4.0 : 2.0) * direct(0, kappa_->params()[0]) * direct(1, theta_->params()[0]));
116 // return std::tan(y / fellerBound * (M_PI - 2.0 * eps) - M_PI_2 - eps); // see above
117 return fellerBound / std::sqrt(fellerFactor_); // see above
118 }
119 default:
120 QL_FAIL("Index is not defined!");
121 }
122}
123
124template <class TS> inline Real CirppConstantWithFellerParametrization<TS>::kappa(const Time) const {
125 return direct(0, kappa_->params()[0]);
126}
127
128template <class TS> inline Real CirppConstantWithFellerParametrization<TS>::theta(const Time) const {
129 return direct(1, theta_->params()[0]);
130}
131
132template <class TS> inline Real CirppConstantWithFellerParametrization<TS>::sigma(const Time) const {
133 return direct(2, sigma_->params()[0]);
134}
135
136template <class TS> inline Real CirppConstantWithFellerParametrization<TS>::y0(const Time) const {
137 return direct(3, y0_->params()[0]);
138}
139
140template <class TS> inline const bool CirppConstantWithFellerParametrization<TS>::relaxed() const {
141 return relaxed_;
142}
143
144template <class TS>
145inline const QuantLib::ext::shared_ptr<Parameter>
147 QL_REQUIRE(i < 4, "parameter " << i << " does not exist, only have 0..3");
148 if (i == 0)
149 return kappa_;
150 else if (i == 1)
151 return theta_;
152 else if (i == 2)
153 return sigma_;
154 else
155 return y0_;
156}
157
158// typedef
161
162} // namespace QuantExt
163
164#endif
CIR ++ parametrisation.
const QuantLib::ext::shared_ptr< PseudoParameter > theta_
Real direct(const Size i, const Real x) const override
const QuantLib::ext::shared_ptr< PseudoParameter > sigma_
const QuantLib::ext::shared_ptr< PseudoParameter > y0_
Real inverse(const Size j, const Real y) const override
const QuantLib::ext::shared_ptr< PseudoParameter > kappa_
const QuantLib::ext::shared_ptr< Parameter > parameter(const Size) const override
CirppConstantWithFellerParametrization(const Currency &currency, const Handle< TS > &termStructure, const Real kappa, const Real theta, const Real sigma, const Real y0, const bool shifted, bool relaxed=false, const Real fellerFactor=2.0, const std::string &name=std::string())
const Handle< TS > termStructure() const
const std::string & name() const
virtual const Currency & currency() const
Parameter that accesses CalibratedModel.
CirppConstantWithFellerParametrization< YieldTermStructure > IrCirppConstantWithFellerParametrization
CirppConstantWithFellerParametrization< DefaultProbabilityTermStructure > CrCirppConstantWithFellerParametrization