Value-at-Risk Forecasts with AR(1)-GARCH(1,1)

Discussions of ARCH, GARCH, and related models
Farid
Posts: 19
Joined: Sun Jun 05, 2011 9:02 pm

Value-at-Risk Forecasts with AR(1)-GARCH(1,1)

Unread post by Farid »

Hi again,

I need to generate and test Value-at-Risk (VaR) forecasts based on AR(1)-GARCH(1,1) estimates. Could you please suggest me any references (RATS codes) which deal with VaR forecasts in GARCH setup?

Thanks in advance,

Farid
TomDoan
Posts: 7814
Joined: Wed Nov 01, 2006 4:36 pm

Re: Value-at-Risk Forecasts with AR(1)-GARCH(1,1)

Unread post by TomDoan »

The Tsay textbook has about five examples on calculation of VaR using GARCH models. This is the closest to what you need. You use UFORECAST to compute the mean and the @GarchFore procedure to compute the variance.

Code: Select all

*
* Tsay, Analysis of Financial Time Series, 3rd edition
* Example 7.3 (continued) from page 338
* Value at Risk calculation
*
open data d-ibmln98.dat
data(format=free,org=columns) 1 9190 ibmlog
set ibmlog = .01*ibmlog
*
* Define the equation for the mean
*
equation ar2 ibmlog
# constant ibmlog{2}
*
* GARCH with normal residuals
*
garch(p=1,q=1,equation=ar2,hseries=h,resids=res)
*
* Forecast the variance using @GARCHFORE and the series itself using
* UFORECAST.
*
@garchfore(steps=15) h res
uforecast(equation=ar2,steps=15) fret
*
* Use SSTATS to accumulate the mean and variance over the forecast period.
*
sstats 9191 9205 fret>>ret15 h>>ret15h
*
disp "5% VaR, 15 day horizon on 10000000" -10000000*(ret15+%invnormal(.05)*sqrt(ret15h))
Attachments
d-ibmln98.dat
Data file
(80.77 KiB) Downloaded 719 times
Farid
Posts: 19
Joined: Sun Jun 05, 2011 9:02 pm

Re: Value-at-Risk Forecasts with AR(1)-GARCH(1,1)

Unread post by Farid »

Thanks for response Tom. In my case, however, I have a little bit different situation. I have a full sample of 1287 days. I use 511 days as a sample period to estimate AR(1)-GARCH(1,1) coefficients. After that I roll the regressions with moving window of 511 to obtain AR(1)-GARCH(1,1) coefficients for the following 777 days (forecasting period).

Here is the code for what I've done so far:

Code: Select all

OPEN DATA "C:\Documents and Settings\admin\Desktop\teze.RAT"
CALENDAR(D) 2006:1:3
DATA(FORMAT=RATS) 2006:01:03 2010:12:08 RT
smpl 2 511
garch(p=1,q=1,reg,resids=u,hseries=h) / rt
# constant rt{1}

***Testing standardized residuals

set ustd = u/sqrt(h)
set ustdsq = ustd^2
correlate(qstat,number=40,dfc=1,title="LB Test") ustd
correlate(qstat,number=40,dfc=2,title="McLeod-Li Test") ustdsq
stats ustd


***Rolling GARCH
compute width=511
dec vect[series] coeffs(5)

do gend=width,1287

   if gend==width
      garch(p=1,q=1,reg,resids=u,hseries=h,noprint) gend-width+2 gend rt
      # constant rt{1}

   else
      garch(p=1,q=1,reg,resids=u,hseries=h,initial=%beta,hessian=%xx,noprint) gend-width+2 gend rt
      # constant rt{1}

   compute %pt(coeffs,gend,%beta)

end do gend
After that, according to the reference you gave, I should have the following:

Code: Select all

* GARCH with normal residuals
*
garch(p=1,q=1,equation=ar1,hseries=h,resids=u)
*
* Forecast the variance using @GARCHFORE and the series itself using
* UFORECAST.
*
@garchfore(steps=777) h u
uforecast(equation=ar1,steps=777) fret

* Use SSTATS to accumulate the mean and variance over the forecast period.
*
sstats 512 1287 fret>>ret1 h>>ret1h
*
disp "5% VaR, 1 day horizon on 10000000" -10000000*(ret1+%invnormal(.05)*sqrt(ret1h))
*
Does it make sense?

Contrary to that I have found one code from my professor, which is not complete though. Thus I cannot follow it properly. It's completely different from Tsay code and that confuses me.

Here it is:

Code: Select all

nonlin(parmset=garchparms) vc=.1 va=.84 vb=.14 
frml resid = x1
frml hf = vc + va*h{1} + vb*u{1}**2
frml logl = (h(t)=%ovcheck(hf(t))),(u(t)=resid(t)),-.5*(log(h)+u**2/h)
linreg(noprint) x1 / u
# constant
compute vc=.5,va=.7,vb=.2
set h = %seesq
maximize(parmset=garchparms,method=bfgs,robusterrors,iters=10,noprint) logl gstart gend

set ce = u/sqrt(h)
order ce secondt lastt

compute perc1=secondt+40
compute perc5=secondt+200
compute perc95=secondt+3800
compute perc99=secondt+3960

compute s_cband1=ce(perc1)
compute s_cband5=ce(perc5)
compute s_cband95=ce(perc95)
compute s_cband99=ce(perc99)

do tim0=4000,7999
compute tim1=tim0+1
compute ht(4000)=h(4000)
compute ut(tim0)=x1(tim0)

compute ht(tim1)= vc + va*ht(tim0) + vb*ut(tim0)**2

compute obser5=s_cband5*sqrt(ht(tim1))
compute obser95=s_cband95*sqrt(ht(tim1))
compute obser1=s_cband1*sqrt(ht(tim1))
compute obser99=s_cband99*sqrt(ht(tim1))
compute s_cp5(tim1)=obser5
compute s_cp95(tim1)=obser95
compute s_cp1(tim1)=obser1
compute s_cp99(tim1)=obser99

compute n_vio(tim1)=%if(s_cp5(tim1)<=x1(tim1).and.x1(tim1)<=s_cp95(tim1),0,1)
if n_vio(tim1)=1.and.x1(tim1)<s_cp5(tim1)
 compute d_vio=s_cp5(tim1)-x1(tim1)
else if n_vio(tim1)=1.and.x1(tim1)>s_cp95(tim1)
 compute d_vio=x1(tim1)-s_cp95(tim1)
else 
 compute d_vio=%NA
 compute cdeg_vio(tim1)=d_vio

compute n_vio(tim1)=%if(s_cp5(tim1)<=x1(tim1).and.x1(tim1)<=s_cp95(tim1),0,1)
if n_vio(tim1)=1.and.x1(tim1)<s_cp5(tim1) {
 compute l_vio=s_cp5(tim1)-x1(tim1),u_vio=%NA 
}
else if n_vio(tim1)=1.and.x1(tim1)>s_cp95(tim1) {
 compute u_vio=x1(tim1)-s_cp95(tim1),l_vio=%NA
}
else {
 compute u_vio=%NA,l_vio=%NA
}
compute l_cdeg_vio(tim1)=l_vio,u_cdeg_vio(tim1)=u_vio
if l_cdeg_vio(tim0)!=%NA.and.l_cdeg_vio(tim1)!=%NA
   compute lc_consec(tim1)=1
else 
compute lc_consec(tim1)=%NA 

if u_cdeg_vio(tim0)!=%NA.and.u_cdeg_vio(tim1)!=%NA
   compute uc_consec(tim1)=1
else 
compute uc_consec(tim1)=%NA 

compute zn_vio(tim1)=%if(s_cp1(tim1)<=x1(tim1).and.x1(tim1)<=s_cp99(tim1),0,1)
if zn_vio(tim1)=1.and.x1(tim1)<s_cp1(tim1)
 compute d_vio=s_cp1(tim1)-x1(tim1)
else if zn_vio(tim1)=1.and.x1(tim1)>s_cp99(tim1)
 compute d_vio=x1(tim1)-s_cp99(tim1)
else 
 compute d_vio=%NA
 compute czdeg_vio(tim1)=d_vio

compute zn_vio(tim1)=%if(s_cp1(tim1)<=x1(tim1).and.x1(tim1)<=s_cp99(tim1),0,1)
if zn_vio(tim1)=1.and.x1(tim1)<s_cp1(tim1) {
 compute zl_vio=s_cp1(tim1)-x1(tim1),zu_vio=%NA 
}
else if zn_vio(tim1)=1.and.x1(tim1)>s_cp99(tim1) {
 compute zu_vio=x1(tim1)-s_cp99(tim1),zl_vio=%NA
}
else {
 compute zu_vio=%NA,zl_vio=%NA
}
compute zl_cdeg_vio(tim1)=zl_vio,zu_cdeg_vio(tim1)=zu_vio

end do tim0

statistics(noprint) ht 4001 8000
compute c_var(k)=sqrt(%variance),c_mvar(k)=%mean

statistics(noprint) s_cp1 4001 8000
compute c_var1(k)= %mean

statistics(noprint) s_cp5 4001 8000
compute c_var5(k)= %mean

statistics(noprint) s_cp95 4001 8000
compute c_var95(k)=%mean

statistics(noprint) s_cp99 4001 8000
compute c_var99(k)=%mean


statistics(noprint) lc_consec 4001 8000
compute nlc_consec(k)=%nobs

statistics(noprint) uc_consec 4001 8000
compute nuc_consec(k)=%nobs

statistics(noprint) czdeg_vio 4001 8000
compute czc_vio(k)=%nobs
compute czt_deg_vio(k)=%mean

statistics(noprint) zl_cdeg_vio 4001 8000
compute zlcc_vio(k)=%nobs
compute zlct_deg_vio(k)=%mean

statistics(noprint) zu_cdeg_vio 4001 8000
compute zucc_vio(k)=%nobs
compute zuct_deg_vio(k)=%mean

statistics(noprint) cdeg_vio 4001 8000
compute cc_vio(k)=%nobs
compute ct_deg_vio(k)=%mean

statistics(noprint) l_cdeg_vio 4001 8000
compute lcc_vio(k)=%nobs
compute lct_deg_vio(k)=%mean

statistics(noprint) u_cdeg_vio 4001 8000
compute ucc_vio(k)=%nobs
compute uct_deg_vio(k)=%mean


compute ccoff0(k)=vc,ccoff1(k)=va, ccoff2(k)=vb
compute cband5(k)=s_cband5,cband95(k)=s_cband95,cband1(k)=s_cband1,cband99(k)=s_cband99




Farid
Posts: 19
Joined: Sun Jun 05, 2011 9:02 pm

Re: Value-at-Risk Forecasts with AR(1)-GARCH(1,1)

Unread post by Farid »

My previous AR(1)-GARCH(1,1) rolling has already forecasted 1) h series 2) u series 3) 5 coefficients for 777 days.

Now I need to do the following:

specify mean equation, variance equation and calculate one day ahead VaR forecasts for further testing (comparing to real returns).

When I specify mean and variance equations I cannot input coefficients into variance model.

I think the following code should be appropriate for one-day ahead VaR forecasts:

Code: Select all

set ht 1 1287 = 0.0
set ut 1 1287 = 0.0

DO lastt = 511,1287
compute lastt2=lastt+1
compute lastt1=lastt-1
compute firstt = lastt-776
compute secondt = firstt+1
compute zerot = firstt-1


set ce = u/sqrt(h)
order ce secondt lastt

compute perc1=secondt+7
compute perc5=secondt+38
compute perc95=secondt+738
compute perc99=secondt+769

compute s_cband1=ce(perc1)
compute s_cband5=ce(perc5)
compute s_cband95=ce(perc95)
compute s_cband99=ce(perc99)

do tim0=511,1287
compute tim1=tim0+1
compute ht(511)=h(511)

compute ut(tim0)=rt(tim0)

compute ht(tim1)= coeffs(3) + coeffs(5)*ht(tim0) + coeffs(4)*ut(tim0)**2

compute obser5=s_cband5*sqrt(ht(tim1))
compute obser95=s_cband95*sqrt(ht(tim1))
compute obser1=s_cband1*sqrt(ht(tim1))
compute obser99=s_cband99*sqrt(ht(tim1))
compute s_cp5(tim1)=obser5
compute s_cp95(tim1)=obser95
compute s_cp1(tim1)=obser1
compute s_cp99(tim1)=obser99

But it's not. It doesn't recognize coefficients as values from previous forecasting and gives an error: "## SX22. Expected Type REAL, Got MATRIX[REAL] Instead
>>>>ffs(4)*ut(tim0)**2<<<<".

Could you please look through this code and help me out?

Thanks in advance
TomDoan
Posts: 7814
Joined: Wed Nov 01, 2006 4:36 pm

Re: Value-at-Risk Forecasts with AR(1)-GARCH(1,1)

Unread post by TomDoan »

Farid wrote:Contrary to that I have found one code from my professor, which is not complete though. Thus I cannot follow it properly. It's completely different from Tsay code and that confuses me.

Here it is:

Code: Select all

nonlin(parmset=garchparms) vc=.1 va=.84 vb=.14 
frml resid = x1
frml hf = vc + va*h{1} + vb*u{1}**2
frml logl = (h(t)=%ovcheck(hf(t))),(u(t)=resid(t)),-.5*(log(h)+u**2/h)
linreg(noprint) x1 / u
# constant
compute vc=.5,va=.7,vb=.2
set h = %seesq
maximize(parmset=garchparms,method=bfgs,robusterrors,iters=10,noprint) logl gstart gend

set ce = u/sqrt(h)
order ce secondt lastt

compute perc1=secondt+40
compute perc5=secondt+200
compute perc95=secondt+3800
compute perc99=secondt+3960

compute s_cband1=ce(perc1)
compute s_cband5=ce(perc5)
compute s_cband95=ce(perc95)
compute s_cband99=ce(perc99)

do tim0=4000,7999
compute tim1=tim0+1
compute ht(4000)=h(4000)
compute ut(tim0)=x1(tim0)

compute ht(tim1)= vc + va*ht(tim0) + vb*ut(tim0)**2

compute obser5=s_cband5*sqrt(ht(tim1))
compute obser95=s_cband95*sqrt(ht(tim1))
compute obser1=s_cband1*sqrt(ht(tim1))
compute obser99=s_cband99*sqrt(ht(tim1))
compute s_cp5(tim1)=obser5
compute s_cp95(tim1)=obser95
compute s_cp1(tim1)=obser1
compute s_cp99(tim1)=obser99

compute n_vio(tim1)=%if(s_cp5(tim1)<=x1(tim1).and.x1(tim1)<=s_cp95(tim1),0,1)
if n_vio(tim1)=1.and.x1(tim1)<s_cp5(tim1)
 compute d_vio=s_cp5(tim1)-x1(tim1)
else if n_vio(tim1)=1.and.x1(tim1)>s_cp95(tim1)
 compute d_vio=x1(tim1)-s_cp95(tim1)
else 
 compute d_vio=%NA
 compute cdeg_vio(tim1)=d_vio

compute n_vio(tim1)=%if(s_cp5(tim1)<=x1(tim1).and.x1(tim1)<=s_cp95(tim1),0,1)
if n_vio(tim1)=1.and.x1(tim1)<s_cp5(tim1) {
 compute l_vio=s_cp5(tim1)-x1(tim1),u_vio=%NA 
}
else if n_vio(tim1)=1.and.x1(tim1)>s_cp95(tim1) {
 compute u_vio=x1(tim1)-s_cp95(tim1),l_vio=%NA
}
else {
 compute u_vio=%NA,l_vio=%NA
}
compute l_cdeg_vio(tim1)=l_vio,u_cdeg_vio(tim1)=u_vio
if l_cdeg_vio(tim0)!=%NA.and.l_cdeg_vio(tim1)!=%NA
   compute lc_consec(tim1)=1
else 
compute lc_consec(tim1)=%NA 

if u_cdeg_vio(tim0)!=%NA.and.u_cdeg_vio(tim1)!=%NA
   compute uc_consec(tim1)=1
else 
compute uc_consec(tim1)=%NA 

compute zn_vio(tim1)=%if(s_cp1(tim1)<=x1(tim1).and.x1(tim1)<=s_cp99(tim1),0,1)
if zn_vio(tim1)=1.and.x1(tim1)<s_cp1(tim1)
 compute d_vio=s_cp1(tim1)-x1(tim1)
else if zn_vio(tim1)=1.and.x1(tim1)>s_cp99(tim1)
 compute d_vio=x1(tim1)-s_cp99(tim1)
else 
 compute d_vio=%NA
 compute czdeg_vio(tim1)=d_vio

compute zn_vio(tim1)=%if(s_cp1(tim1)<=x1(tim1).and.x1(tim1)<=s_cp99(tim1),0,1)
if zn_vio(tim1)=1.and.x1(tim1)<s_cp1(tim1) {
 compute zl_vio=s_cp1(tim1)-x1(tim1),zu_vio=%NA 
}
else if zn_vio(tim1)=1.and.x1(tim1)>s_cp99(tim1) {
 compute zu_vio=x1(tim1)-s_cp99(tim1),zl_vio=%NA
}
else {
 compute zu_vio=%NA,zl_vio=%NA
}
compute zl_cdeg_vio(tim1)=zl_vio,zu_cdeg_vio(tim1)=zu_vio

end do tim0

statistics(noprint) ht 4001 8000
compute c_var(k)=sqrt(%variance),c_mvar(k)=%mean

statistics(noprint) s_cp1 4001 8000
compute c_var1(k)= %mean

statistics(noprint) s_cp5 4001 8000
compute c_var5(k)= %mean

statistics(noprint) s_cp95 4001 8000
compute c_var95(k)=%mean

statistics(noprint) s_cp99 4001 8000
compute c_var99(k)=%mean


statistics(noprint) lc_consec 4001 8000
compute nlc_consec(k)=%nobs

statistics(noprint) uc_consec 4001 8000
compute nuc_consec(k)=%nobs

statistics(noprint) czdeg_vio 4001 8000
compute czc_vio(k)=%nobs
compute czt_deg_vio(k)=%mean

statistics(noprint) zl_cdeg_vio 4001 8000
compute zlcc_vio(k)=%nobs
compute zlct_deg_vio(k)=%mean

statistics(noprint) zu_cdeg_vio 4001 8000
compute zucc_vio(k)=%nobs
compute zuct_deg_vio(k)=%mean

statistics(noprint) cdeg_vio 4001 8000
compute cc_vio(k)=%nobs
compute ct_deg_vio(k)=%mean

statistics(noprint) l_cdeg_vio 4001 8000
compute lcc_vio(k)=%nobs
compute lct_deg_vio(k)=%mean

statistics(noprint) u_cdeg_vio 4001 8000
compute ucc_vio(k)=%nobs
compute uct_deg_vio(k)=%mean


compute ccoff0(k)=vc,ccoff1(k)=va, ccoff2(k)=vb
compute cband5(k)=s_cband5,cband95(k)=s_cband95,cband1(k)=s_cband1,cband99(k)=s_cband99

This part is computing the empirical 1%, 5%, 95% and 99%-iles of the standardized residuals. (This is a rather clumsy way to do this---STATS(FRACTILES) CE rather than the ORDER instruction will compute and defined %FRACT01, %FRACT05, %FRACT95 and %FRACT99).

Code: Select all

set ce = u/sqrt(h)
order ce secondt lastt

compute perc1=secondt+40
compute perc5=secondt+200
compute perc95=secondt+3800
compute perc99=secondt+3960

compute s_cband1=ce(perc1)
compute s_cband5=ce(perc5)
compute s_cband95=ce(perc95)
compute s_cband99=ce(perc99)
This computes the GARCH variance for the next period and determines the predicted set of percentiles for the distribution of the return for that period. The s_cp5, s_cp95, etc. series are those percentiles. The remainder of the loop is counting the number of times the actual data fall into various categories.

Code: Select all

   compute ht(tim1)= vc + va*ht(tim0) + vb*ut(tim0)**2
   
   compute obser5=s_cband5*sqrt(ht(tim1))
   compute obser95=s_cband95*sqrt(ht(tim1))
   compute obser1=s_cband1*sqrt(ht(tim1))
   compute obser99=s_cband99*sqrt(ht(tim1))
   compute s_cp5(tim1)=obser5
   compute s_cp95(tim1)=obser95
   compute s_cp1(tim1)=obser1
   compute s_cp99(tim1)=obser99
Farid
Posts: 19
Joined: Sun Jun 05, 2011 9:02 pm

Re: Value-at-Risk Forecasts with AR(1)-GARCH(1,1)

Unread post by Farid »

...
Last edited by Farid on Sun Jun 26, 2011 1:34 am, edited 1 time in total.
Farid
Posts: 19
Joined: Sun Jun 05, 2011 9:02 pm

Re: Value-at-Risk Forecasts with AR(1)-GARCH(1,1)

Unread post by Farid »

Thanks for clarification Tom.

How do I incorporate COEFFS series (there are available in the series window under COEFF(1), COEFFS(2), etc. labels) into mean and variance equations? I did simple "compute coeffs(3,4,5)=vc,va,vb", but as you can see the code generates an error in variance equation:

"## MAT13. Store into Out-of-Range Matrix or Series Element
The Error Occurred At Location 187, Line 12 of loop/block"

Code: Select all

***VaR Forecasts


set ce = u/sqrt(h)
stats(fractiles) ce

compute s_cband1=-2.682658
compute s_cband5=-1.627572
compute s_cband95=1.538992
compute s_cband99=2.345644

set ht 1 1287 = 0.0
set ut 1 1287 = 0.0

do tim0=512,1287

compute tim1=tim0+1
compute ht(tim0)=h(tim0)
compute ut(tim0)=rt(tim0)


compute vc=coeffs(3)
compute va=coeffs(5)
compute vb=coeffs(4)

compute ht(tim1) = vc + va*ht(tim0) + vb*ut(tim0)**2

compute obser5=s_cband5*sqrt(ht(tim1))
compute obser95=s_cband95*sqrt(ht(tim1))
compute obser1=s_cband1*sqrt(ht(tim1))
compute obser99=s_cband99*sqrt(ht(tim1))
compute s_cp5(tim1)=obser5
compute s_cp95(tim1)=obser95
compute s_cp1(tim1)=obser1
compute s_cp99(tim1)=obser99

end do tim0

Post Reply