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 
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 g2.hpp
22     \brief Two-factor additive Gaussian Model G2++
23 */
24 
25 #ifndef quantlib_two_factor_models_g2_h
26 #define quantlib_two_factor_models_g2_h
27 
28 #include <ql/models/shortrate/twofactormodel.hpp>
29 #include <ql/processes/ornsteinuhlenbeckprocess.hpp>
30 #include <ql/instruments/swaption.hpp>
31 
32 namespace QuantLib {
33 
34     //! Two-additive-factor gaussian model class.
35     /*! This class implements a two-additive-factor model defined by
36         \f[
37             dr_t = \varphi(t) + x_t + y_t
38         \f]
39         where \f$ x_t \f$ and \f$ y_t \f$ are defined by
40         \f[
41             dx_t = -a x_t dt + \sigma dW^1_t, x_0 = 0
42         \f]
43         \f[
44             dy_t = -b y_t dt + \sigma dW^2_t, y_0 = 0
45         \f]
46         and \f$ dW^1_t dW^2_t = \rho dt \f$.
47 
48         \bug This class was not tested enough to guarantee
49              its functionality.
50 
51         \ingroup shortrate
52     */
53     class G2 : public TwoFactorModel,
54                public AffineModel,
55                public TermStructureConsistentModel {
56       public:
57         G2(const Handle<YieldTermStructure>& termStructure,
58            Real a = 0.1,
59            Real sigma = 0.01,
60            Real b = 0.1,
61            Real eta = 0.01,
62            Real rho = -0.75);
63 
64         ext::shared_ptr<ShortRateDynamics> dynamics() const;
65 
discountBond(Time now,Time maturity,Array factors) const66         virtual Real discountBond(Time now,
67                                   Time maturity,
68                                   Array factors) const {
69             QL_REQUIRE(factors.size()>1,
70                        "g2 model needs two factors to compute discount bond");
71             return discountBond(now, maturity, factors[0], factors[1]);
72         }
73 
74         Real discountBond(Time, Time, Rate, Rate) const;
75 
76         Real discountBondOption(Option::Type type,
77                                 Real strike,
78                                 Time maturity,
79                                 Time bondMaturity) const;
80 
81         Real swaption(const Swaption::arguments& arguments,
82                       Rate fixedRate,
83                       Real range,
84                       Size intervals) const;
85 
discount(Time t) const86         DiscountFactor discount(Time t) const {
87             return termStructure()->discount(t);
88         }
89 
a() const90         Real a() const { return a_(0.0); }
sigma() const91         Real sigma() const { return sigma_(0.0); }
b() const92         Real b() const { return b_(0.0); }
eta() const93         Real eta() const { return eta_(0.0); }
rho() const94         Real rho() const { return rho_(0.0); }
95 
96       protected:
97         void generateArguments();
98 
99         Real A(Time t, Time T) const;
100         Real B(Real x, Time t) const;
101 
102       private:
103         class Dynamics;
104         class FittingParameter;
105 
106         Real sigmaP(Time t, Time s) const;
107 
108         Parameter& a_;
109         Parameter& sigma_;
110         Parameter& b_;
111         Parameter& eta_;
112         Parameter& rho_;
113 
114         Parameter phi_;
115 
116         Real V(Time t) const;
117 
118         class SwaptionPricingFunction;
119         friend class SwaptionPricingFunction;
120     };
121 
122     class G2::Dynamics : public TwoFactorModel::ShortRateDynamics {
123       public:
Dynamics(const Parameter & fitting,Real a,Real sigma,Real b,Real eta,Real rho)124         Dynamics(const Parameter& fitting,
125                  Real a,
126                  Real sigma,
127                  Real b,
128                  Real eta,
129                  Real rho)
130         : ShortRateDynamics(ext::shared_ptr<StochasticProcess1D>(
131                                       new OrnsteinUhlenbeckProcess(a, sigma)),
132                             ext::shared_ptr<StochasticProcess1D>(
133                                       new OrnsteinUhlenbeckProcess(b, eta)),
134                             rho),
135           fitting_(fitting) {}
shortRate(Time t,Real x,Real y) const136         virtual Rate shortRate(Time t,
137                                Real x,
138                                Real y) const {
139             return fitting_(t) + x + y;
140         }
141       private:
142         Parameter fitting_;
143     };
144 
145     //! Analytical term-structure fitting parameter \f$ \varphi(t) \f$.
146     /*! \f$ \varphi(t) \f$ is analytically defined by
147         \f[
148             \varphi(t) = f(t) +
149                  \frac{1}{2}(\frac{\sigma(1-e^{-at})}{a})^2 +
150                  \frac{1}{2}(\frac{\eta(1-e^{-bt})}{b})^2 +
151                  \rho\frac{\sigma(1-e^{-at})}{a}\frac{\eta(1-e^{-bt})}{b},
152         \f]
153         where \f$ f(t) \f$ is the instantaneous forward rate at \f$ t \f$.
154     */
155     class G2::FittingParameter : public TermStructureFittingParameter {
156       private:
157         class Impl : public Parameter::Impl {
158           public:
Impl(const Handle<YieldTermStructure> & termStructure,Real a,Real sigma,Real b,Real eta,Real rho)159             Impl(const Handle<YieldTermStructure>& termStructure,
160                  Real a,
161                  Real sigma,
162                  Real b,
163                  Real eta,
164                  Real rho)
165             : termStructure_(termStructure),
166               a_(a), sigma_(sigma), b_(b), eta_(eta), rho_(rho) {}
167 
value(const Array &,Time t) const168             Real value(const Array&, Time t) const {
169                 Rate forward = termStructure_->forwardRate(t, t,
170                                                            Continuous,
171                                                            NoFrequency);
172                 Real temp1 = sigma_*(1.0-std::exp(-a_*t))/a_;
173                 Real temp2 = eta_*(1.0-std::exp(-b_*t))/b_;
174                 Real value = 0.5*temp1*temp1 + 0.5*temp2*temp2 +
175                     rho_*temp1*temp2 + forward;
176                 return value;
177             }
178 
179           private:
180             Handle<YieldTermStructure> termStructure_;
181             Real a_, sigma_, b_, eta_, rho_;
182         };
183       public:
FittingParameter(const Handle<YieldTermStructure> & termStructure,Real a,Real sigma,Real b,Real eta,Real rho)184         FittingParameter(const Handle<YieldTermStructure>& termStructure,
185                          Real a,
186                          Real sigma,
187                          Real b,
188                          Real eta,
189                          Real rho)
190         : TermStructureFittingParameter(ext::shared_ptr<Parameter::Impl>(
191                           new FittingParameter::Impl(termStructure, a, sigma,
192                                                      b, eta, rho))) {}
193     };
194 
195 }
196 
197 
198 #endif
199 
200