QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
g2.cpp
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) 2001, 2002, 2003 Sadruddin Rejeb
5 Copyright (C) 2004 Mike Parker
6 Copyright (C) 2021 Magnus Mencke
7
8 This file is part of QuantLib, a free-software/open-source library
9 for financial quantitative analysts and developers - http://quantlib.org/
10
11 QuantLib is free software: you can redistribute it and/or modify it
12 under the terms of the QuantLib license. You should have received a
13 copy of the license along with this program; if not, please email
14 <quantlib-dev@lists.sf.net>. The license is also available online at
15 <http://quantlib.org/license.shtml>.
16
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the license for more details.
20*/
21
27#include <utility>
28
29namespace QuantLib {
30
31 G2::G2(const Handle<YieldTermStructure>& termStructure,
32 Real a, Real sigma, Real b, Real eta, Real rho)
34 a_(arguments_[0]), sigma_(arguments_[1]), b_(arguments_[2]),
35 eta_(arguments_[3]), rho_(arguments_[4]) {
36
42
44
46 }
47
48 ext::shared_ptr<TwoFactorModel::ShortRateDynamics> G2::dynamics() const {
49 return ext::shared_ptr<ShortRateDynamics>(new
50 Dynamics(phi_, a(), sigma(), b(), eta(), rho()));
51 }
52
54
56 a(), sigma(), b(), eta(), rho());
57 }
58
60 Real temp = 1.0 - std::exp(-(a()+b())*t);
61 Real temp1 = 1.0 - std::exp(-a()*(s-t));
62 Real temp2 = 1.0 - std::exp(-b()*(s-t));
63 Real a3 = a()*a()*a();
64 Real b3 = b()*b()*b();
65 Real sigma2 = sigma()*sigma();
66 Real eta2 = eta()*eta();
67 Real value =
68 0.5*sigma2*temp1*temp1*(1.0 - std::exp(-2.0*a()*t))/a3 +
69 0.5*eta2*temp2*temp2*(1.0 - std::exp(-2.0*b()*t))/b3 +
70 2.0*rho()*sigma()*eta()/(a()*b()*(a()+b()))*
71 temp1*temp2*temp;
72 return std::sqrt(value);
73 }
74
76 return A(t,T) * std::exp(-B(a(),(T-t))*x-B(b(),(T-t))*y);
77 }
78
80 Time bondMaturity) const {
81
82 Real v = sigmaP(maturity, bondMaturity);
83 Real f = termStructure()->discount(bondMaturity);
84 Real k = termStructure()->discount(maturity)*strike;
85
86 return blackFormula(type, k, f, v);
87 }
88
89 Real G2::V(Time t) const {
90 Real expat = std::exp(-a()*t);
91 Real expbt = std::exp(-b()*t);
92 Real cx = sigma()/a();
93 Real cy = eta()/b();
94 Real valuex = cx*cx*(t + (2.0*expat-0.5*expat*expat-1.5)/a());
95 Real valuey = cy*cy*(t + (2.0*expbt-0.5*expbt*expbt-1.5)/b());
96 Real value = 2.0*rho()*cx*cy* (t + (expat - 1.0)/a()
97 + (expbt - 1.0)/b()
98 - (expat*expbt-1.0)/(a()+b()));
99 return valuex + valuey + value;
100 }
101
102 Real G2::A(Time t, Time T) const {
103 return termStructure()->discount(T)/termStructure()->discount(t)*
104 std::exp(0.5*(V(T-t) - V(T) + V(t)));
105 }
106
107 Real G2::B(Real x, Time t) const {
108 return (1.0 - std::exp(-x*t))/x;
109 }
110
111 class G2::SwaptionPricingFunction {
112 public:
113 SwaptionPricingFunction(Real a,
114 Real sigma,
115 Real b,
116 Real eta,
117 Real rho,
118 Real w,
119 Real start,
120 std::vector<Time> payTimes,
121 Rate fixedRate,
122 const G2& model)
123 : a_(a), sigma_(sigma), b_(b), eta_(eta), rho_(rho), w_(w), T_(start),
124 t_(std::move(payTimes)), rate_(fixedRate), size_(t_.size()), A_(size_), Ba_(size_),
125 Bb_(size_) {
126
127
128 sigmax_ = sigma_*std::sqrt(0.5*(1.0-std::exp(-2.0*a_*T_))/a_);
129 sigmay_ = eta_*std::sqrt(0.5*(1.0-std::exp(-2.0*b_*T_))/b_);
130 rhoxy_ = rho_*eta_*sigma_*(1.0 - std::exp(-(a_+b_)*T_))/
131 ((a_+b_)*sigmax_*sigmay_);
132
133 Real temp = sigma_*sigma_/(a_*a_);
134 mux_ = -((temp+rho_*sigma_*eta_/(a_*b_))*(1.0 - std::exp(-a*T_)) -
135 0.5*temp*(1.0 - std::exp(-2.0*a_*T_)) -
136 rho_*sigma_*eta_/(b_*(a_+b_))*
137 (1.0- std::exp(-(b_+a_)*T_)));
138
139 temp = eta_*eta_/(b_*b_);
140 muy_ = -((temp+rho_*sigma_*eta_/(a_*b_))*(1.0 - std::exp(-b*T_)) -
141 0.5*temp*(1.0 - std::exp(-2.0*b_*T_)) -
142 rho_*sigma_*eta_/(a_*(a_+b_))*
143 (1.0- std::exp(-(b_+a_)*T_)));
144
145 for (Size i=0; i<size_; i++) {
146 A_[i] = model.A(T_, t_[i]);
147 Ba_[i] = model.B(a_, t_[i]-T_);
148 Bb_[i] = model.B(b_, t_[i]-T_);
149 }
150 }
151
152 Real mux() const { return mux_; }
153 Real sigmax() const { return sigmax_; }
154 Real operator()(Real x) const {
155 CumulativeNormalDistribution phi;
156 Real temp = (x - mux_)/sigmax_;
157 Real txy = std::sqrt(1.0 - rhoxy_*rhoxy_);
158
159 Array lambda(size_);
160 Size i;
161 for (i=0; i<size_; i++) {
162 Real tau = (i==0 ? t_[0] - T_ : t_[i] - t_[i-1]);
163 Real c = (i==size_-1 ? Real(1.0+rate_*tau) : rate_*tau);
164 lambda[i] = c*A_[i]*std::exp(-Ba_[i]*x);
165 }
166
167 SolvingFunction function(lambda, Bb_) ;
168 Brent s1d;
169 s1d.setMaxEvaluations(1000);
170 Real searchBound = std::max(10.0*sigmay_, 1.0);
171 Real yb = s1d.solve(function, 1e-6, 0.00, -searchBound, searchBound);
172
173 Real h1 = (yb - muy_)/(sigmay_*txy) -
174 rhoxy_*(x - mux_)/(sigmax_*txy);
175 Real value = phi(-w_*h1);
176
177
178 for (i=0; i<size_; i++) {
179 Real h2 = h1 +
180 Bb_[i]*sigmay_*std::sqrt(1.0-rhoxy_*rhoxy_);
181 Real kappa = - Bb_[i] *
182 (muy_ - 0.5*txy*txy*sigmay_*sigmay_*Bb_[i] +
183 rhoxy_*sigmay_*(x-mux_)/sigmax_);
184 value -= lambda[i] *std::exp(kappa)*phi(-w_*h2);
185 }
186
187 return std::exp(-0.5*temp*temp)*value/
188 (sigmax_*std::sqrt(2.0*M_PI));
189 }
190
191
192 private:
193 class SolvingFunction {
194 public:
195 SolvingFunction(const Array& lambda, const Array& Bb)
196 : lambda_(lambda), Bb_(Bb) {}
197 Real operator()(Real y) const {
198 Real value = 1.0;
199 for (Size i=0; i<lambda_.size(); i++) {
200 value -= lambda_[i]*std::exp(-Bb_[i]*y);
201 }
202 return value;
203 }
204 private:
205 const Array& lambda_;
206 const Array& Bb_;
207 };
208
209 Real a_, sigma_, b_, eta_, rho_, w_;
210 Time T_;
211 std::vector<Time> t_;
212 Rate rate_;
213 Size size_;
214 Array A_, Ba_, Bb_;
215 Real mux_, muy_, sigmax_, sigmay_, rhoxy_;
216 };
217
219 Rate fixedRate, Real range, Size intervals) const {
220
221 QL_REQUIRE(arguments.nominal != Null<Real>(),
222 "non-constant nominals are not supported yet");
223
224 Date settlement = termStructure()->referenceDate();
225 DayCounter dayCounter = termStructure()->dayCounter();
226 Time start = dayCounter.yearFraction(settlement,
227 arguments.floatingResetDates[0]);
228 Real w = (arguments.type==Swap::Payer ? 1 : -1 );
229
230 std::vector<Time> fixedPayTimes(arguments.fixedPayDates.size());
231 for (Size i=0; i<fixedPayTimes.size(); ++i)
232 fixedPayTimes[i] =
233 dayCounter.yearFraction(settlement,
234 arguments.fixedPayDates[i]);
235
236 SwaptionPricingFunction function(a(), sigma(), b(), eta(), rho(),
237 w, start,
238 fixedPayTimes,
239 fixedRate, (*this));
240
241 Real upper = function.mux() + range*function.sigmax();
242 Real lower = function.mux() - range*function.sigmax();
243 SegmentIntegral integrator(intervals);
244 return arguments.nominal * w * termStructure()->discount(start) *
245 integrator(function, lower, upper);
246 }
247
248}
Black formula.
Brent 1-D solver.
Constraint imposing all arguments to be in [low,high]
Definition: constraint.hpp:114
Real value(const Array &params, const std::vector< ext::shared_ptr< CalibrationHelper > > &)
Definition: model.cpp:117
Standard constant parameter .
Definition: parameter.hpp:71
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
Analytical term-structure fitting parameter .
Definition: g2.hpp:142
Two-additive-factor gaussian model class.
Definition: g2.hpp:56
Parameter & sigma_
Definition: g2.hpp:106
Real discountBond(Time now, Time maturity, Array factors) const override
Definition: g2.hpp:67
Parameter & b_
Definition: g2.hpp:107
Parameter phi_
Definition: g2.hpp:111
G2(const Handle< YieldTermStructure > &termStructure, Real a=0.1, Real sigma=0.01, Real b=0.1, Real eta=0.01, Real rho=-0.75)
Definition: g2.cpp:31
Real b() const
Definition: g2.hpp:89
Real sigma() const
Definition: g2.hpp:88
Parameter & eta_
Definition: g2.hpp:108
Real swaption(const Swaption::arguments &arguments, Rate fixedRate, Real range, Size intervals) const
Definition: g2.cpp:218
Real sigmaP(Time t, Time s) const
Definition: g2.cpp:59
Real discountBondOption(Option::Type type, Real strike, Time maturity, Time bondMaturity) const override
Definition: g2.cpp:79
void generateArguments() override
Definition: g2.cpp:53
Real V(Time t) const
Definition: g2.cpp:89
Real rho() const
Definition: g2.hpp:91
Real a() const
Definition: g2.hpp:87
Parameter & rho_
Definition: g2.hpp:109
Real A(Time t, Time T) const
Definition: g2.cpp:102
ext::shared_ptr< ShortRateDynamics > dynamics() const override
Returns the short-rate dynamics.
Definition: g2.cpp:48
Real eta() const
Definition: g2.hpp:90
Parameter & a_
Definition: g2.hpp:105
Real B(Real x, Time t) const
Definition: g2.cpp:107
Shared handle to an observable.
Definition: handle.hpp:41
template class providing a null value for a given type.
Definition: null.hpp:76
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
Constraint imposing positivity to all arguments
Definition: constraint.hpp:92
Integral of a one-dimensional function.
Arguments for swaption calculation
Definition: swaption.hpp:147
Term-structure consistent model class.
Definition: model.hpp:73
const Handle< YieldTermStructure > & termStructure() const
Definition: model.hpp:77
Abstract base-class for two-factor models.
Real a_
const DefaultType & t
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
ext::function< Real(Real)> b
Two-factor additive Gaussian Model G2++.
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
Real kappa
Real rho
Real sigma
const VF_R b_
#define M_PI
Definition: any.hpp:35
Real blackFormula(Option::Type optionType, Real strike, Real forward, Real stdDev, Real discount, Real displacement)
STL namespace.
normal, cumulative and inverse cumulative distributions
ext::shared_ptr< BlackVolTermStructure > v
Size size_
Definition: pseudosqrt.cpp:76
Integral of a one-dimensional function using segment algorithm.