Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
lgmimpliedyieldtermstructure.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 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 lgmimpliedyieldtermstructure.hpp
20 \brief yield term structure implied by a LGM model
21 \ingroup models
22*/
23
24#ifndef quantext_lgm_implied_yts_hpp
25#define quantext_lgm_implied_yts_hpp
26
27#include <qle/models/lgm.hpp>
28
29#include <ql/termstructures/yieldtermstructure.hpp>
30
31namespace QuantExt {
32using namespace QuantLib;
33
34//! Lgm Implied Yield Term Structure
35/*! The termstructure has the reference date of the model's
36 termstructure at construction, but you can vary this
37 as well as the state.
38 The purely time based variant is mainly there for
39 performance reasons, note that it does not provide the
40 full term structure interface and does not send
41 notifications on reference time updates.
42
43 \ingroup models
44 */
45
46class LgmImpliedYieldTermStructure : public YieldTermStructure {
47public:
48 LgmImpliedYieldTermStructure(const QuantLib::ext::shared_ptr<LinearGaussMarkovModel>& model,
49 const DayCounter& dc = DayCounter(), const bool purelyTimeBased = false,
50 const bool cacheValues = false);
51
52 Date maxDate() const override;
53 Time maxTime() const override;
54
55 const Date& referenceDate() const override;
56
57 virtual void referenceDate(const Date& d);
58 virtual void referenceTime(const Time t);
59 void state(const Real s);
60 void move(const Date& d, const Real s);
61 void move(const Time t, const Real s);
62
63 virtual void update() override;
64
65protected:
66 Real discountImpl(Time t) const override;
67 mutable Real dt_;
68 mutable Real zeta_;
69 mutable Real Ht_;
71
72 const QuantLib::ext::shared_ptr<LinearGaussMarkovModel> model_;
73 const bool purelyTimeBased_;
76};
77
78//! Lgm Implied Yts Fwd Corrected
79/*! the target curve should have a reference date consistent with
80 the model's term structure
81
82 \ingroup models
83*/
85public:
86 LgmImpliedYtsFwdFwdCorrected(const QuantLib::ext::shared_ptr<LinearGaussMarkovModel>& model,
87 const Handle<YieldTermStructure> targetCurve, const DayCounter& dc = DayCounter(),
88 const bool purelyTimeBased = false, const bool cacheValues = false);
89
90 void referenceDate(const Date& d) override;
91 void referenceTime(const Time t) override;
92
93protected:
94 Real discountImpl(Time t) const override;
95
96private:
97 const Handle<YieldTermStructure> targetCurve_;
98};
99
100//! Lgm Implied Yts Spot Corrected
101/*! the target curve should have a reference date consistent with
102 the model's term structure
103
104 \ingroup models
105*/
107public:
108 LgmImpliedYtsSpotCorrected(const QuantLib::ext::shared_ptr<LinearGaussMarkovModel>& model,
109 const Handle<YieldTermStructure> targetCurve, const DayCounter& dc,
110 const bool purelyTimeBased, const bool cacheValues = false);
111
112protected:
113 Real discountImpl(Time t) const override;
114
115private:
116 const Handle<YieldTermStructure> targetCurve_;
117};
118
119// inline
120
122 // we don't care - let the underlying classes throw
123 // exceptions if applicable
124 return Date::maxDate();
125}
126
128 // see maxDate
129 return QL_MAX_REAL;
130}
131
133 QL_REQUIRE(!purelyTimeBased_, "reference date not available for purely "
134 "time based term structure");
135 return referenceDate_;
136}
137
139 QL_REQUIRE(!purelyTimeBased_, "reference date not available for purely "
140 "time based term structure");
141 referenceDate_ = d;
142 update();
143}
144
146 QL_REQUIRE(!purelyTimeBased_, "reference date not available for purely "
147 "time based term structure");
148 Date oldDate = referenceDate_;
149 referenceDate_ = d;
150 update();
151 if (cacheValues_ && oldDate != referenceDate_) {
152 dt_ = targetCurve_->discount(relativeTime_);
153 zeta_ = model_->parametrization()->zeta(relativeTime_);
154 Ht_ = model_->parametrization()->H(relativeTime_);
155 }
156}
157
159 QL_REQUIRE(purelyTimeBased_, "reference time can only be set for purely "
160 "time based term structure");
161 relativeTime_ = t;
162 notifyObservers();
163}
164
166 QL_REQUIRE(purelyTimeBased_, "reference time can only be set for purely "
167 "time based term structure");
168 if (cacheValues_ && relativeTime_ != t) {
169 dt_ = targetCurve_->discount(t);
170 zeta_ = model_->parametrization()->zeta(t);
171 Ht_ = model_->parametrization()->H(t);
172 }
173 relativeTime_ = t;
174
175 notifyObservers();
176}
177
178inline void LgmImpliedYieldTermStructure::state(const Real s) {
179 state_ = s;
180 notifyObservers();
181}
182
183inline void LgmImpliedYieldTermStructure::move(const Date& d, const Real s) {
184
185 state_ = s;
186 referenceDate(d);
187}
188
189inline void LgmImpliedYieldTermStructure::move(const Time t, const Real s) {
190 state_ = s;
191 referenceTime(t);
192
193 notifyObservers();
194}
195
197 if (!purelyTimeBased_) {
199 dayCounter().yearFraction(model_->parametrization()->termStructure()->referenceDate(), referenceDate_);
200 }
201
202 notifyObservers();
203}
204
206 QL_REQUIRE(t >= 0.0, "negative time (" << t << ") given");
207 return model_->discountBond(relativeTime_, relativeTime_ + t, state_);
208}
209
211 QL_REQUIRE(t >= 0.0, "negative time (" << t << ") given");
212 // if relativeTime_ is close to zero, we return the discount factor directly from the target curve
213 if (QuantLib::close_enough(relativeTime_, 0.0)) {
214 return targetCurve_->discount(t);
215 } else {
216 Real HT = model_->parametrization()->H(relativeTime_ + t);
217 if (!cacheValues_) {
218 dt_ = targetCurve_->discount(relativeTime_);
219 zeta_ = model_->parametrization()->zeta(relativeTime_);
220 Ht_ = model_->parametrization()->H(relativeTime_);
221 }
222 return std::exp(-(HT - Ht_) * state_ - 0.5 * (HT * HT - Ht_ * Ht_) * zeta_) *
223 targetCurve_->discount(relativeTime_ + t) / dt_;
224 }
225}
226
228 QL_REQUIRE(t >= 0.0, "negative time (" << t << ") given");
230 model_->parametrization()->termStructure()->discount(relativeTime_) /
231 model_->parametrization()->termStructure()->discount(relativeTime_ + t);
232}
233
234} // namespace QuantExt
235
236#endif
const QuantLib::ext::shared_ptr< LinearGaussMarkovModel > model_
const Handle< YieldTermStructure > targetCurve_
const Handle< YieldTermStructure > targetCurve_
lgm model class