1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
/*
Copyright (C) 2001, 2002 Sadruddin Rejeb
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 ferdinando@ametrano.net
The license is also available online at http://quantlib.org/html/license.html
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.
*/
/*! \file onefactormodel.cpp
\brief Abstract one-factor interest rate model class
\fullpath
ql/InterestRateModelling/%onefactormodel.cpp
*/
// $Id: onefactormodel.cpp,v 1.13 2002/03/05 01:10:37 sadrejeb Exp $
#include "ql/InterestRateModelling/onefactormodel.hpp"
#include "ql/Lattices/trinomialtree.hpp"
#include "ql/Solvers1D/brent.hpp"
namespace QuantLib {
namespace InterestRateModelling {
using Optimization::Constraint;
class OneFactorModel::StandardConstraint : public Constraint {
virtual bool test(const Array& params) const {
if (params[params.size()-1] > 0.0)
return true;
else
return false;
}
virtual void correct(Array& params) const {
if (!test(params))
params[params.size()-1] = 0.000001;
}
};
//Private function used by solver to determine time-dependent parameter
class OneFactorModel::OwnTrinomialTree::Helper
: public ObjectiveFunction {
public:
Helper(
Time t, Time dt, double dx,
int jMin, int jMax,
const std::vector<double>& statePrices,
double discountBondPrice,
const Handle<ShortRateProcess>& process,
const
Handle<TermStructureFittingParameter::NumericalImpl>& theta)
: t_(t), dt_(dt), dx_(dx),
jMin_(jMin), jMax_(jMax),
statePrices_(statePrices),
discountBondPrice_(discountBondPrice),
process_(process), theta_(theta) {
theta_->set(t, 0.0);
}
double operator()(double theta) const {
double value = discountBondPrice_;
theta_->change(theta);
Size k=0;
double x = process_->x0() + jMin_*dx_;
for (int j=jMin_; j<=jMax_; j++, k++) {
Rate r = process_->shortRate(t_, x);
value -= statePrices_[k]*QL_EXP(-r*dt_);
x += dx_;
}
return value;
}
private:
Time t_, dt_;
double dx_;
int jMin_, jMax_;
const std::vector<double>& statePrices_;
double discountBondPrice_;
Handle<ShortRateProcess> process_;
Handle<TermStructureFittingParameter::NumericalImpl> theta_;
};
OneFactorModel::OwnTrinomialTree::OwnTrinomialTree(
const Handle<ShortRateProcess>& process,
const Handle<TermStructureFittingParameter::NumericalImpl>& theta,
const TimeGrid& timeGrid,
bool isPositive)
: Lattices::TrinomialTree(process, timeGrid, isPositive),
process_(process) {
theta->reset();
for (Size i=0; i<(timeGrid.size() - 1); i++) {
double discountBond = theta->termStructure()->discount(t(i+1));
std::vector<double> statePrices(0);
for (int j=jMin(i); j<=jMax(i); j++)
statePrices.push_back(node(i,j).statePrice());
Helper finder(t(i), dt(i), dx(i), jMin(i), jMax(i),
statePrices, discountBond, process_, theta);
Solvers1D::Brent s1d = Solvers1D::Brent();
s1d.setMaxEvaluations(1000);
double value = s1d.solve(finder, 1e-6, 1.0, -50.0, 50.0);
theta->change(value);
computeStatePrices(i+1);
}
}
OneFactorModel::OneFactorModel(
Size nParameters,
const RelinkableHandle<TermStructure>& termStructure)
: Model(nParameters, termStructure) {
constraint_ = Handle<Constraint>(new StandardConstraint());
}
}
}
|