I am conducting an event study and need the average value of return to generate abnormal returns. My benchmark window is [-60,-11] and my event window is [-5,-1] with 0 as announcement date. However, I have several announcements which could contaminate the benchmark and event window. Still, I want to keep the 50 days of benchmark window intact, thus, if there is an announcement in the benchmark window, delete this day and extend the window by 1.
Right now I generate averages with proc expand:
proc expand; by stock;
convert logreturn = avg_logreturn / METHOD = none TRANSFORMOUT = (movave 60 lag 11);
run;
And then deduct the average from the actual returns.
My data set looks like this (10 years of data):
Stock Date Return Announcement
AAA 01/01/10 0.05
AAA 02/01/10 0.04
AAA 03/01/10 -0.02 03/01/10 this one should be deleted as is spoils the coming announcement but still be counted as an announcement
AAA 04/01/10 0.01
AAA 05/01/10 -0.03
AAA 06/01/10 0.05
AAA 07/01/10 0.04
AAA 08/01/10 -0.02 08/01/10
AAA 09/01/10 0.01
AAA 10/01/10 -0.03
AAB 01/01/10 0.01
etc
Basically, each announcement needs a window of -60 to -11 where I calculate the average of. The length should remain the same but always if there is anther announcement in this window, the return should not be counted in that average.
The idea is simple but the realization seems compliacted...
Pre process the data to be expanded.
Sample code:
data have;
attrib
stock length=$3
date length=4 format=date9. informat=mmddyy8.
return length=8 format=6.2
announcement length=4 format=date9. informat=mmddyy8.
;
infile cards missover;
input stock date return announcement;
datalines;
AAA 01/01/10 0.05
AAA 02/01/10 0.04
AAA 03/01/10 -0.02 03/01/10 this one should be deleted as is spoils the coming announcement but still be counted as an announcement
AAA 04/01/10 0.01
AAA 05/01/10 -0.03
AAA 06/01/10 0.05
AAA 07/01/10 0.04
AAA 08/01/10 -0.02 08/01/10
AAA 09/01/10 0.01
AAA 10/01/10 -0.03
AAB 01/01/10 0.01
run;
%let CULL_GAP_LE_CRITERIA = 5 ;
data cull(keep=stock cull_date);
set have;
by stock date;
retain cull_date;
if first.stock then cull_date = .;
if announcement then do;
if cull_date then do;
gap = intck('month', cull_date, announcement);
if gap <= &CULL_GAP_LE_CRITERIA then
OUTPUT;
end;
cull_date = announcement; * setup for culling this announcement as well;
put cull_date=;
end;
run;
data DATA_FOR_EXPAND / view=DATA_FOR_EXPAND;
merge
have
cull(rename=cull_date=date in=culled)
;
by stock date;
if not culled;
run;
if not culled
will remove the culled row. I think this is correct for you because you said the window was to increase by 1.
If you want the culled date to be used in rolling windows prior to itself you have a bit of a pickle.