File: onefactormodel.cpp

package info (click to toggle)
quantlib 0.2.1.cvs20020322-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 4,716 kB
  • ctags: 4,614
  • sloc: cpp: 19,601; sh: 7,389; makefile: 796; ansic: 22
file content (124 lines) | stat: -rw-r--r-- 4,673 bytes parent folder | download
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());
        }

    }

}