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