📄 garch.cpp
字号:
#define WANT_STREAM#define WANT_MATH#include "newmatap.h"#include "newmatio.h"#include "newmatnl.h"#include <fstream.h>#ifdef use_namespaceusing namespace RBD_LIBRARIES;#endif// This is a demonstration of a special case of the Garch model// Observe two series X and Y of length n// and suppose// Y(i) = beta * X(i) + epsilon(i)// where epsilon(i) is normally distributed with zero mean and variance =// h(i) = alpha0 + alpha1 * square(epsilon(i-1)) + beta1 * h(i-1).// Then this program is supposed to estimate beta, alpha0, alpha1, beta1// The Garch model is supposed to model something like an instability// in the stock or options market following an unexpected result.// alpha1 determines the size of the instability and beta1 determines how// quickly is dies away.// We should, at least, have an X of several columns and beta as a vectorinline Real square(Real x) { return x*x; }// the class that defines the GARCH log-likelihoodclass GARCH11_LL : public LL_D_FI{ ColumnVector Y; // Y values ColumnVector X; // X values ColumnVector D; // derivatives of loglikelihood SymmetricMatrix D2; // - approximate second derivatives int n; // number of observations Real beta, alpha0, alpha1, beta1; // the parameterspublic: GARCH11_LL(const ColumnVector& y, const ColumnVector& x) : Y(y), X(x), n(y.Nrows()) {} // constructor - load Y and X values void Set(const ColumnVector& p) // set parameter values { para = p; beta = para(1); alpha0 = para(2); alpha1 = para(3); beta1 = para(4); } bool IsValid(); // are parameters valid Real LogLikelihood(); // return the loglikelihood ReturnMatrix Derivatives(); // derivatives of log-likelihood ReturnMatrix FI(); // Fisher Information matrix};bool GARCH11_LL::IsValid(){ return alpha0>0 && alpha1>0 && beta1>0 && (alpha1+beta1)<1.0; }Real GARCH11_LL::LogLikelihood(){// cout << endl << " ";// cout << setw(10) << setprecision(5) << beta;// cout << setw(10) << setprecision(5) << alpha0;// cout << setw(10) << setprecision(5) << alpha1;// cout << setw(10) << setprecision(5) << beta1;// cout << endl; ColumnVector H(n); // residual variances ColumnVector U = Y - X * beta; // the residuals ColumnVector LH(n); // derivative of log-likelihood wrt H // each row corresponds to one observation LH(1)=0; Matrix Hderiv(n,4); // rectangular matrix of derivatives // of H wrt parameters // each row corresponds to one observation // each column to one of the parameters // Regard Y(1) as fixed and don't include in likelihood // then put in an expected value of H(1) in place of actual value // which we don't know. Use // E{H(i)} = alpha0 + alpha1 * E{square(epsilon(i-1))} + beta1 * E{H(i-1)} // and E{square(epsilon(i-1))} = E{H(i-1)} = E{H(i)} Real denom = (1-alpha1-beta1); H(1) = alpha0/denom; // the expected value of H Hderiv(1,1) = 0; Hderiv(1,2) = 1.0 / denom; Hderiv(1,3) = alpha0 / square(denom); Hderiv(1,4) = Hderiv(1,3); Real LL = 0.0; // the log likelihood Real sum1 = 0; // for forming derivative wrt beta Real sum2 = 0; // for forming second derivative wrt beta for (int i=2; i<=n; i++) { Real u1 = U(i-1); Real h1 = H(i-1); Real h = alpha0 + alpha1*square(u1) + beta1*h1; // variance of this obsv. H(i) = h; Real u = U(i); LL += log(h) + square(u) / h; // -2 * log likelihood // Hderiv are derivatives of h with respect to the parameters // need to allow for h1 depending on parameters Hderiv(i,1) = -2*u1*alpha1*X(i-1) + beta1*Hderiv(i-1,1); // beta Hderiv(i,2) = 1 + beta1*Hderiv(i-1,2); // alpha0 Hderiv(i,3) = square(u1) + beta1*Hderiv(i-1,3); // alpha1 Hderiv(i,4) = h1 + beta1*Hderiv(i-1,4); // beta1 LH(i) = -0.5 * (1/h - square(u/h)); sum1 += u * X(i)/ h; sum2 += square(X(i)) / h; } D = Hderiv.t()*LH; // derivatives of likelihood wrt parameters D(1) += sum1; // add on deriv wrt beta from square(u) term// cout << setw(10) << setprecision(5) << D << endl; // do minus expected value of second derivatives if (wg) // do only if second derivatives wanted { Hderiv.Row(1) = 0.0; Hderiv = H.AsDiagonal().i() * Hderiv; D2 << Hderiv.t() * Hderiv; D2 = D2 / 2.0; D2(1,1) += sum2;// cout << setw(10) << setprecision(5) << D2 << endl;// DiagonalMatrix DX; EigenValues(D2,DX);// cout << setw(10) << setprecision(5) << DX << endl; } return -0.5 * LL;}ReturnMatrix GARCH11_LL::Derivatives(){ return D; }ReturnMatrix GARCH11_LL::FI(){ if (!wg) cout << endl << "unexpected call of FI" << endl; return D2;}int main(){ // get data ifstream fin("garch.dat"); if (!fin) { cout << "cannot find garch.dat\n"; exit(1); } int n; fin >> n; // series length // Y contains the dependant variable, X the predictor variable ColumnVector Y(n), X(n); int i; for (i=1; i<=n; i++) fin >> Y(i) >> X(i); cout << "Read " << n << " data points - begin fit\n\n"; // now do the fit ColumnVector H(n); GARCH11_LL garch11(Y,X); // loglikehood "object" MLE_D_FI mle_d_fi(garch11,100,0.0001); // mle "object" ColumnVector Para(4); // to hold the parameters Para << 0.0 << 0.1 << 0.1 << 0.1; // starting values // (Should change starting values to a more intelligent formula) mle_d_fi.Fit(Para); // do the fit ColumnVector SE; mle_d_fi.GetStandardErrors(SE); cout << "\n\n"; cout << "estimates and standard errors\n"; cout << setw(15) << setprecision(5) << (Para | SE) << endl << endl; SymmetricMatrix Corr; mle_d_fi.GetCorrelations(Corr); cout << "correlation matrix\n"; cout << setw(10) << setprecision(2) << Corr << endl << endl; cout << "inverse of correlation matrix\n"; cout << setw(10) << setprecision(2) << Corr.i() << endl << endl; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -