Performs an event study
Example
/* ********************************************************************************* */
/* ******************** W R D S R E S E A R C H M A C R O S ******************** */
/* ********************************************************************************* */
/* WRDS Macro: EVTSTUDY */
/* Summary : Performs an event study */
/* Date : July 17, 2009 */
/* Modified : May 30, 2012 */
/* Author : Denys Glushkov, WRDS */
/* Parameters: */
/* - ID : Name of security identifier in INSET: PERMNO or CUSIP */
/* CUSIP should be at least 8 (eight) characters */
/* - INSET : Input dataset containg security IDs and event dates */
/* - OUTSET : Name of the output dataset to store mean CAR and t-stats */
/* - OUTSTATS:Name of the output dataset to store test statistics (Patell Z, etc) */
/* - EVTDATE: Name of the event date variable in INSET dataset */
/* - DATA : Name of CRSP library to use. CRSP and CRSPQ for annual and */
/* quarterly updates, respectively */
/* - ESTPER : Length of the estimation period in trading days over which */
/* the risk model is run, e.g., 110; */
/* - START : Beginning of the event window (relative to the event date, eg. -2) */
/* - END : End of the event window (relative to the event date, e.g., +1) */
/* - GAP : Length of pre-event window, i.e., number of trading days between */
/* the end of estimation period and the beginning of the event window */
/* -GROUP: Defines an subgroup (can be more than 2) */
/* -MODEL: Risk model to be used for risk-adjustment */
/* madj - Market-Adjusted Model (assumes stock beta=1) */
/* m - Standard Market Model (CRSP value-weighted index as the market) */
/* ff - Fama-French three factor model */
/* ffm - Carhart model that includes FF factors plus momentum */
/* ********************************************************************************* */
%MACRO EVTSTUDY (INSET=, OUTSET=, OUTSTATS=, ID=permno, EVTDATE=, DATA=CRSP,
ESTPER=, START=,END=,GAP=,GROUP=,MODEL=);
%local evtwin factors abret newvars;
%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 evtwin=%eval(&end-&start+1); *length of event window in trading days;
/*depending on the model, define the model for abnormal returns*/
%if %lowcase(&model)=madj %then %do; %let factors=vwretd;
%let abret=ret-vwretd;
%let newvars=(intercept=alpha);
%end;%else
%if %lowcase(&model)=m %then %do; %let factors=vwretd;
%let abret=ret-alpha-beta*vwretd;
%let newvars=(intercept=alpha vwretd=beta);
%end;%else
%if %lowcase(&model)=ff %then %do;
%let factors=vwretd smb hml;
%let abret=ret-alpha-beta*vwretd-sminb*smb-hminl*hml;
%let newvars=(intercept=alpha vwretd=beta smb=sminb hml=hminl);
%end;%else
%if %lowcase(&model)=ffm %then %do;
%let factors=vwretd smb hml mom;
%let abret=ret-alpha-beta*vwretd-sminb*smb-hminl*hml-wminl*mom;
%let newvars=(intercept=alpha vwretd=beta smb=sminb hml=hminl mom=wminl);
%end;
%put; %put ### CREATING TRADING DAY CALENDAR...;
data _caldates;
merge &data..dsiy (keep=caldt rename=(caldt=estper_beg))
&data..dsiy (keep=caldt firstobs=%eval(&estper) rename=(caldt=estper_end))
&data..dsiy (keep=caldt firstobs=%eval(&estper+&gap+1) rename=(caldt=evtwin_beg))
&data..dsiy (keep=caldt firstobs=%eval(&estper+&gap-&start+1) rename=(caldt=&evtdate))
&data..dsiy (keep=caldt firstobs=%eval(&estper+&gap+&evtwin) rename=(caldt=evtwin_end));
format estper_beg estper_end evtwin_beg &evtdate evtwin_end date9.;
if nmiss(estper_beg,estper_end,evtwin_beg,evtwin_end,&evtdate)=0;
time+1;
run;
%put ### DONE!;
/*If primary identifier is Cusip, then link in permno*/
%if %lowcase(&id)=cusip %then %do;
proc sql;
create view _link
as select permno, ncusip,
min(namedt) as fdate format=date9., max(nameendt) as ldate format=date9.
from &data..dsenames
group by permno, ncusip;
create table _temp
as select distinct b.permno, a.*
from &inset a left join _link b
on a.cusip=b.ncusip and b.fdate<=a.&evtdate<=b.ldate
order by a.&evtdate;
quit;%end;
%else %do;
/*pre-sort the input dataset in case it is not sorted yet*/
proc sort data=&inset out=_temp;
by &evtdate;
run;
%end;
/*If event date is a non-trading day, select the closest */
/*trading day that follows the event day */
/*Merge in relevant dates from the trading calendar */
proc printto log=junk;run;
proc sql;
create table _temp (drop=&evtdate)
as select a.*, a.&evtdate as _edate format date9., b.*
from _temp a left join _caldates (drop=time) b
on b.&evtdate-a.&evtdate>=0
group by a.&evtdate
having (b.&evtdate-a.&evtdate)=min(b.&evtdate-a.&evtdate);
quit;
proc printto;run;
%put ; %put ### PREPARING BENCHMARK FACTORS... ;
proc sql;create table _factors
as select a.caldt as date, a.vwretd, b.smb, b.hml, b.umd as mom
from &data..dsiy (keep=caldt vwretd) a left join ff.factors_daily b
on a.caldt=b.date;
quit;
%put ### DONE! ;
%put; %put ### RETRIEVING RETURNS DATA FROM CRSP...;
proc printto log=junk;run;
proc sql;
create table _evtrets_temp
as select a.permno, a.date format date9., a.ret as ret1, b.*
from &data..dsf a, _temp b
where a.permno=b.permno and b.estper_beg<=a.date<=b.evtwin_end;
quit;
proc printto;run;
%put ### DONE!;
%put; %put ### MERGING IN BECHMARK FACTORS...;
proc printto log=junk;run;
proc sql;
create table _evtrets1
as select a.*, b.*, (c.time-d.time) as evttime
from _evtrets_temp a
left join _factors (keep=date &factors) b
on a.date=b.date
left join _caldates c
on a.date=c.&evtdate
left join _caldates d
on a._edate=d.&evtdate;
create table _evtrets (where=(not missing(vwretd)))
as select a.*, a.ret1 label='Ret unadjusted for delisting',
(1+a.ret1)*sum(1,b.dlret)-1-a.vwretd as exret label='Market-adjusted total ret',
(1+a.ret1)*sum(1,b.dlret)-1 as ret "Ret adjusted for delisting"
from _evtrets1 a left join &data..dsedelist (where=(missing(dlret)=0)) b
on a.permno=b.permno and a.date=b.dlstdt
order by a.permno,a._edate,a.date, a.evttime;
quit;
proc printto;run;
%put ### DONE!;
%put; %put ### ESTIMATING FACTOR EXPOSURES OVER THE ESTIMATION PERIOD...;
%if %lowcase(&model) ne madj %then %do;
/*estimate risk factor exposures during the estimation period*/
proc reg data=_evtrets edf outest=_params (rename=&newvars
keep=permno _edate intercept &factors _rmse_ _p_ _edf_) noprint;
where estper_beg<=date<=estper_end;
by permno _edate;
model ret=&factors;
quit;%end;
%else %do;
proc reg data=_evtrets edf outest=_params (rename=&newvars
keep=permno _edate intercept _rmse_ _p_ _edf_) noprint;
where estper_beg<=date<=estper_end;
by permno _edate;
model ret=;
quit;%end;
%put ### DONE!;
%put; %put ### CALCULATING ONE-DAY ABNORMAL RETURN IN THE EVENT WINDOW...;
data _abrets/view=_abrets;
merge _evtrets (where=(evtwin_beg<=date<=evtwin_end) in=a) _params;
by permno _edate;
abret=&abret;
logret=log(1+ret);
var_estp=_rmse_*_rmse_;
nobs=_p_+_edf_;
label var_estp='Estimation Period Variance'
abret= 'One-day Abnormal Return (AR)'
ret= 'Raw Return'
_edate= 'Event Date'
evttime= "Trading day within (&start,&end) event window";
drop &factors _p_ _edf_ estper_beg estper_end;
if a;
run;
%put ### DONE!;
%put; %put ### CALCULATING CARS AND VARIOUS STATISTICS...;
proc means data=_abrets noprint;
by permno _edate;
id &group var_estp;
output out=_car sum(logret)=cret sum(abret)=car n(abret)=nrets;
/*calculate Standardized Cumulative Abnormal Returns*/
data _car; set _car;
poscar=car>0;
scar=car/(&evtwin*var_estp)**0.5;
cret=exp(cret)-1;
label poscar='Positive Abnormal Return Dummy'
scar= 'Standardized Cumulative Abnormal Return (SCAR)'
car= 'Cumulative Abnormal Return (CAR)'
cret= 'Cumulative Raw Return'
nrets= 'Number of non-missing abnormal returns within event window';
/*compute stats across all events (i.e., permno-event date combinations*/
proc means data=_car noprint;
var cret car scar poscar;
class &group;
output out=_test
mean= n= t=/autoname;
/*calculate different stats for assessing */
/*statistical signficance of abnormal returns*/
data &outstats; set _test;
tpatell=scar_mean*((scar_n)**0.5);
tsign=(poscar_mean-0.5)/sqrt(0.25/poscar_n);
format cret_mean car_mean percent7.5;
label tpatell= "Patell's t-stat"
car_mean= 'Mean Cumulative Abnormal Return'
cret_mean= 'Mean Cumulative Raw Return'
scar_mean= 'Mean Cumulative Standardized Abnormal Return'
car_t= 'Cross-sectional t-stat'
scar_t= "Boehmer's et al. (1991) t-stat"
car_n= 'Number of events in the portfolio'
poscar_mean= 'Percent of positive abnormal returns'
tsign= 'Sign-test statistic';
drop cret_N scar_N poscar_N cret_t poscar_t;
run;
%put ### DONE!;
proc print label u;
title1 "Output for dataset &inset for a
(&start,&end) event window using &model model";
id &group;
var cret_mean car_mean scar_mean poscar_mean
car_n tsign tpatell car_t scar_t;
%if "&group" ne "" %then %do;
title2 "Test for Equality of CARs among groups defined by &group";
/*To find out the results of the hypothesis test for comparing groups */
/*find the row of output labeled 'Model' and look at the column labeled */
/*F-value for the Fisher statistic and Pr>F for the associated p-value */
/*HOVTEST tests for whether variances of two groups are the same */
proc glm data=_car;
class &group;
model scar=&group;
means &group /hovtest;
proc npar1way data=_car wilcoxon;
var scar;
class &group;
%end;
run;
/*create the final output dataset*/
data &outset;
merge &inset (in=a rename=(&evtdate=_edate))
_abrets(keep=permno _edate date evttime ret abret var_estp)
_car (keep=permno _edate cret car scar nrets);
by permno _edate;
rename _edate=evtdate;
label _edate='Event date'
date='Trading date in event window';
format _edate date9. date date9.;
if a;
run;
/*house cleaning*/
proc sql; drop table _caldates, _car, _factors, _test,
_params, _temp, _evtrets,_evtrets1, _evtrets_temp;
drop view _abrets; quit;
options errors=&errors &oldoptions;
%put ;%put ### OUTPUT IN THE DATASET &outset;
%put ;%put ### TEST STATISTICS IN THE DATASET &outstats;
%MEND;
/* ********************************************************************************* */
/* ************* Material Copyright Wharton Research Data Services *************** */
/* ****************************** All Rights Reserved ****************************** */
/* ********************************************************************************* */