Path: blob/master/sandbox/paper_analysis/insample/estimationfunctions.R
1433 views
1#-----------------------------------------------------------2# General functions3#-----------------------------------------------------------45vech <- function(x){6t(x[!upper.tri(x)])7}89lvech <- function(x){10t(x[!upper.tri(x, diag = T)])11}1213#-----------------------------------------------------------14# Functions for the GARCH estimation15#-----------------------------------------------------------1617hatsigma <- function( par , x ,uncH){18# see: code underlying fGarch package of Chalaby and Wuertz19alpha = par[1] ; beta = par[2];20omega = uncH*(1-alpha-beta)21s2 = rep( uncH , T )22e2 <- x^223e2t <- omega + alpha*c(mean(e2),e2[-length(x)])24s2 <- filter(e2t, beta, "recursive", init = uncH )25return(s2)26}2728llhGarch11N <- function(par, x, uncH){29# see: code underlying fGarch package of Chalaby and Wuertz30x = as.numeric(x)31s2 = hatsigma( par = par , x = x ,uncH=uncH)32return( sum( log(s2) + x^2/s2 ))33}3435weightedvariance = function( u ){36k = qchisq(0.99,df=1) ;37jumpIndicator = ( (u/mad(u))^2<=k )38ufilt = u[jumpIndicator]39uncH = mean(ufilt^2,na.rm=TRUE)*(0.99/pchisq(k,df=3))40return(uncH)41# check: U = matrix( rnorm(500000),ncol=100) ; mean(apply(U,2,'weightedvariance'))42}434445garchVol = function( mR.centered , parN ){46S = c();47S_forecast = c();48N = ncol(mR.centered)49vuncH = apply( mR.centered , 2 , 'weightedvariance' )50for( i in 1:N ){51uncH = vuncH[i]52# do the garch estimation53# fitN <- try( nlminb(start=parN, objective=llhGarch11N , x = mR.centered[,i], lower=lowN, upper=upN,54# control=list(x.tol = 1e-8,trace=0)) )55# do the garch estimation with constraints to unsure covariance stationarity ie alpha + beta < 156fitN <- try( constrOptim( theta = parN , f = llhGarch11N , ui=rbind(c(1,0),c(0,1),c(-1,0),c(0,-1),c(-1,-1) ),57ci=c(0,0,-1,-1,-1), grad=NULL, x = mR.centered[,i], uncH=uncH) )5859LLH_constant = llhGarch11N( par=c(0,0), x=mR.centered[,i], uncH = uncH )60if( !inherits(fitN, "try-error") ){ LLH_garch = -fitN$value }else{ LLH_garch = LLH_constant }61# Likelihood ratio test statistic for the case of time-varying garch effects62# cases where garch volatility is probably not reliable or the volatility forecasts are so erratic that a constant garch works fine63useGARCHd = TRUE64if( LLH_garch=="NaN" | (fitN$par[1]>= 0.1&fitN$par[2]<=0.7) | sum(fitN$par)>=0.999 ){65LLH_garch = LLH_constant ;66useGARCHd = F;67} #volatility is too erratic68# Data is from inception: once we start using garch, we continue to ensure stability of the forecasts69# Likelihood ratio test for a time-varying vol model70if( 2*(LLH_garch-LLH_constant) <= qchisq(0.999,df=2) & (!useGARCHd) ){71sigmat = rep( sd( as.vector(mR.centered[,i])), length(mR.centered[,i]) );72S_forecast = c( S_forecast ,sqrt(uncH))73}else{74sigmat = sqrt(hatsigma( par = fitN$par , x = mR.centered[,i] , uncH=uncH ) )75lastsigmat = tail(sigmat,1)76if( lastsigmat=="NaN" | is.na(lastsigmat) ){77print( c("NaN day", d , "for asset" , i) );78sigmat = rep( sqrt(uncH) , length(mR.centered[,i]) );79# print(c("unc sd",sqrt(uncH) ))80S_forecast = c( S_forecast , sqrt(uncH) )81}else{82e2 = as.numeric(tail(mR.centered[,i],1)^2)83S_forecast = c( S_forecast ,84sqrt( uncH*(1-sum(fitN$par))+ fitN$par[1]*e2+ fitN$par[2]*lastsigmat^2 ) )85}86}87S = cbind( S , sigmat )88}89return( list(S,S_forecast) )90}9192#-----------------------------------------------------------93# Fuction for the shrinkage correlation94#-----------------------------------------------------------959697shrinkagecorrelation = function( mDevolR.centered ){98N = ncol( mDevolR.centered )99# Unconditional correlation estimate is shrinkage between sample (spearman) correlation and equicorrelation100sample = cor(mDevolR.centered,method="spearman") #make it robust by using ranks101# Elton and Gruber: same correlation across all assets102rho = mean( lvech(sample) )103I = diag( rep(1,N) ) ; J = matrix( rep(1,N^2) , ncol=N )104target = (1-rho)*I + rho*J105# The shrinkage estimate = delta*target F + (1-delta)* sample S106kappahat = shrinkage.intensity( mDevolR.centered , prior = target , sample = sample )107delta = max( 0 , min(kappahat/T,1) )108C = delta*target +(1-delta)*sample109return(C)110}111112113#-----------------------------------------------------------114# Functions for the DCC estimation115#-----------------------------------------------------------116117118DCCestimation = function( mDevolR.centered , parN , uncR ){119#fitN <- try( nlminb(start=parN, objective=loglik.dcc2.DECO , lower=lowN, upper=upN,120# control=list(x.tol = 1e-8,trace=0)) )121# Ensure covariance stationarity122N = ncol( mDevolR.centered )123I = diag( rep(1,N) ) ; J = matrix( rep(1,N^2) , ncol=N )124rho = mean( lvech(uncR) )125fitN <- try( constrOptim( theta = parN , f = loglik.dcc2.DECO , ui=rbind(c(1,0),c(0,1),c(-1,0),c(0,-1),c(-1,-1) ),126ci=c(lowN,-upN,-1), grad=NULL, uncR= uncR , mDevolR.centered=mDevolR.centered ) )127# compare with constant correlation case128LLH_constant = 0;129invtarget = (1/(1-rho))*( I - rho/( 1+(N-1)*rho )*J );130for(t in 2:nrow(mDevolR.centered)){131st = matrix( mDevolR.centered[t,] , ncol = 1 );132LLH_constant = LLH_constant + log( det(uncR) ) + t(st)%*%invtarget%*%st133}134LLH_constant = - LLH_constant135if( !inherits(fitN, "try-error") ){ LLH_DCC = -fitN$value }else{ LLH_DCC = -LLH_constant }136# Likelihood ratio test statistic for the case of time-varying garch effects137# cases where garch volatility is probably not reliable or the volatility forecasts are so erratic that a constant garch works fine138if( LLH_DCC=="NaN" | (fitN$par[1]>= 0.1&fitN$par[2]<=0.7) | sum(fitN$par)>=0.999 ){139LLH_DCC = LLH_constant ;140useDCC = F;141} #volatility is too erratic142if( 2*(LLH_DCC-LLH_constant) <= qchisq(0.999,df=2) ){143Rt = uncR;144}else{145print( c("use DCC with parameters",fitN$par) )146Rt = Rforecast(fitN$par,mR=mDevolR.centered,uncR=C)147}148return(Rt)149}150151Rforecast <- function(par,mR,uncR){152T = nrow(mR); N = ncol(mR)153alpha = par[1] ; beta = par[2];154omega = (1-par[1]-par[2])*uncR155Qt = diag( rep(1,N) )156k = 1157for( i in 2:N ){158for(j in 1:(i-1)){159e2 = mR[,i]*mR[,j];160e2[is.na(e2)] = mean( na.omit(e2 ) )161e2t <- omega[i,j] + alpha*c(mean(e2),e2[-length(e2)], tail(e2,1) )162Qt[i,j] = Qt[j,i] = tail(filter(e2t, beta, "recursive", init = uncR[i,j] ),1)163}164}165166return( diag(diag(Qt)^(-0.5))%*%Qt%*%diag(diag(Qt)^(-0.5)) )167}168# test; uncR=diag(c(1,1)) ; Rforecast( c(0.05,0.4) , matrix(rnorm(400),ncol=2),uncR)169170loglik.dcc2.DECO = function (param,uncR,mDevolR.centered)171{172require('ccgarch')173dvar = mDevolR.centered174nobs <- dim(dvar)[1]175ndim <- dim(dvar)[2]176out <- .Call("dcc_est", dvar, uncR, param[1], param[2])177DCC <- dcc.est(dvar, param)$DCC178lf <- numeric(ndim)179I = diag( rep(1,ndim) ) ; J = matrix( rep(1,ndim^2) , ncol=ndim )180for (i in 1:nobs) {181R <- matrix(DCC[i, ], ndim, ndim)182rho = mean( lvech(R) )183DECO = (1-rho)*I + rho*J184invDECO = (1/(1-rho))*( I - rho/( 1+(ndim-1)*rho )*J )185lf[i] <- log(det(DECO)) + sum(dvar[i, ] * crossprod(invDECO,186dvar[i, ]))187}188sum(lf)189}190191192193