BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Tango_Mike
Fluorite | Level 6

Hello,

This is probably a very novice question. I've tried several methods I've found by reading previous threads but none has worked so far.

 

I have a dataset of abnormal returns from -10 days to +10 days around an event study (dataset named firm_level_results). These 135 companies are organized by PERMNO. I am trying to create an output table with cumulative results for each company in five different trading day windows (-1 to 0; 1- to 1; 0 to 1; 0 to 2; 0 to 5). Here is a screenshot of the dataset, EVTTIME is the trading day reference to the event date; ABRET is each day's abnormal return.

image.png

 

/* I have previous code steps SQL combining several tables for regression controls*/

/*Calculate CARs for each company for each trading window*/

data temp.car_windows; set temp.car_windows; /* Create CAR results table */
run;

data temp.firm_level_results; set temp.firm_level_results; /* Source event data */

data want;
set temp.firm_level_results;
where evttime => -1 and evttime <= 0; /* First trading window wanted */

run;

I realize this code is clunky, I was trying to figure out the first step before expanding into summing the results, etc.

 

Thanks for whatever help someone can provide

1 ACCEPTED SOLUTION

Accepted Solutions
mkeintz
PROC Star

Editted note:  Mistake!  Mistake!  Mistake!  The CAR's starting in event date zero should be this:

 

  car_0_1  = (1+daily_car{1})/(1+daily_car{-1})-1;   * for (0,1);
  car_0_2  = (1+daily_car{2})/(1+daily_car{-1})-1;   * for (0,2);
  car_0_5  = (1+daily_car{5})/(1+daily_car{-1})-1;   * for (0,5);

 

 

The specified CAR's should, I believe be calculated like this:\

 

 

 

 

So do you want 1 record per event with identifiers and 5 cumulative return variables corresponding to the five event-related periods you identify?

 

If so, assuming your data are sorted by permno/evtdate/evttime, then you can do something like this:

 

 

 

 

data selected_cum_ar (drop=abret date ret);
  set have;
  by permno evtdate;
  where evttime between -1 and 5;
  array daily_car {-1:5} _temporary_;
  if first.evtdate then do;
    call missing (of daily_car{*});
    daily_car{evttime}=abret;
  end;
  else daily_car{evttime}= (1+daily_car(evttime-1))*(1+abret)-1;
  if last.evtdate;
  car_m1_0 = daily_car{0};  * for (-1,0);
  car_m1_1 = daily_car{1};  * for (-1,1);
  car_0_1  = daily_car{1}/daily_car{-1};   * for (0,1);
  car_0_2  = daily_car{2}/daily_car{-1};   * for (0,2);
  car_0_5  = daily_car{5}/daily_car{-1};   * for (0,5);
run;

 

 

 

  1. The WHERE filter only keeps trading day -1 through +5;
  2. The array "daily_car" will hold cumulative abnormal returns for -1, 0, 1, 2, ... through +5.   As a _temporary_ array it (a) won't be written to the output dataset, and (b) will not have values automatically reset to missing - a handy feature for building today's CAR using today's abret and the preceding CAR.
  3.  The BY statement tells sas to expect the data in HAVE to be sorted, and provides automatic dummy variables letting you know if the record-in-hand is the beginning (or ending) of a set of records for a given permno/evtdate.
  4.   The "if last.evtdate" is a filter, allowing the subsequent production of your desired CARs only when the group of records is exhausted.
--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------

View solution in original post

2 REPLIES 2
mkeintz
PROC Star

Editted note:  Mistake!  Mistake!  Mistake!  The CAR's starting in event date zero should be this:

 

  car_0_1  = (1+daily_car{1})/(1+daily_car{-1})-1;   * for (0,1);
  car_0_2  = (1+daily_car{2})/(1+daily_car{-1})-1;   * for (0,2);
  car_0_5  = (1+daily_car{5})/(1+daily_car{-1})-1;   * for (0,5);

 

 

The specified CAR's should, I believe be calculated like this:\

 

 

 

 

So do you want 1 record per event with identifiers and 5 cumulative return variables corresponding to the five event-related periods you identify?

 

If so, assuming your data are sorted by permno/evtdate/evttime, then you can do something like this:

 

 

 

 

data selected_cum_ar (drop=abret date ret);
  set have;
  by permno evtdate;
  where evttime between -1 and 5;
  array daily_car {-1:5} _temporary_;
  if first.evtdate then do;
    call missing (of daily_car{*});
    daily_car{evttime}=abret;
  end;
  else daily_car{evttime}= (1+daily_car(evttime-1))*(1+abret)-1;
  if last.evtdate;
  car_m1_0 = daily_car{0};  * for (-1,0);
  car_m1_1 = daily_car{1};  * for (-1,1);
  car_0_1  = daily_car{1}/daily_car{-1};   * for (0,1);
  car_0_2  = daily_car{2}/daily_car{-1};   * for (0,2);
  car_0_5  = daily_car{5}/daily_car{-1};   * for (0,5);
run;

 

 

 

  1. The WHERE filter only keeps trading day -1 through +5;
  2. The array "daily_car" will hold cumulative abnormal returns for -1, 0, 1, 2, ... through +5.   As a _temporary_ array it (a) won't be written to the output dataset, and (b) will not have values automatically reset to missing - a handy feature for building today's CAR using today's abret and the preceding CAR.
  3.  The BY statement tells sas to expect the data in HAVE to be sorted, and provides automatic dummy variables letting you know if the record-in-hand is the beginning (or ending) of a set of records for a given permno/evtdate.
  4.   The "if last.evtdate" is a filter, allowing the subsequent production of your desired CARs only when the group of records is exhausted.
--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
Tango_Mike
Fluorite | Level 6

That is excellent, thank you very much for the code and the explanation

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 2 replies
  • 696 views
  • 1 like
  • 2 in conversation