GARCH (generalized autoregressive conditional heteroscedasticity) models are widely used in market risk industry to estimate and forecast the volatility of returns. GARCH, including many variants like A-GARCH, GJR-GARCH and E-GARCH, is especially suitable for predicting short and medium term volatility forecasts, since it is based on sound economic model and capable of capturing volatility clustering [Ref. 1].

Matlab and R dominate the skies of market risk [Ref. 2], while SAS is frequently mentioned in the area of credit risk. For univariate volatility modeling of market risk, I personally feel that SAS’s AUTOREG procedure performs better than either the fGarch package in R or the garchset() function in Matlab [Ref. 3], because in my experience it is more robust and code-efficient. The pitfall for SAS to analyze volatility is that it does not have functionality to download financial market data. Fortunately the tseries package from R provides a get.hist.quote() function which obtains data from YAHOO or OANDA [Ref. 4]. In the example below, I embedded the corresponding modules of R into a SAS’s macro getr(), and therefore downloaded and transformed the historical data of S&P 500 adjusted close prices. Then I implemented a GARCH(4,1) model in another univol() macro to estimate and forecast the volatilities until the end of this year. The results suggest that the combination of SAS, R and Excel would be useful to generate and diagnose the desired GARCH model for volatility.

References:
1. Carol Alexander. ‘Market Risk Analysis, Practical Financial Econometrics’. Wiley.
2. Jon Danielsson. ‘Financial Risk Forecasting: The Theory and Practice of Forecasting Market Risk with Implementation in R and Matlab’. Wiley.
3. The AUTOREG procedure. ‘SAS/ETS 9.2 User's Guide’. http://support.sas.com
4. The get.hist.quote() function. http://finzi.psych.upenn.edu/R/library/tseries

/*******************READ ME*********************************************
* - Automate univariate volatility modeling by macros -
*
* SAS VERSION: 9.2.2
* R VERSION: 2.13.0 (library: 'tseries', 'foreign')
* EXCEL VERSION:2007
*
* DATE: 08jun2011
* AUTHOR: [email protected]
****************END OF READ ME******************************************/

****************(1) MODULE-BUILDING STEP*******************************;
%macro getr(startday = '01jan2005'd, squote =, filepath =, rpath =);
/****************************************************************
* MACRO: getr()
* GOAL: download adjusted close prices for specified quote
* and convert them into returns
* PARAMETERS: startday = start day of data to be downloaded
* squote = quote symbol to be downloaded
* filepath = file path for data exchange
* rpath = installation path for R
*****************************************************************/
options mprint mlogic;
data _null_;
day = &startday;
call symput('startdate', %str(put(&startday,yymmdd10.)));
call symput('enddate', %str(put(today(),yymmdd10.)));
run;

proc sql;
create table _tmp0 (string char(800));
insert into _tmp0
values("library(tseries,foreign)")
values("p=get.hist.quote(instrument='quote_choose',")
values("start='start_date',end='end_date',quote ='AdjClose',quiet=T)")
values("y=diff(log(p))")
values("y=y-mean(y)")
values("result=as.data.frame(y)")
values("write.csv(result,file='sas_path/find_result.csv')")
;quit;

data _tmp1;
set _tmp0;
string = tranwrd(string, "start_date", "&startdate");
string = tranwrd(string, "end_date", "&enddate");
string = tranwrd(string, "quote_choose", lowcase("&squote"));
string = tranwrd(string, "sas_path", translate("&filepath", "/", "\"));
string = tranwrd(string, "find_result", "&squote");
run;
data _null_;
set _tmp1;
file "&filepath\sas_r.r";
put string;
run;

options xsync xwait;
x "cd &rpath";
x "R.exe CMD BATCH --vanilla --slave &filepath\sas_r.r";
%mend getr;

%macro univol(predday = '31dec2011'd, q = 1, p = 0, filepath =);
/****************************************************************
* MACRO: univol()
* GOAL: estimate or forcast volatilities by garch(q, p)
* and plot diagnosis
* PARAMETERS: predday = end day for volatility prediction
* q = the subset of ARCH terms to be fitted
* p = the subset of GARCH terms to be fitted
* filepath = file path to exchange data
*****************************************************************/
options mprint mlogic;
data _tmp01;
infile "&filepath\result.csv" delimiter = ',' missover dsd
lrecl=32767 firstobs=2 end = eof;
format date yymmdd10.; informat date yymmdd10.;
format r best32.; informat r best32.;
input date $ r;
if eof then call symput('maxdaygot', date);
run;

data _null_;
format date yymmdd10.;
date = &maxdaygot;
dayinterval = intck('day', date, &predday);
call symput('dayinterval', dayinterval);
run;

%if %eval(&dayinterval) gt 0 %then %do;
data _tmp02(drop=i);
format date yymmdd10.;
date = &maxdaygot;
do i = 1 to &dayinterval;
r = .;
date + 1;
output;
end;
run;
data _tmp01;
set _tmp01 _tmp02;
run;
%end;

ods html file = "&filepath\output.xls" gpath = "&filepath\" style = harvest;
title; footnote;
ods graphics on;
ods select standardresidualplot fitplot qqplot residualhistogram acfplot;
proc autoreg data=_tmp01 all plots(unpack);
model r = / noint garch=(q=&q, p=&p);
output out=_tmp02 cev=v;
run;
ods graphics off;
data _tmp03;
set _tmp02;
length type $ 8.;
if r ne . then do;
type = 'estimate'; output; end;
else do;
type = 'forecast'; output; end;
run;

proc print data = _tmp03 noobs;
run;
proc sgplot data=_tmp01;
series y=r x=date /lineattrs=(color=blue);
refline 0/ axis = y lineattrs = (pattern=shortdash);
run;
proc sgplot data=_tmp03;
series x=date y=v/group=type;
refline &maxdaygot/ axis = x lineattrs = (pattern=shortdash);
run;
ods html close;
%mend univol;

****************(2) TESTING STEP****************************************;
%getr(startday = '01jan2005'd, squote = ^gspc, filepath = c:\tmp,
rpath = c:\Program Files\R\R-2.13.0\bin);
%univol(predday = '31dec2011'd, q = 4, p = 1, filepath = c:\tmp);

****************END OF ALL CODING***************************************;