'Maximum likelihood estimation of Univariate GARCH Models with Skewed Student's-t Errors 'Open the workfile wfopen ".\usdtry.wf1" 'Convert log returns to approximate percentages returns = 100*returns 'Comparison of theoretical densities series r = @runif(-6,6) r.sort !df = 6 !skew = 1.4 series tdensity = @dtdist(r,!df) series skewtdensity = @recode(r<0,(2/(!skew+(1/!skew)))*@dtdist(r*!skew,!df),(2/(!skew+(1/!skew)))*@dtdist(r/!skew,!df)) group grdensity.add r tdensity skewtdensity freeze(dens) grdensity.scat dens.setelem(1) symbolsize(X-Small) dens.setelem(2) symbolsize(X-Small) dens.legend position(BOTCENTER) dens.setelem(1) legend("") dens.setelem(2) legend("Student's-t (df=6)") dens.setelem(3) legend("Skewed Student's-t (df=6, lambda=1.4)") dens.options size(6,3) 'Generate series for squared returns series returnsq = returns^2 'Visually compare the size of shocks smpl @first 12/31/2017 returnsq.line smpl @all 'Fit a family of GARCH models equation garchmodel1.arch(backcast=1) returns c 'GARCH(1,1) model with normal errors equation garchmodel2.arch(thrsh=1,backcast=1) returns c 'TGARCH(1,1) model with normal errors equation garchmodel3.arch(tdist,backcast=1) returns c 'GARCH(1,1) model with Student's-t errors equation garchmodel4.arch(tdist,thrsh=1,backcast=1) returns c 'TGARCH(1,1) model with Student's-t errors 'Estimate long-memory models equation arfimamodel1.ls(optmethod=opg) returnsq c d 'ARFIMA model for squared returns equation garchmodel5.arch(tdist,figarch,backcast=1) returns c 'FIGARCH(1,1) model with Student's-t errors 'Save the conditional variance and structural series from the final selected model garchmodel4.makegarch garch_leverage garchmodel4.makeresids(s) sresids_leverage 'Distribution fit for standardized residuals freeze(dist_graph) sresids_leverage.distplot hist(anchor=0, scale=dens) theory(lgnd=detail) theory(dist=tdist, lgnd=detail) 'Draw the News Impact Curve freeze(nic_graph) garchmodel4.newsimpact 'Re-estimate the final model via add-in assuming skewed Student's-t errors garchmodel4.skewedugarch(results,makegarch,makesresids) 'Compute 99% Value-at-Risk and compare the results of alternative distributions !alpha=0.01 !mean = 0 !qn_long = @qnorm(1-!alpha) !qn_short = @qnorm(!alpha) !qt_long = @qtdist(1-!alpha,c(6)) !qt_short = @qtdist(!alpha,c(6)) !qskewt_long = -exp(c(7))*@qtdist(0.5*(1-(1-!alpha))*(1+exp(c(7))^(-2)),c(6)) !qskewt_short = @qtdist(0.5*!alpha*(1+exp(c(7))^2),c(6))/exp(c(7)) series var_long_n = !mean + !qn_long*@sqrt(garchskew) 'Long position in TL series var_short_n = !mean + !qn_short*@sqrt(garchskew) 'Short position in TL series var_long_t = !mean + !qt_long*@sqrt(garchskew) series var_short_t = !mean + !qt_short*@sqrt(garchskew) series var_long_skewt = !mean + !qskewt_long*@sqrt(garchskew) series var_short_skewt = !mean + !qskewt_short*@sqrt(garchskew) series loss_dif_long_n = var_long_t - var_long_n series loss_dif_short_n = var_short_t - var_short_n series loss_dif_long_t = var_long_skewt - var_long_t series loss_dif_short_t = var_short_skewt - var_short_t group grlong.add var_long_n loss_dif_long_n loss_dif_long_t freeze(lossdiff) grlong.area(s) lossdiff.setelem(1) fillcolor(@rgb(87,131,196)) fillgray(0) lossdiff.setelem(2) fillcolor(@rgb(240,202,164)) fillgray(0) lossdiff.setelem(3) fillcolor(@rgb(255,0,0)) fillgray(0) lossdiff.options -outlinearea lossdiff.setelem(1) legend("VaR (Normal)") lossdiff.setelem(2) legend("Impact of fat tails") lossdiff.setelem(3) legend("Impact of skewness") lossdiff.legend columns(3)