QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
generalizedhullwhite.hpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2010 SunTrust Bank
5 Copyright (C) 2010, 2014 Cavit Hafizoglu
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21/*! \file generalizedhullwhite.hpp
22 \brief generalized Hull-White model
23*/
24
25#ifndef quantlib_generalized_hull_white_hpp
26#define quantlib_generalized_hull_white_hpp
27
32#include <utility>
33
34namespace QuantLib {
35
36 //! Parameter that holds an interpolation object
38 private:
39 class Impl final : public Parameter::Impl {
40 public:
41 Real value(const Array&, Time t) const override { return interpolator_(t); }
42 void reset(const Interpolation& interp) { interpolator_ = interp; }
43 private:
45 };
46 public:
48 Size count,
50 : Parameter(count,
51 ext::shared_ptr<Parameter::Impl>(
54 { }
55 void reset(const Interpolation &interp) {
56 ext::shared_ptr<InterpolationParameter::Impl> impl =
57 ext::dynamic_pointer_cast<InterpolationParameter::Impl>(impl_);
58 if (impl != nullptr)
59 impl->reset(interp);
60 }
61 };
62
63 //! Generalized Hull-White model class.
64 /*! This class implements the standard Black-Karasinski model defined by
65 \f[
66 d f(r_t) = (\theta(t) - \alpha f(r_t))dt + \sigma dW_t,
67 \f]
68 where \f$ alpha \f$ and \f$ sigma \f$ are piecewise linear functions.
69
70 \ingroup shortrate
71 */
74 public:
75
77 const Handle<YieldTermStructure>& yieldtermStructure,
78 const std::vector<Date>& speedstructure,
79 const std::vector<Date>& volstructure,
80 const std::vector<Real>& speed,
81 const std::vector<Real>& vol,
82 const ext::function<Real(Real)>& f = {},
83 const ext::function<Real(Real)>& fInverse = {});
84
85 template <class SpeedInterpolationTraits,class VolInterpolationTraits>
87 const Handle<YieldTermStructure>& yieldtermStructure,
88 const std::vector<Date>& speedstructure,
89 const std::vector<Date>& volstructure,
90 const std::vector<Real>& speed,
91 const std::vector<Real>& vol,
92 const SpeedInterpolationTraits &speedtraits,
93 const VolInterpolationTraits &voltraits,
94 const ext::function<Real(Real)>& f = {},
95 const ext::function<Real(Real)>& fInverse = {}) :
96 OneFactorAffineModel(2), TermStructureConsistentModel(yieldtermStructure),
97 speedstructure_(speedstructure), volstructure_(volstructure),
99 f_(f), fInverse_(fInverse)
100 {
101 initialize(yieldtermStructure,speedstructure,volstructure,
102 speed,vol,speedtraits,voltraits,f,fInverse);
103 }
104
105 ext::shared_ptr<ShortRateDynamics> dynamics() const override {
106 QL_FAIL("no defined process for generalized Hull-White model, "
107 "use HWdynamics()");
108 }
109
110 ext::shared_ptr<Lattice> tree(const TimeGrid& grid) const override;
111
112 //Analytical calibration of HW
113
115 const Handle<YieldTermStructure>& yieldtermStructure,
116 Real a = 0.1, Real sigma = 0.01);
117
118
119 ext::shared_ptr<ShortRateDynamics> HWdynamics() const;
120
121 //! Only valid under Hull-White model
123 Real strike,
124 Time maturity,
125 Time bondMaturity) const override;
126
127 //! vector to pass to 'calibrate' to fit only volatility
128 std::vector<bool> fixedReversion() const;
129
130 protected:
131 //Analytical calibration of HW
132 Real a() const { return a_(0.0); }
133 Real sigma() const { return sigma_(0.0); }
134 void generateArguments() override;
135 Real A(Time t, Time T) const override;
136 Real B(Time t, Time T) const override;
137 Real V(Time t, Time T) const;
138
139 private:
140
141 class Dynamics;
142 class Helper;
143 class FittingParameter;// for analytic HW fitting
144
145 std::vector<Date> speedstructure_;
146 std::vector<Date> volstructure_;
147 std::vector<Time> speedperiods_;
148 std::vector<Time> volperiods_;
151
152 ext::function<Real (Time)> speed() const;
153 ext::function<Real (Time)> vol() const;
154
158
159 ext::function<Real(Real)> f_;
160 ext::function<Real(Real)> fInverse_;
161
162 static Real identity(Real x) {
163 return x;
164 }
165
166 template <class SpeedInterpolationTraits,class VolInterpolationTraits>
167 void initialize(const Handle<YieldTermStructure>& yieldtermStructure,
168 const std::vector<Date>& speedstructure,
169 const std::vector<Date>& volstructure,
170 const std::vector<Real>& speed,
171 const std::vector<Real>& vol,
172 const SpeedInterpolationTraits &speedtraits,
173 const VolInterpolationTraits &voltraits,
174 const ext::function<Real(Real)>& f,
175 const ext::function<Real(Real)>& fInverse)
176 {
177 QL_REQUIRE(speedstructure.size()==speed.size(),
178 "mean reversion inputs inconsistent");
179 QL_REQUIRE(volstructure.size()==vol.size(),
180 "volatility inputs inconsistent");
181 if (!f_)
182 f_ = identity;
183 if (!fInverse_)
185
186 DayCounter dc = yieldtermStructure->dayCounter();
187 Date ref = yieldtermStructure->referenceDate();
188 for (auto i : speedstructure)
189 speedperiods_.push_back(dc.yearFraction(ref, i));
190 for (auto i : volstructure)
191 volperiods_.push_back(dc.yearFraction(ref, i));
192
193 // interpolator x points to *periods_ vector, y points to
194 // the internal Array in the parameter
196 a_ = atemp;
197 for (Size i=0; i<speedperiods_.size(); i++)
198 a_.setParam(i, speed[i]);
199 speed_ = speedtraits.interpolate(speedperiods_.begin(),
200 speedperiods_.end(),a_.params().begin());
202 atemp.reset(speed_);
203
205 sigma_ = sigmatemp;
206 for (Size i=0; i<volperiods_.size(); i++)
207 sigma_.setParam(i, vol[i]);
208 vol_ = voltraits.interpolate(volperiods_.begin(),
209 volperiods_.end(),sigma_.params().begin());
211 sigmatemp.reset(vol_);
212
214 registerWith(yieldtermStructure);
215 }
216 };
217
218 //! Short-rate dynamics in the generalized Hull-White model
219 /*! The short-rate is here
220
221 f(r_t) = x_t + g(t)
222
223 where g is the deterministic time-dependent
224 parameter (which can't be determined analytically)
225 used for initial term-structure fitting and x_t is the state
226 variable following an Ornstein-Uhlenbeck process.
227
228 In this version, the function f may also be defined as a piece-wise linear
229 function and can be calibrated to the away-from-the-money instruments.
230
231 */
233 : public GeneralizedHullWhite::ShortRateDynamics {
234 public:
236 const ext::function<Real(Time)>& alpha,
237 const ext::function<Real(Time)>& sigma,
238 ext::function<Real(Real)> f,
239 ext::function<Real(Real)> fInverse)
240 : ShortRateDynamics(ext::shared_ptr<StochasticProcess1D>(
242 fitting_(std::move(fitting)), _f_(std::move(f)), _fInverse_(std::move(fInverse)) {}
243
244 //classical HW dynamics
247 ext::shared_ptr<StochasticProcess1D>(new OrnsteinUhlenbeckProcess(a, sigma))),
248 fitting_(std::move(fitting)), _f_(identity()), _fInverse_(identity()) {}
249
250 Real variable(Time t, Rate r) const override { return _f_(r) - fitting_(t); }
251
252 Real shortRate(Time t, Real x) const override { return _fInverse_(x + fitting_(t)); }
253
254 private:
256 ext::function<Real(Real)> _f_;
257 ext::function<Real(Real)> _fInverse_;
258 struct identity {
259 Real operator()(Real x) const {return x;};
260 };
261 };
262
263 //! Analytical term-structure fitting parameter \f$ \varphi(t) \f$.
264 /*! \f$ \varphi(t) \f$ is analytically defined by
265 \f[
266 \varphi(t) = f(t) + \frac{1}{2}[\frac{\sigma(1-e^{-at})}{a}]^2,
267 \f]
268 where \f$ f(t) \f$ is the instantaneous forward rate at \f$ t \f$.
269 */
272 private:
273 class Impl final : public Parameter::Impl {
274 public:
277
278 Real value(const Array&, Time t) const override {
279 Rate forwardRate =
280 termStructure_->forwardRate(t, t, Continuous, NoFrequency);
281 Real temp = a_ < std::sqrt(QL_EPSILON) ?
282 Real(sigma_*t) :
283 Real(sigma_*(1.0 - std::exp(-a_*t))/a_);
284 return (forwardRate + 0.5*temp*temp);
285 }
286
287 private:
290 };
291 public:
293 Real a, Real sigma)
294 : TermStructureFittingParameter(ext::shared_ptr<Parameter::Impl>(
296 };
297
298 // Analytic fitting dynamics
299 inline ext::shared_ptr<OneFactorModel::ShortRateDynamics>
301 return ext::shared_ptr<ShortRateDynamics>(
302 new Dynamics(phi_, a(), sigma()));
303 }
304
305 namespace detail {
306 template <class I1, class I2>
307 class LinearFlatInterpolationImpl;
308 }
309
310 //! %Linear interpolation between discrete points with flat extapolation
311 /*! \ingroup interpolations */
313 public:
314 /*! \pre the \f$ x \f$ values must be sorted. */
315 template <class I1, class I2>
316 LinearFlatInterpolation(const I1& xBegin, const I1& xEnd,
317 const I2& yBegin) {
318 impl_ = ext::shared_ptr<Interpolation::Impl>(new
320 yBegin));
321 impl_->update();
322 }
323 };
324
325 //! %Linear-interpolation with flat-extrapolation factory and traits
326 /*! \ingroup interpolations */
328 public:
329 template <class I1, class I2>
330 Interpolation interpolate(const I1& xBegin, const I1& xEnd,
331 const I2& yBegin) const {
332 return LinearFlatInterpolation(xBegin, xEnd, yBegin);
333 }
334 static const bool global = false;
335 static const Size requiredPoints = 1;
336 };
337
338 namespace detail {
339 template <class I1, class I2>
341 : public Interpolation::templateImpl<I1,I2> {
342 public:
343 LinearFlatInterpolationImpl(const I1& xBegin, const I1& xEnd,
344 const I2& yBegin)
345 : Interpolation::templateImpl<I1,I2>(xBegin, xEnd, yBegin,
346 LinearFlat::requiredPoints),
347 primitiveConst_(xEnd-xBegin), s_(xEnd-xBegin) {}
348 void update() override {
349 primitiveConst_[0] = 0.0;
350 for (Size i=1; i<Size(this->xEnd_-this->xBegin_); ++i) {
351 Real dx = this->xBegin_[i]-this->xBegin_[i-1];
352 s_[i-1] = (this->yBegin_[i]-this->yBegin_[i-1])/dx;
354 + dx*(this->yBegin_[i-1] +0.5*dx*s_[i-1]);
355 }
356 }
357 Real value(Real x) const override {
358 if (x <= this->xMin())
359 return this->yBegin_[0];
360 if (x >= this->xMax())
361 return *(this->yBegin_+(this->xEnd_-this->xBegin_)-1);
362 Size i = this->locate(x);
363 return this->yBegin_[i] + (x-this->xBegin_[i])*s_[i];
364 }
365 Real primitive(Real x) const override {
366 Size i = this->locate(x);
367 Real dx = x-this->xBegin_[i];
368 return primitiveConst_[i] +
369 dx*(this->yBegin_[i] + 0.5*dx*s_[i]);
370 }
371 Real derivative(Real x) const override {
372 if (!this->isInRange(x))
373 return 0;
374 Size i = this->locate(x);
375 return s_[i];
376 }
377 Real secondDerivative(Real) const override { return 0.0; }
378
379 private:
380 std::vector<Real> primitiveConst_, s_;
381 };
382 }
383
384}
385
386
387#endif
1-D array used in linear algebra.
Definition: array.hpp:52
const_iterator begin() const
Definition: array.hpp:503
std::vector< Parameter > arguments_
Definition: model.hpp:126
Base constraint class.
Definition: constraint.hpp:35
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
Time yearFraction(const Date &, const Date &, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date()) const
Returns the period between two dates as a fraction of year.
Definition: daycounter.hpp:128
void enableExtrapolation(bool b=true)
enable extrapolation in subsequent calls
Short-rate dynamics in the generalized Hull-White model.
Dynamics(Parameter fitting, Real a, Real sigma)
Real shortRate(Time t, Real x) const override
Dynamics(Parameter fitting, const ext::function< Real(Time)> &alpha, const ext::function< Real(Time)> &sigma, ext::function< Real(Real)> f, ext::function< Real(Real)> fInverse)
Real variable(Time t, Rate r) const override
Real value(const Array &, Time t) const override
Impl(Handle< YieldTermStructure > termStructure, Real a, Real sigma)
Analytical term-structure fitting parameter .
FittingParameter(const Handle< YieldTermStructure > &termStructure, Real a, Real sigma)
Generalized Hull-White model class.
ext::function< Real(Time)> speed() const
ext::shared_ptr< ShortRateDynamics > dynamics() const override
returns the short-rate dynamics
ext::function< Real(Real)> fInverse_
Real B(Time t, Time T) const override
std::vector< bool > fixedReversion() const
vector to pass to 'calibrate' to fit only volatility
Real discountBondOption(Option::Type type, Real strike, Time maturity, Time bondMaturity) const override
Only valid under Hull-White model.
GeneralizedHullWhite(const Handle< YieldTermStructure > &yieldtermStructure, const std::vector< Date > &speedstructure, const std::vector< Date > &volstructure, const std::vector< Real > &speed, const std::vector< Real > &vol, const SpeedInterpolationTraits &speedtraits, const VolInterpolationTraits &voltraits, const ext::function< Real(Real)> &f={}, const ext::function< Real(Real)> &fInverse={})
ext::function< Real(Time)> vol() const
ext::shared_ptr< ShortRateDynamics > HWdynamics() const
ext::shared_ptr< Lattice > tree(const TimeGrid &grid) const override
Real A(Time t, Time T) const override
void initialize(const Handle< YieldTermStructure > &yieldtermStructure, const std::vector< Date > &speedstructure, const std::vector< Date > &volstructure, const std::vector< Real > &speed, const std::vector< Real > &vol, const SpeedInterpolationTraits &speedtraits, const VolInterpolationTraits &voltraits, const ext::function< Real(Real)> &f, const ext::function< Real(Real)> &fInverse)
Piecewise linear Ornstein-Uhlenbeck process class.
Shared handle to an observable.
Definition: handle.hpp:41
basic template implementation
templateImpl(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin, const int requiredPoints=2)
bool isInRange(Real x) const override
base class for 1-D interpolations.
ext::shared_ptr< Impl > impl_
Real value(const Array &, Time t) const override
void reset(const Interpolation &interp)
Parameter that holds an interpolation object.
InterpolationParameter(Size count, const Constraint &constraint=NoConstraint())
void reset(const Interpolation &interp)
Linear-interpolation with flat-extrapolation factory and traits
static const Size requiredPoints
Interpolation interpolate(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin) const
Linear interpolation between discrete points with flat extapolation
LinearFlatInterpolation(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin)
No constraint.
Definition: constraint.hpp:79
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
Single-factor affine base class.
Base class describing the short-rate dynamics.
Ornstein-Uhlenbeck process class.
Base class for model parameter implementation.
Definition: parameter.hpp:41
Base class for model arguments.
Definition: parameter.hpp:38
const Constraint & constraint() const
Definition: parameter.hpp:62
void setParam(Size i, Real x)
Definition: parameter.hpp:51
const Array & params() const
Definition: parameter.hpp:50
ext::shared_ptr< Impl > impl_
Definition: parameter.hpp:46
Constraint imposing positivity to all arguments
Definition: constraint.hpp:92
1-dimensional stochastic process
Term-structure consistent model class.
Definition: model.hpp:73
const Handle< YieldTermStructure > & termStructure() const
Definition: model.hpp:77
Deterministic time-dependent parameter used for yield-curve fitting.
Definition: parameter.hpp:145
time grid class
Definition: timegrid.hpp:43
LinearFlatInterpolationImpl(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin)
const DefaultType & t
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
#define QL_FAIL(message)
throw an error (possibly with file and line information)
Definition: errors.hpp:92
Ornstein-Uhlenbeck process with piecewise linear coefficients.
@ NoFrequency
null frequency
Definition: frequency.hpp:37
#define QL_EPSILON
Definition: qldefines.hpp:178
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
base class for 1-D interpolations
Definition: any.hpp:35
STL namespace.
Abstract one-factor interest rate model class.
Ornstein-Uhlenbeck process.
ext::shared_ptr< YieldTermStructure > r
Real alpha
Definition: sabr.cpp:200