/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2001, 2002, 2003 Sadruddin Rejeb Copyright (C) 2004 Mike Parker This file is part of QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ QuantLib is free software: you can redistribute it and/or modify it under the terms of the QuantLib license. You should have received a copy of the license along with this program; if not, please email . The license is also available online at . This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ #include #include #include #include #include namespace QuantLib { G2::G2(const Handle& termStructure, Real a, Real sigma, Real b, Real eta, Real rho) : TwoFactorModel(5), TermStructureConsistentModel(termStructure), a_(arguments_[0]), sigma_(arguments_[1]), b_(arguments_[2]), eta_(arguments_[3]), rho_(arguments_[4]) { a_ = ConstantParameter(a, PositiveConstraint()); sigma_ = ConstantParameter(sigma, PositiveConstraint()); b_ = ConstantParameter(b, PositiveConstraint()); eta_ = ConstantParameter(eta, PositiveConstraint()); rho_ = ConstantParameter(rho, BoundaryConstraint(-1.0, 1.0)); generateArguments(); registerWith(termStructure); } boost::shared_ptr G2::dynamics() const { return boost::shared_ptr(new Dynamics(phi_, a(), sigma(), b(), eta(), rho())); } void G2::generateArguments() { phi_ = FittingParameter(termStructure(), a(), sigma(), b(), eta(), rho()); } Real G2::sigmaP(Time t, Time s) const { Real temp = 1.0 - std::exp(-(a()+b())*t); Real temp1 = 1.0 - std::exp(-a()*(s-t)); Real temp2 = 1.0 - std::exp(-b()*(s-t)); Real a3 = a()*a()*a(); Real b3 = b()*b()*b(); Real sigma2 = sigma()*sigma(); Real eta2 = eta()*eta(); Real value = 0.5*sigma2*temp1*temp1*(1.0 - std::exp(-2.0*a()*t))/a3 + 0.5*eta2*temp2*temp2*(1.0 - std::exp(-2.0*b()*t))/b3 + 2.0*rho()*sigma()*eta()/(a()*b()*(a()+b()))* temp1*temp2*temp; return std::sqrt(value); } Real G2::discountBond(Time t, Time T, Real x, Real y) const { return A(t,T) * std::exp(-B(a(),(T-t))*x-B(b(),(T-t))*y); } Real G2::discountBondOption(Option::Type type, Real strike, Time maturity, Time bondMaturity) const { Real v = sigmaP(maturity, bondMaturity); Real f = termStructure()->discount(bondMaturity); Real k = termStructure()->discount(maturity)*strike; return blackFormula(type, k, f, v); } Real G2::V(Time t) const { Real expat = std::exp(-a()*t); Real expbt = std::exp(-b()*t); Real cx = sigma()/a(); Real cy = eta()/b(); Real valuex = cx*cx*(t + (2.0*expat-0.5*expat*expat-1.5)/a()); Real valuey = cy*cy*(t + (2.0*expbt-0.5*expbt*expbt-1.5)/b()); Real value = 2.0*rho()*cx*cy* (t + (expat - 1.0)/a() + (expbt - 1.0)/b() - (expat*expbt-1.0)/(a()+b())); return valuex + valuey + value; } Real G2::A(Time t, Time T) const { return termStructure()->discount(T)/termStructure()->discount(t)* std::exp(0.5*(V(T-t) - V(T) + V(t))); } Real G2::B(Real x, Time t) const { return (1.0 - std::exp(-x*t))/x; } class G2::SwaptionPricingFunction { public: SwaptionPricingFunction(Real a, Real sigma, Real b, Real eta, Real rho, Real w, Real start, const std::vector