***********************************; /* RESEARCH METHODS IN ACCOUNTING */ /* Exercise 22.1.2020 */ ***********************************; libname rma "\\home.org.aalto.fi\jarvah1\data\Downloads"; run; data rdq; set rma.rdq; if RDQ='.'D then delete; /* <- delete if quarter earnings announcement date is missing */ if FQTR=4; /* <- retain only the fourth quarter */ run; proc print data=rdq (obs=15); run; * import earnings data from Compustat Fundamentals Annual database; data ni; set rma.ni; dNI=dif(NI); /* <- change in net income*/ if GVKEY^=lag(GVKEY) then dNI=.; /* take into account when company changes */ if dNI=. then delete; SURP=0; if dNI>0 then SURP=1; /* surprise sign indicator (dummy) variable */ keep GVKEY DATADATE LPERMCO dNI SURP; run; proc print data=ni (obs=15); run; proc contents data=ni; run; * merge data; proc sort data=rdq; by GVKEY DATADATE; proc sort data=ni; by GVKEY DATADATE; data aaa; merge ni (in=a) rdq (in=b); by GVKEY DATADATE; if a and b; * check outiers; EAlag=RDQ-DATADATE; * delete outliers; if EAlag<7 then delete; if EAlag>126 then delete; run; proc print data=aaa (obs=15); run; proc means data=aaa n mean min p1 q1 median q3 p99 max maxdec=0; var EAlag; run; * import returns data; * mCRSPret contains equal-weighted monthly returns of CRSP stock market index; proc sql; create table ret as select * from rma.mret as a, rma.mCRSPret as b where a.date=b.date; quit; proc print data=ret (obs=15); run; data ret; set ret; * missing returns; if ret<-1 then ret=.; if ret=. then ret=EWRETD; /* if a company firm have a missing monthly return let's set it to index return */ drop PERMNO; run; * MERGE COMPUSTAT AND CRSP DATA; proc sql; create table bbb as select * from aaa as a, ret as b where a.LPERMCO=b.PERMCO and (-400 <= (b.date - a.rdq) <=220); /* this makes sure that we have 12 (6) months before (after) data */ quit; * Need to count trading months; * First, count trading months before event; proc sort data=bbb out=b1; where date lt rdq; /* lt syntax means 'less than'*/ by PERMCO RDQ descending date; run; /* FIRST.variable and LAST.variable Other automatic variables are available only in special circumstances. The FIRST.variable and LAST.variable automatic variables are available when you are using a BY statement in a DATA step. The FIRST.variable will have a value of 1 when SAS is processing an observation with the first occurrence of a new value for that variable and a value of 0 for the other observations. The LAST.variable will have a value of 1 for an observation with the last occurrence of a value for that variable and the value 0 for the other observations. */ data b1; set b1; by PERMCO RDQ; if first.RDQ=1 then tm_count=0; /* see above */ tm_count=tm_count-1; /* this is our own month calculator */ retain tm_count; run; proc print data=b1 (obs=15); run; * Next count trading months after event; proc sort data=bbb out=b2; where date ge RDQ; /* ge syntax means 'greater or equal' */ by PERMCO RDQ date; run; data b2; set b2; by PERMCO RDQ; if first.RDQ=1 then tm_count=-1; tm_count=tm_count+1; * special case for even date; if date=RDQ then tm_count=0; retain tm_count; run; * rejoin the before and after months; data ccc; set b1 b2; run; proc sort data=ccc; by permco RDQ tm_count; data ddd; set ccc; where -12<=tm_count<=6; run; * cumulating returns; proc sort data=ddd; by PERMCO RDQ DATE; proc expand data=ddd out=eee; /* SAS tips folder in MyCourses */ convert ret=cum_ret / method=none transformout=(+1 cuprod -1); convert ewretd=cum_mkt / method=none transformout=(+1 cuprod -1); by PERMCO RDQ; run; data fff; set eee; CAR=cum_ret-cum_mkt; /* deduct CRSP stock market index return */ run; proc sort data=fff; by tm_count SURP; proc means data=fff noprint; output out=ggg (drop=_type_) mean(CAR)=mCAR; by tm_count SURP; proc means data=fff noprint; output out=hhh (drop=_type_) mean(CAR)=mCAR; by tm_count; run; proc format; /* The FORMAT procedure creates formats that will later be associated with variables in a FORMAT statement. */ value stype 0='Negative NI surprise' 1='Positive NI surprise' 2='Both NI groups'; run; data BB68; set ggg hhh (in=b); if b then SURP=2; format SURP stype.; run; proc sgplot data=BB68; title 'Ball & Brown (1968)'; series x=tm_count y=mCAR / GROUP=SURP; XAXIS TYPE=DISCRETE; YAXIS LABEL ='cumulative abnormal return'; refline -0.15 0 0.15 / transparency =0.5; /* You can add reference lines to many types of graphs using the REFLINE statement. transarency sets the transparency of the line. Values range from 0 to 1 with a default of 0. */ run;