| 1 |  | 
|---|
| 2 | #define WANT_STREAM | 
|---|
| 3 | #define WANT_MATH | 
|---|
| 4 | #define WANT_FSTREAM | 
|---|
| 5 |  | 
|---|
| 6 | #include "newmatap.h" | 
|---|
| 7 | #include "newmatio.h" | 
|---|
| 8 | #include "newmatnl.h" | 
|---|
| 9 |  | 
|---|
| 10 | #ifdef use_namespace | 
|---|
| 11 | using namespace RBD_LIBRARIES; | 
|---|
| 12 | #endif | 
|---|
| 13 |  | 
|---|
| 14 | // This is a demonstration of a special case of the Garch model | 
|---|
| 15 | // Observe two series X and Y of length n | 
|---|
| 16 | // and suppose | 
|---|
| 17 | //    Y(i) = beta * X(i) + epsilon(i) | 
|---|
| 18 | // where epsilon(i) is normally distributed with zero mean and variance = | 
|---|
| 19 | //    h(i) = alpha0 + alpha1 * square(epsilon(i-1)) + beta1 * h(i-1). | 
|---|
| 20 | // Then this program is supposed to estimate beta, alpha0, alpha1, beta1 | 
|---|
| 21 | // The Garch model is supposed to model something like an instability | 
|---|
| 22 | // in the stock or options market following an unexpected result. | 
|---|
| 23 | // alpha1 determines the size of the instability and beta1 determines how | 
|---|
| 24 | // quickly is dies away. | 
|---|
| 25 | // We should, at least, have an X of several columns and beta as a vector | 
|---|
| 26 |  | 
|---|
| 27 | inline Real square(Real x) { return x*x; } | 
|---|
| 28 |  | 
|---|
| 29 | // the class that defines the GARCH log-likelihood | 
|---|
| 30 |  | 
|---|
| 31 | class GARCH11_LL : public LL_D_FI | 
|---|
| 32 | { | 
|---|
| 33 |    ColumnVector Y;                 // Y values | 
|---|
| 34 |    ColumnVector X;                 // X values | 
|---|
| 35 |    ColumnVector D;                 // derivatives of loglikelihood | 
|---|
| 36 |    SymmetricMatrix D2;             // - approximate second derivatives | 
|---|
| 37 |    int n;                          // number of observations | 
|---|
| 38 |    Real beta, alpha0, alpha1, beta1; | 
|---|
| 39 |                                    // the parameters | 
|---|
| 40 |  | 
|---|
| 41 | public: | 
|---|
| 42 |  | 
|---|
| 43 |    GARCH11_LL(const ColumnVector& y, const ColumnVector& x) | 
|---|
| 44 |       : Y(y), X(x), n(y.Nrows()) {} | 
|---|
| 45 |                                    // constructor - load Y and X values | 
|---|
| 46 |  | 
|---|
| 47 |    void Set(const ColumnVector& p) // set parameter values | 
|---|
| 48 |    { | 
|---|
| 49 |       para = p; | 
|---|
| 50 |       beta = para(1); alpha0 = para(2); | 
|---|
| 51 |       alpha1 = para(3); beta1 = para(4); | 
|---|
| 52 |    } | 
|---|
| 53 |  | 
|---|
| 54 |    bool IsValid();                 // are parameters valid | 
|---|
| 55 |    Real LogLikelihood();           // return the loglikelihood | 
|---|
| 56 |    ReturnMatrix Derivatives();     // derivatives of log-likelihood | 
|---|
| 57 |    ReturnMatrix FI();              // Fisher Information matrix | 
|---|
| 58 | }; | 
|---|
| 59 |  | 
|---|
| 60 | bool GARCH11_LL::IsValid() | 
|---|
| 61 | { return alpha0>0 && alpha1>0 && beta1>0 && (alpha1+beta1)<1.0; } | 
|---|
| 62 |  | 
|---|
| 63 | Real GARCH11_LL::LogLikelihood() | 
|---|
| 64 | { | 
|---|
| 65 | //   cout << endl << "                           "; | 
|---|
| 66 | //   cout << setw(10) << setprecision(5) << beta; | 
|---|
| 67 | //   cout << setw(10) << setprecision(5) << alpha0; | 
|---|
| 68 | //   cout << setw(10) << setprecision(5) << alpha1; | 
|---|
| 69 | //   cout << setw(10) << setprecision(5) << beta1; | 
|---|
| 70 | //   cout << endl; | 
|---|
| 71 |    ColumnVector H(n);              // residual variances | 
|---|
| 72 |    ColumnVector U = Y - X * beta;  // the residuals | 
|---|
| 73 |    ColumnVector LH(n);     // derivative of log-likelihood wrt H | 
|---|
| 74 |                            // each row corresponds to one observation | 
|---|
| 75 |    LH(1)=0; | 
|---|
| 76 |    Matrix Hderiv(n,4);     // rectangular matrix of derivatives | 
|---|
| 77 |                            // of H wrt parameters | 
|---|
| 78 |                            // each row corresponds to one observation | 
|---|
| 79 |                            // each column to one of the parameters | 
|---|
| 80 |  | 
|---|
| 81 |    // Regard Y(1) as fixed and don't include in likelihood | 
|---|
| 82 |    // then put in an expected value of H(1) in place of actual value | 
|---|
| 83 |    //   which we don't know. Use | 
|---|
| 84 |    // E{H(i)} = alpha0 + alpha1 * E{square(epsilon(i-1))} + beta1 * E{H(i-1)} | 
|---|
| 85 |    // and  E{square(epsilon(i-1))} = E{H(i-1)} = E{H(i)} | 
|---|
| 86 |    Real denom = (1-alpha1-beta1); | 
|---|
| 87 |    H(1) = alpha0/denom;    // the expected value of H | 
|---|
| 88 |    Hderiv(1,1) = 0; | 
|---|
| 89 |    Hderiv(1,2) = 1.0 / denom; | 
|---|
| 90 |    Hderiv(1,3) = alpha0 / square(denom); | 
|---|
| 91 |    Hderiv(1,4) = Hderiv(1,3); | 
|---|
| 92 |    Real LL = 0.0;          // the log likelihood | 
|---|
| 93 |    Real sum1 = 0;          // for forming derivative wrt beta | 
|---|
| 94 |    Real sum2 = 0;          // for forming second derivative wrt beta | 
|---|
| 95 |    for (int i=2; i<=n; i++) | 
|---|
| 96 |    { | 
|---|
| 97 |       Real u1 = U(i-1); Real h1 = H(i-1); | 
|---|
| 98 |       Real h = alpha0 + alpha1*square(u1) + beta1*h1; // variance of this obsv. | 
|---|
| 99 |       H(i) = h; Real u = U(i); | 
|---|
| 100 |       LL += log(h) + square(u) / h;        // -2 * log likelihood | 
|---|
| 101 |       // Hderiv are derivatives of h with respect to the parameters | 
|---|
| 102 |       // need to allow for h1 depending on parameters | 
|---|
| 103 |       Hderiv(i,1) = -2*u1*alpha1*X(i-1) + beta1*Hderiv(i-1,1);  // beta | 
|---|
| 104 |       Hderiv(i,2) = 1 + beta1*Hderiv(i-1,2);                    // alpha0 | 
|---|
| 105 |       Hderiv(i,3) = square(u1) + beta1*Hderiv(i-1,3);           // alpha1 | 
|---|
| 106 |       Hderiv(i,4) = h1 + beta1*Hderiv(i-1,4);                   // beta1 | 
|---|
| 107 |       LH(i) = -0.5 * (1/h - square(u/h)); | 
|---|
| 108 |       sum1 += u * X(i)/ h; | 
|---|
| 109 |       sum2 += square(X(i)) / h; | 
|---|
| 110 |    } | 
|---|
| 111 |    D = Hderiv.t()*LH;         // derivatives of likelihood wrt parameters | 
|---|
| 112 |    D(1) += sum1;              // add on deriv wrt beta from square(u) term | 
|---|
| 113 | //   cout << setw(10) << setprecision(5) << D << endl; | 
|---|
| 114 |  | 
|---|
| 115 |    // do minus expected value of second derivatives | 
|---|
| 116 |    if (wg)                    // do only if second derivatives wanted | 
|---|
| 117 |    { | 
|---|
| 118 |       Hderiv.Row(1) = 0.0; | 
|---|
| 119 |       Hderiv = H.AsDiagonal().i() * Hderiv; | 
|---|
| 120 |       D2 << Hderiv.t() * Hderiv;  D2 = D2 / 2.0; | 
|---|
| 121 |       D2(1,1) += sum2; | 
|---|
| 122 | //      cout << setw(10) << setprecision(5) << D2 << endl; | 
|---|
| 123 | //      DiagonalMatrix DX; EigenValues(D2,DX); | 
|---|
| 124 | //      cout << setw(10) << setprecision(5) << DX << endl; | 
|---|
| 125 |  | 
|---|
| 126 |    } | 
|---|
| 127 |    return -0.5 * LL; | 
|---|
| 128 | } | 
|---|
| 129 |  | 
|---|
| 130 | ReturnMatrix GARCH11_LL::Derivatives() | 
|---|
| 131 | { return D; } | 
|---|
| 132 |  | 
|---|
| 133 | ReturnMatrix GARCH11_LL::FI() | 
|---|
| 134 | { | 
|---|
| 135 |    if (!wg) cout << endl << "unexpected call of FI" << endl; | 
|---|
| 136 |    return D2; | 
|---|
| 137 | } | 
|---|
| 138 |  | 
|---|
| 139 |  | 
|---|
| 140 |  | 
|---|
| 141 | int main() | 
|---|
| 142 | { | 
|---|
| 143 |    // get data | 
|---|
| 144 |    ifstream fin("garch.dat"); | 
|---|
| 145 |    if (!fin) { cout << "cannot find garch.dat\n"; exit(1); } | 
|---|
| 146 |    int n; fin >> n;            // series length | 
|---|
| 147 |    // Y contains the dependant variable, X the predictor variable | 
|---|
| 148 |    ColumnVector Y(n), X(n); | 
|---|
| 149 |    int i; | 
|---|
| 150 |    for (i=1; i<=n; i++) fin >> Y(i) >> X(i); | 
|---|
| 151 |    cout << "Read " << n << " data points - begin fit\n\n"; | 
|---|
| 152 |    // now do the fit | 
|---|
| 153 |    ColumnVector H(n); | 
|---|
| 154 |    GARCH11_LL garch11(Y,X);                  // loglikehood "object" | 
|---|
| 155 |    MLE_D_FI mle_d_fi(garch11,100,0.0001);    // mle "object" | 
|---|
| 156 |    ColumnVector Para(4);                     // to hold the parameters | 
|---|
| 157 |    Para << 0.0 << 0.1 << 0.1 << 0.1;         // starting values | 
|---|
| 158 |       // (Should change starting values to a more intelligent formula) | 
|---|
| 159 |    mle_d_fi.Fit(Para);                       // do the fit | 
|---|
| 160 |    ColumnVector SE; | 
|---|
| 161 |    mle_d_fi.GetStandardErrors(SE); | 
|---|
| 162 |    cout << "\n\n"; | 
|---|
| 163 |    cout << "estimates and standard errors\n"; | 
|---|
| 164 |    cout << setw(15) << setprecision(5) << (Para | SE) << endl << endl; | 
|---|
| 165 |    SymmetricMatrix Corr; | 
|---|
| 166 |    mle_d_fi.GetCorrelations(Corr); | 
|---|
| 167 |    cout << "correlation matrix\n"; | 
|---|
| 168 |    cout << setw(10) << setprecision(2) << Corr << endl << endl; | 
|---|
| 169 |    cout << "inverse of correlation matrix\n"; | 
|---|
| 170 |    cout << setw(10) << setprecision(2) << Corr.i() << endl << endl; | 
|---|
| 171 |    return 0; | 
|---|
| 172 | } | 
|---|
| 173 |  | 
|---|
| 174 |  | 
|---|
| 175 |  | 
|---|