garch.cc
Go to the documentation of this file.
00001 
00002 #define WANT_STREAM
00003 #define WANT_MATH
00004 #define WANT_FSTREAM
00005 
00006 #include "newmatap.h"
00007 #include "newmatio.h"
00008 #include "newmatnl.h"
00009 
00010 #ifdef use_namespace
00011 using namespace RBD_LIBRARIES;
00012 #endif
00013 
00014 // This is a demonstration of a special case of the Garch model
00015 // Observe two series X and Y of length n
00016 // and suppose
00017 //    Y(i) = beta * X(i) + epsilon(i)
00018 // where epsilon(i) is normally distributed with zero mean and variance =
00019 //    h(i) = alpha0 + alpha1 * square(epsilon(i-1)) + beta1 * h(i-1).
00020 // Then this program is supposed to estimate beta, alpha0, alpha1, beta1
00021 // The Garch model is supposed to model something like an instability
00022 // in the stock or options market following an unexpected result.
00023 // alpha1 determines the size of the instability and beta1 determines how
00024 // quickly is dies away.
00025 // We should, at least, have an X of several columns and beta as a vector
00026 
00027 inline Real square(Real x) { return x*x; }
00028 
00029 // the class that defines the GARCH log-likelihood
00030 
00031 class GARCH11_LL : public LL_D_FI
00032 {
00033    ColumnVector Y;                 // Y values
00034    ColumnVector X;                 // X values
00035    ColumnVector D;                 // derivatives of loglikelihood
00036    SymmetricMatrix D2;             // - approximate second derivatives
00037    int n;                          // number of observations
00038    Real beta, alpha0, alpha1, beta1;
00039                                    // the parameters
00040 
00041 public:
00042 
00043    GARCH11_LL(const ColumnVector& y, const ColumnVector& x)
00044       : Y(y), X(x), n(y.Nrows()) {}
00045                                    // constructor - load Y and X values
00046 
00047    void Set(const ColumnVector& p) // set parameter values
00048    {
00049       para = p;
00050       beta = para(1); alpha0 = para(2);
00051       alpha1 = para(3); beta1 = para(4);
00052    }
00053 
00054    bool IsValid();                 // are parameters valid
00055    Real LogLikelihood();           // return the loglikelihood
00056    ReturnMatrix Derivatives();     // derivatives of log-likelihood
00057    ReturnMatrix FI();              // Fisher Information matrix
00058 };
00059 
00060 bool GARCH11_LL::IsValid()
00061 { return alpha0>0 && alpha1>0 && beta1>0 && (alpha1+beta1)<1.0; }
00062 
00063 Real GARCH11_LL::LogLikelihood()
00064 {
00065 //   cout << endl << "                           ";
00066 //   cout << setw(10) << setprecision(5) << beta;
00067 //   cout << setw(10) << setprecision(5) << alpha0;
00068 //   cout << setw(10) << setprecision(5) << alpha1;
00069 //   cout << setw(10) << setprecision(5) << beta1;
00070 //   cout << endl;
00071    ColumnVector H(n);              // residual variances
00072    ColumnVector U = Y - X * beta;  // the residuals
00073    ColumnVector LH(n);     // derivative of log-likelihood wrt H
00074                            // each row corresponds to one observation
00075    LH(1)=0;
00076    Matrix Hderiv(n,4);     // rectangular matrix of derivatives
00077                            // of H wrt parameters
00078                            // each row corresponds to one observation
00079                            // each column to one of the parameters
00080 
00081    // Regard Y(1) as fixed and don't include in likelihood
00082    // then put in an expected value of H(1) in place of actual value
00083    //   which we don't know. Use
00084    // E{H(i)} = alpha0 + alpha1 * E{square(epsilon(i-1))} + beta1 * E{H(i-1)}
00085    // and  E{square(epsilon(i-1))} = E{H(i-1)} = E{H(i)}
00086    Real denom = (1-alpha1-beta1);
00087    H(1) = alpha0/denom;    // the expected value of H
00088    Hderiv(1,1) = 0;
00089    Hderiv(1,2) = 1.0 / denom;
00090    Hderiv(1,3) = alpha0 / square(denom);
00091    Hderiv(1,4) = Hderiv(1,3);
00092    Real LL = 0.0;          // the log likelihood
00093    Real sum1 = 0;          // for forming derivative wrt beta
00094    Real sum2 = 0;          // for forming second derivative wrt beta
00095    for (int i=2; i<=n; i++)
00096    {
00097       Real u1 = U(i-1); Real h1 = H(i-1);
00098       Real h = alpha0 + alpha1*square(u1) + beta1*h1; // variance of this obsv.
00099       H(i) = h; Real u = U(i);
00100       LL += log(h) + square(u) / h;        // -2 * log likelihood
00101       // Hderiv are derivatives of h with respect to the parameters
00102       // need to allow for h1 depending on parameters
00103       Hderiv(i,1) = -2*u1*alpha1*X(i-1) + beta1*Hderiv(i-1,1);  // beta
00104       Hderiv(i,2) = 1 + beta1*Hderiv(i-1,2);                    // alpha0
00105       Hderiv(i,3) = square(u1) + beta1*Hderiv(i-1,3);           // alpha1
00106       Hderiv(i,4) = h1 + beta1*Hderiv(i-1,4);                   // beta1
00107       LH(i) = -0.5 * (1/h - square(u/h));
00108       sum1 += u * X(i)/ h;
00109       sum2 += square(X(i)) / h;
00110    }
00111    D = Hderiv.t()*LH;         // derivatives of likelihood wrt parameters
00112    D(1) += sum1;              // add on deriv wrt beta from square(u) term
00113 //   cout << setw(10) << setprecision(5) << D << endl;
00114 
00115    // do minus expected value of second derivatives
00116    if (wg)                    // do only if second derivatives wanted
00117    {
00118       Hderiv.Row(1) = 0.0;
00119       Hderiv = H.AsDiagonal().i() * Hderiv;
00120       D2 << Hderiv.t() * Hderiv;  D2 = D2 / 2.0;
00121       D2(1,1) += sum2;
00122 //      cout << setw(10) << setprecision(5) << D2 << endl;
00123 //      DiagonalMatrix DX; EigenValues(D2,DX);
00124 //      cout << setw(10) << setprecision(5) << DX << endl;
00125 
00126    }
00127    return -0.5 * LL;
00128 }
00129 
00130 ReturnMatrix GARCH11_LL::Derivatives()
00131 { return D; }
00132 
00133 ReturnMatrix GARCH11_LL::FI()
00134 {
00135    if (!wg) cout << endl << "unexpected call of FI" << endl;
00136    return D2;
00137 }
00138 
00139 
00140 
00141 int main()
00142 {
00143    // get data
00144    ifstream fin("garch.dat");
00145    if (!fin) { cout << "cannot find garch.dat\n"; exit(1); }
00146    int n; fin >> n;            // series length
00147    // Y contains the dependant variable, X the predictor variable
00148    ColumnVector Y(n), X(n);
00149    int i;
00150    for (i=1; i<=n; i++) fin >> Y(i) >> X(i);
00151    cout << "Read " << n << " data points - begin fit\n\n";
00152    // now do the fit
00153    ColumnVector H(n);
00154    GARCH11_LL garch11(Y,X);                  // loglikehood "object"
00155    MLE_D_FI mle_d_fi(garch11,100,0.0001);    // mle "object"
00156    ColumnVector Para(4);                     // to hold the parameters
00157    Para << 0.0 << 0.1 << 0.1 << 0.1;         // starting values
00158       // (Should change starting values to a more intelligent formula)
00159    mle_d_fi.Fit(Para);                       // do the fit
00160    ColumnVector SE;
00161    mle_d_fi.GetStandardErrors(SE);
00162    cout << "\n\n";
00163    cout << "estimates and standard errors\n";
00164    cout << setw(15) << setprecision(5) << (Para | SE) << endl << endl;
00165    SymmetricMatrix Corr;
00166    mle_d_fi.GetCorrelations(Corr);
00167    cout << "correlation matrix\n";
00168    cout << setw(10) << setprecision(2) << Corr << endl << endl;
00169    cout << "inverse of correlation matrix\n";
00170    cout << setw(10) << setprecision(2) << Corr.i() << endl << endl;
00171    return 0;
00172 }
00173 
00174 
00175 


rl_agent
Author(s): Todd Hester
autogenerated on Thu Jun 6 2019 22:00:13