MOOS 0.2375
|
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