QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
generalizedhullwhite.cpp
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#include <ql/experimental/shortrate/generalizedhullwhite.hpp>
22#include <ql/math/integrals/simpsonintegral.hpp>
23#include <ql/math/interpolations/backwardflatinterpolation.hpp>
24#include <ql/math/solvers1d/brent.hpp>
25#include <ql/methods/lattices/trinomialtree.hpp>
26#include <ql/pricingengines/blackformula.hpp>
27#include <utility>
28
29namespace QuantLib {
30
31 namespace {
32
33 // integral of mean reversion
34 Real integrateMeanReversion(const Interpolation &a,Real t,Real T) {
35 if ((T-t) < QL_EPSILON)
36 return 0.0;
37 SimpsonIntegral integrator(1e-5, 1000);
38 Real mr = integrator(a,t,T);
39 return mr;
40 }
41
42 }
43
44 /* Private function used by solver to determine time-dependent parameter
45 df(r) = [theta(t) - a(t) f(r)]dt + sigma(t) dz
46 dg = [theta(t) - a(t) g(t)] dt
47 dx = -a(t) x dt + sigma(t) dz
48 x = f(r) - g(t)
49 */
50 class GeneralizedHullWhite::Helper {
51 public:
52 Helper(const Size i,
53 const Real xMin,
54 const Real dx,
55 const Real discountBondPrice,
56 const ext::shared_ptr<ShortRateTree>& tree,
57 ext::function<Real(Real)> fInv)
58 : size_(tree->size(i)), dt_(tree->timeGrid().dt(i)), xMin_(xMin), dx_(dx),
59 statePrices_(tree->statePrices(i)), discountBondPrice_(discountBondPrice),
60 fInverse_(std::move(fInv)) {}
61
62 Real operator()(const Real theta) const {
63 Real value = discountBondPrice_;
64 Real x = xMin_;
65 for (Size j=0; j<size_; j++) {
66 Real discount = std::exp(- fInverse_(theta+x)*dt_);
67 value -= statePrices_[j]*discount;
68 x += dx_;
69 }
70 return value;
71 };
72
73 private:
74 Size size_;
75 Time dt_;
76 Real xMin_, dx_;
77 const Array& statePrices_;
78 Real discountBondPrice_;
79 ext::function<Real(Real)> fInverse_;
80 };
81
83 const Handle<YieldTermStructure>& yieldtermStructure,
84 const std::vector<Date>& speedstructure,
85 const std::vector<Date>& volstructure,
86 const std::vector<Real>& speed,
87 const std::vector<Real>& vol,
88 const ext::function<Real(Real)>& f,
89 const ext::function<Real(Real)>& fInverse)
90 : OneFactorAffineModel(2), TermStructureConsistentModel(yieldtermStructure),
91 speedstructure_(speedstructure),
92 volstructure_(volstructure),
93 a_(arguments_[0]), sigma_(arguments_[1]),
94 f_(f), fInverse_(fInverse) {
95
96 LinearFlat traits;
97 initialize(yieldtermStructure,speedstructure,volstructure,
98 speed, vol, traits, traits, f, fInverse);
99 }
100
101 //classical HW
103 const Handle<YieldTermStructure>& yieldtermStructure,
104 Real a, Real sigma)
106 TermStructureConsistentModel(yieldtermStructure),
107 a_(arguments_[0]),
108 sigma_(arguments_[1])
109 {
110 Date ref = yieldtermStructure->referenceDate();
111 std::vector<Date> speedstructure,volstructure;
112 std::vector<Real> _a, _sigma;
113 _a.push_back(a);
114 _sigma.push_back(sigma);
115 speedstructure.push_back(ref);
116 volstructure.push_back(ref);
117 BackwardFlat traits;
118 initialize(yieldtermStructure,speedstructure,volstructure,
119 _a, _sigma, traits, traits, identity, identity);
120 }
121
123 speed_.update();
124 vol_.update();
126 }
127
129 // Gurrieri et al, equations (30) and (31)
130 Real lnEt = integrateMeanReversion(speed_,0,t);
131 Real Et = exp(lnEt);
132 Real B = 0;
133 Size N = std::min<Size>(Size((T-t)*365), 2000);
134 if (N==0) N=1;
135 Real dt = 0.5*(T-t)/N;
136 Real a,b,c,_t,total=0;
137 _t = t;
138 c = speed_(_t);
139 _t += dt;
140 for (Size i=0; i<N; i++) {
141 a = c;
142 b = speed_(_t);
143 c = speed_(_t+dt);
144 total += (dt*(2.0/6.0))*(a+4*b+c);
145 B += (2*dt) / exp(lnEt+total);
146 _t += 2*dt;
147 }
148 B *= Et;
149 return B;
150 }
151
153 // Gurrieri et al, equation (37)
154 Real lnEt = integrateMeanReversion(speed_,0,t);
155 Real V = 0,Eu;
156 Size N = std::min<Size>(Size((T-t)*365), 2000);
157 if (N==0) N=1;
158 Real dt = 0.5*(T-t)/N;
159 Real a,b,c,_t,lnE=lnEt;
160 _t = t;
161 Real vol = vol_(_t);
162 Eu = exp(lnE);
163 c = Eu*Eu*vol*vol;
164 _t += dt;
165 for (Size i=0; i<N; i++) {
166 a = c;
167 vol = vol_(_t);
168 lnE += speed_(_t)*dt;
169 Eu = exp(lnE);
170 b = Eu*Eu*vol*vol;
171 vol = vol_(_t+dt);
172 lnE += speed_(_t+dt)*dt;
173 Eu = exp(lnE);
174 c = Eu*Eu*vol*vol;
175 V += (dt*(2.0/6.0))*(a+4*b+c);
176 _t += 2*dt;
177 }
178 return V / (Eu*Eu);
179 }
180
182 Time maturity,
183 Time bondMaturity) const
184 {
185 /*
186 Hull-White bond option pricing with time varying sigma and mean reversion.
187 Based on Gurrieri, Nakabayashi & Wong (2009) "Calibration Methods of
188 Hull-White Model", https://ssrn.com/abstract=1514192
189 */
190 Real BtT = B(maturity,bondMaturity);
191 Real Vr = V(0,maturity);
192 Real Vp = Vr*BtT*BtT;
193 Real vol = sqrt(Vp);
194 Real f = termStructure()->discount(bondMaturity);
195 Real k = termStructure()->discount(maturity)*strike;
196 return blackFormula(type, k, f, vol);
197 }
198
200 // Gurrieri et al, equation (43)
201 DiscountFactor discount1 = termStructure()->discount(t);
202 DiscountFactor discount2 = termStructure()->discount(T);
203 Rate forward = termStructure()->forwardRate(t, t, Continuous, NoFrequency);
204 Real BtT = B(t,T);
205 Real Vr = V(0,t);
206 Real AtT = log(discount2/discount1) + BtT*forward - 0.5*BtT*BtT*Vr;
207 return exp(AtT);
208 }
209
210
211 ext::shared_ptr<Lattice> GeneralizedHullWhite::tree(
212 const TimeGrid& grid) const{
213
215 ext::shared_ptr<ShortRateDynamics> numericDynamics(
216 new Dynamics(phi, speed(), vol(), f_, fInverse_));
217 ext::shared_ptr<TrinomialTree> trinomial(
218 new TrinomialTree(numericDynamics->process(), grid));
219 ext::shared_ptr<ShortRateTree> numericTree(
220 new ShortRateTree(trinomial, numericDynamics, grid));
222 ext::shared_ptr<NumericalImpl> impl =
223 ext::dynamic_pointer_cast<NumericalImpl>(phi.implementation());
224
225 impl->reset();
226 Real value = 1.0;
227 Real vMin = -50.0;
228 Real vMax = 50.0;
229
230 for (Size i=0; i<(grid.size() - 1); i++) {
231 Real discountBond = termStructure()->discount(grid[i+1]);
232 Real xMin = trinomial->underlying(i, 0);
233 Real dx = trinomial->dx(i);
234 Helper finder(i, xMin, dx, discountBond, numericTree, fInverse_);
235 Brent s1d;
236 s1d.setMaxEvaluations(2000);
237 value =s1d.solve(finder, 1e-8, value, vMin, vMax);
238 impl->set(grid[i], value);
239 }
240
241 return numericTree;
242 }
243
244 ext::function<Real (Time)> GeneralizedHullWhite::speed() const {
245 return speed_;
246 }
247
248 ext::function<Real (Time)> GeneralizedHullWhite::vol() const {
249 return vol_;
250 }
251
253 std::vector<bool> GeneralizedHullWhite::fixedReversion() const {
254 Size na = a_.params().size();
255 Size nsigma = sigma_.params().size();
256 std::vector<bool> fixr(na+nsigma,false);
257 std::fill(fixr.begin(),fixr.begin()+na,true);
258 return fixr;
259 }
260
261}
Size size() const
dimension of the array
Definition: array.hpp:495
Backward-flat interpolation factory and traits.
Brent 1-D solver
Definition: brent.hpp:37
Real value(const Array &params, const std::vector< ext::shared_ptr< CalibrationHelper > > &)
Definition: model.cpp:117
Concrete date class.
Definition: date.hpp:125
Short-rate dynamics in the generalized Hull-White model.
Analytical term-structure fitting parameter .
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 ext::function< Real(Real)> &f={}, const ext::function< Real(Real)> &fInverse={})
ext::function< Real(Time)> speed() const
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.
ext::function< Real(Time)> vol() 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)
Shared handle to an observable.
Definition: handle.hpp:41
Linear-interpolation with flat-extrapolation factory and traits
Single-factor affine base class.
Real discountBond(Time now, Time maturity, Array factors) const override
DiscountFactor discount(Time t) const override
Implied discount curve.
Recombining trinomial tree discretizing the state variable.
const ext::shared_ptr< Impl > & implementation() const
Definition: parameter.hpp:59
const Array & params() const
Definition: parameter.hpp:50
void setMaxEvaluations(Size evaluations)
Definition: solver1d.hpp:238
Real solve(const F &f, Real accuracy, Real guess, Real step) const
Definition: solver1d.hpp:84
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:149
time grid class
Definition: timegrid.hpp:43
Size size() const
Definition: timegrid.hpp:164
Recombining trinomial tree class.
@ 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 DiscountFactor
discount factor between dates
Definition: types.hpp:66
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
Real blackFormula(Option::Type optionType, Real strike, Real forward, Real stdDev, Real discount, Real displacement)
STL namespace.