WRDS Macro: IDVOL

Calculates idiosyncratic volatility using time-series monthly/daily regressions for various risk models

Example

/* ********************************************************************************* */
/* ******************** W R D S   R E S E A R C H   M A C R O S ******************** */
/* ********************************************************************************* */
/* WRDS Macro: IDVOL                                                                 */
/* Summary   : Calculates idiosyncratic volatility using time-series monthly/daily   */
/*              regressions for various risk models                                  */
/* Date      : July 07, 2009                                                         */
/* Author    : Denys Glushkov, WRDS                                                  */
/* Variables : - INSET and OUTSET are input and output datasets                      */
/*             - DATEVAR: name of the date variable in INSET dataset                 */
/*             - RETVAR : name of the raw return variable in INSET dataset           */
/*             - FREQ   : frequency of returns in incoming INSET dataset,            */
/*                        m (monthly) or d(daily)                                    */
/*             - WINDOW : the length of the rolling estimation window in             */
/*                        months/trading days over which the idiosyncratic volatility*/
/*                        is estimated                                               */
/*             - STEP   : number of months/trading days by which the estimation      */
/*                        window is rolled forward                                   */
/*             - MIN    : minimum number of non-missing returns in the esitmation    */
/*                        window required for generating valid estimates of IDVOL    */
/*             - MODEL  : risk model used in estimation of idiosyncratic volatility  */
/*                        m (market), ff (Fama-French 3 factor), ffm (FF+Momentum)   */
/* ********************************************************************************* */
    
 %MACRO IDVOL (INSET=, OUTSET=, DATEVAR=, RETVAR=, FREQ=, WINDOW=,STEP=, MIN=, MODEL=);
    
   %local oldoptions errors;
   %let oldoptions=%sysfunc(getoption(mprint)) %sysfunc(getoption(notes))
                   %sysfunc(getoption(source));
   %let errors=%sysfunc(getoption(errors));
   options nonotes nomprint nosource errors=0;
   %let model=%lowcase(&model);%let freq=%lowcase(&freq);
    
  /*Depending on the incoming return frequency, create ancillary macro variables*/
  %if &freq=m %then %do; %let file=monthly; %let inc=month;%let dateff=dateff;%end;%else
  %if &freq=d %then %do; %let file=daily;   %let inc=day;  %let dateff=date;%end;
    
  /*Depending on the type of the risk model, create the variable list to be extracted*/
  %if &model=m   %then %let vars=mktrf;            %else
  %if &model=ff  %then %let vars=mktrf smb hml;    %else
  %if &model=ffm %then %let vars=mktrf smb hml umd;
    
  %put ### CREATING TRADING CALENDAR;
  proc printto log=junk;
  %Trade_Date_Windows (freq=&freq, size=&window, minsize=&min, outdsn=_caldates);
  proc printto;run;
  %put ### DONE!;
    
  %put ### MERGING IN THE RISK FACTORS;
  proc sql noprint; create table _vol
     as select a.*, b.*, (&retvar-rf) as exret
     from &inset a left join ff.factors_&file (keep=&dateff rf &vars) b
     on a.&datevar=b.&dateff
     order by a.permno, a.&datevar;
     select distinct min(&datevar) format date9.,
                     max(&datevar) format date9. into :mindate,:maxdate
    from _vol;
  quit;
%put ### DONE!;
    
 /*Save the beginning and ending position of the earliest    */
 /*and the latest dates in the trading calendar              */
  data _caldates; set _caldates;
    n+1;
    if intnx('month',beg_date,0,'e')=
    intnx('month',"&mindate"d,0,'e') then call symput ('start',n);
    if intnx('month',end_date,0,'e')=
    intnx('month',"&maxdate"d,0,'e') then call symput ('finish',n);
  run;
    
 /*Main part. Estimate Idiosyncratic Volatility using   */
 /*rolling time-series regressions. Boundaries for      */
 /*regressions are based on start and end dates in the  */
 /*trading calendar                                     */
  %put ### ESTIMATING IDIOSYNCRATIC VOLATILITY;
  proc printto log=junk;run;
  %do j=&start %to &finish %by &step;
    
   data _null_; set _caldates (sortedby=n where=(n=&j));
    call symput ('beg',beg_date);call symput ('end',end_date);
   run;
    
   data _sample/view=_sample;
     do k=1 by 1 until (last.permno);
      set _vol; by permno;
      where &beg<=date<&end;
      if missing(ret) then continue;
      mcount=sum(mcount,1);
    end;
   keep permno mcount;
   run;
    
  data _vvol/view=_vvol;
  merge _vol (sortedby=date where=(&beg<=date<&end)) _sample;
   by permno;
   if mcount>=&min;
   drop mcount;
  run;
    
  proc reg data=_vvol edf noprint outest=_stats;
   by permno;
   model exret=&vars;
  quit;
    
  data _stats; set _stats;
   format start_date end_date date9.;
   start_date=&beg;end_date=&end;
   nused=_p_+_edf_;
   label _rmse_ = " "; rename _rmse_=Idrisk_std;
   keep permno start_date end_date _rmse_ nused;
  run;
    
 /*Pool all estimates of idiosyncratic risk together*/
  proc append base=_idvol data=_stats force;run;
  %end;
  proc printto;run;
    
 /*Merge the incoming dataset with idiosyncratic risk estimates*/
  proc sql; create table &outset
   as select *
   from &inset a left join _idvol b
   on a.permno=b.permno and a.date=b.end_date;
   /* house cleaning*/
   drop table _stats, _vol, _caldates;
   drop view _vvol, _sample;
  quit;
  options &oldoptions errors=&errors;
  %put ### DONE!;
  %put ### OUTPUT IN THE DATASET &outset;
 %MEND;
     
 /* ********************************************************************************* */
 /* *************  Material Copyright Wharton Research Data Services  *************** */
 /* ****************************** All Rights Reserved ****************************** */
 /* ********************************************************************************* */

Top of Section

Top