Saturday, June 11, 2011

Using PROC IML to deploy EWMA model for market risk


Exponentially weighted moving average (EWMA) model, which is a straight-forward moving average method in market risk, could memorize the finite market movements and address the relationship among multiple asset prices. Comparing with other multivariate volatility solutions like OGARCH or DCC, it usually shows the strongest fluctuations during the time span [Ref.1].

Since EWMA would utilize the variance-covariance matrices, Proc IML in SAS is the best match. In his blog, Rick Wicklin introduced a Cov() function in SAS/IML to create the sample covariance matrix for a given matrix [Ref. 2]. Thus I implemented this IML function in an EWMA() macro below and analyzed the correlations of the daily market returns between Google and Apple since 2005. As the result, SAS/IML proves very efficient and robust. Interestingly, in this experiment, I found that if a matrix or a vector is declared with specified size before the computation step, the program’s efficiency would be significantly improved. It may suggest that declaring matrices explicitly could be a good habit for SAS/IML programming.

References:
1. Jon Danielsson. ‘Financial Risk Forecasting’. Wiley, 2011.
2. Rick Wicklin. ‘Computing Covariance and Correlation Matrices’. The Do Loop. 08DEC2010.

/*******************READ ME*********************************************
* -  Using Proc IML to deploy EWMA model for market risk  -
*
* SAS VERSION:    9.2.2
* DATE:           12jun2011
* AUTHOR:         hchao8@gmail.com
*
****************END OF READ ME******************************************/

****************(1) MODULE-BUILDING STEP********************************;
%macro EWMA(squote1 =, squote2 =, slambda =, filepath = );
   /****************************************************************
   *  MACRO:      EWMA()
   *  GOAL:       estimate correlations between two stocks 
   *              according to market daily returns by EWMA
   *  PARAMETERS: squote1   = first stock share 
   *              squote2   = second stock share
   *              slambda   = weight coefficient
   *              filepath  = file path to input data and output plot
   *****************************************************************/
   options mlogic mprint;
   data &squote1;
      infile "&filepath\&squote1..csv" delimiter = ',' missover dsd firstobs=2;
      format date yymmdd10.; informat date yymmdd10.; 
      format r best32.; informat r best32.;
      input date $ r;
   run;
   data &squote2;
      infile "&filepath\&squote2..csv" delimiter = ',' missover dsd firstobs=2;
      format date yymmdd10.; informat date yymmdd10.; 
      format r best32.; informat r best32.;
      input date $ r;
   run;
   proc sql;
      create table _tmp01 as 
      select a.date, a.r as r1, b.r as r2
      from &squote1 as a, &squote2 as b
      where a.date = b.date
   ;quit;

   proc iml;
      start Cov(A);            
         n = nrow(A);         
         C = A - A[:,];       
         return( (C` * C) / (n-1) );
      finish;
      use _tmp01;
      read all var{date r1 r2};
      N = nrow(r1);
      y = r1 || r2;
      lambda = &slambda;
      EWMA=J(N, 3);
      S = J(2, 2);
      S = Cov(y);
      EWMA[1, ] = S[1,1] || S[2,2] || S[1, 2];
      do i = 2 to N;
         S = lambda * S  + (1-lambda) * t(y[i, ]) * y[i, ];
         EWMA[i, ] = S[1,1] || S[2,2] || S[1, 2];
      end;
     create _tmp02 from EWMA ;
     append from EWMA;
   quit;

   data  _tmp03;
      set  _tmp02;
      rho = col3 / sqrt(col1 * col2);
      keep rho;
   run;
   data _tmp04;
      set _tmp01;
      set _tmp03;
   run;

   proc template;
      define statgraph ewmaplot;
      begingraph / designwidth=1000px designheight=800px;
      layout lattice / columns=1 columndatarange=union rowweights=(0.3 0.3 0.4);
         layout overlay / cycleattrs=true xaxisopts=(label="Returns of %upcase(&squote1)") 
            yaxisopts=(griddisplay=on label=" " display=(line) displaysecondary=all);
            seriesplot x=date y=r1;
         endlayout;
         layout overlay / cycleattrs=true xaxisopts=(label="Returns of %upcase(&squote2)")
            yaxisopts=(griddisplay=on label=" " display=(line) displaysecondary=all); 
            seriesplot x=date y=r2 ;
         endlayout;
         layout overlay / cycleattrs=true  xaxisopts=(label="Correlation by EWMA") 
            yaxisopts=(griddisplay=on label=" " display=(line) displaysecondary=all);
             seriesplot x=date y=rho;
         endlayout;
      endlayout;
      endgraph;
      end;
   run;
   ods html  gpath = "&filepath" style = harvest;
   proc sgrender data=_tmp04 template=ewmaplot; 
   run;
   ods html close;
%mend EWMA;

****************(2) TESTING STEP****************************************;
%getr(startday = '01jan2005'd, squote = goog, filepath = c:\tmp, 
      rpath = c:\Program Files\R\R-2.13.0\bin);
%getr(startday = '01jan2005'd, squote = aapl, filepath = c:\tmp, 
      rpath = c:\Program Files\R\R-2.13.0\bin);
%ewma(squote1 = goog, squote2 = aapl, slambda = 0.94, filepath = c:\tmp);

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

Good math, bad engineering

As a formal statistician and a current engineer, I feel that a successful engineering project may require both the mathematician’s abilit...