Subject: #3 - The EVENT Program

From: Gerry <[email-masked]>
Date: Mon, 17 Jun 96 16:03:51 EDT

Don:

This is the EVENT program itself. The first half of the code is for
the windows (entry & message), and parameter checking code. The "real"
action starts at line 309, where the "EVENTS" lookup table is created
from the user's CUSIP/Date file.

The next Data Step retrieves the earliest and latest date values, which
is the maximum span between dates in the Events lookup table. The EVENTS
table is then sorted by CUSIP (remember our database is in CUSIP number
order) and indexed.

The last Data Step performs the actual data extraction, using the KEY=
Set option, matching the records in the CRSP database that meet the
selection criteria as defined by the EVENTS lookup table file.

-Gerry

--------------------------- EVENT SAS ------------------------------

/**********************************************************************/
/*************************** Pace University **************************/
/****************** Department of Academic Computing ******************/
/**********************************************************************/
/*                                                                    */
/* Program Name:               Event                                  */
/*                                                                    */
/* Program Implemented:        10/06/94                               */
/*                                                                    */
/* Program Version:            1.01                                   */
/*                                                                    */
/* Program Language:           SAS (Macro, V6.08)                     */
/*                                                                    */
/* Program Author:             Gerry Pauline,                         */
/*                             Statman @ Pacevm.Dac.Pace.Edu          */
/*                                                                    */
/**********************************************************************/
/************************* Purpose of Program *************************/
/**********************************************************************/
/*                                                                    */
/* This program retrieves data from the CRSP database for a set of    */
/* CUSIP numbers and an 'event' date. This is a re-implementation     */
/* of the RESEARCH program, originally written by Tuan.               */
/*                                                                    */
/* The user supplies the name of a file containing the CUSIPs and     */
/* 'event' dates, the name of the exchange (NYSEAMX or NASDAQ), the   */
/* variable to retrieve (Askhi, Bidlo, Price, Return, Volume) and     */
/* the number of days before the event date and the number of days    */
/* after the event date, which forms the data retrieval 'window'.     */
/*                                                                    */
/**********************************************************************/
/************************ Input And Output Files **********************/
/**********************************************************************/
/*                                                                    */
/* xxxxxxxx INPDATA A  - Name of the file containing the CUSIPs and   */
/*                       the event dates.                             */
/*                                                                    */
/* xxxxxxxx OUTDATA A  - Name of the file data is outputted to (will  */
/*                       be the same as the INPDATA filename).        */
/*                                                                    */
/* xxxxxxxx BADDATA A  - Name of the file containing CUSIP numbers    */
/*                       that had an event date that was not a        */
/*                       valid CRSP trading date.                     */
/*                                                                    */
/* **** Note:  The filetype for the input file MUST be INPDATA; the   */
/*             filetype for the output file will be OUTDATA.          */
/*                                                                    */
/**********************************************************************/
/********************* Subroutines And Procedures *********************/
/**********************************************************************/
/*                                                                    */
/* None                                                               */
/*                                                                    */
/**********************************************************************/
/**************** External References And Dependencies ****************/
/**********************************************************************/
/*                                                                    */
/* 0FORMATS CRSPDATE - Format table containing the trading dates in   */
/*                     YYMMDD6. format. The program will look for     */
/*                     this file on the account's 'A' disk.           */
/*                                                                    */
/**********************************************************************/
/***************************** Update Log *****************************/
/**********************************************************************/
/*                                                                    */
/*  1.)  10/17/94  Gerry                                              */
/*                                                                    */
/*       Recoded the program section assigning the lowest X value and */
/*       the highest Y value to macro variables from using a condit-  */
/*       ional loop traversing the dataset to using the POINT keyword */
/*       on the SET statement for a direct access look up.            */
/*                                                                    */
/**********************************************************************/
/***************************** Disclaimer *****************************/
/**********************************************************************/
/*                                                                    */
/*    This program is made available by the Department of Academic    */
/*    Computing at Pace University and may not be distributed with-   */
/*    out its permission. Copying, either in whole or in part, for    */
/*    commercial use is strictly prohibited. For permission to dis-   */
/*    tribute this program, contact:                                  */
/*                                                                    */
/*                    Associate Director,                             */
/*                    Department of Academic Computing                */
/*                    Pace University                                 */
/*                    861 Bedford Road                                */
/*                    Pleasantville, NY 10570-2799                    */
/*                    (914) 773-3632                                  */
/*                                                                    */
/**********************************************************************/

Options MACROGEN MSTORED MTRACE SYMBOLGEN SASMSTORE=EVENT ;

%Macro EVENT / Store ;                        /* Save Executable Code */

  /*------------------------------------------------------------------*/
  /*            Define The 2 Windows Used By This Program             */
  /*------------------------------------------------------------------*/

  %Window EVENT Color=BLUE

   Group=CRSP

   #1  @3  'Please enter the following data retrieval information.'
       C=BLUE
   #3  @3  'Event File:' C=C @16 EVFILE   8 C=R A=H Auto=YES
       @26 '(the default is' C=C +1 'EVENT' C=BLUE A=H +1
           'if not specified by the user)' C=C
   #5  @3  'Exchange:'   C=C @16 XCHANGE  4 C=R A=H Auto=YES
       @26 '(either' C=C +1 'NYSE' C=BLUE A=H +1 'for NYSE/AMEX or'
           C=C +1 'NASD' C=BLUE A=H +1 'for NASDAQ)' C=C
   #7  @3  'Variable:'   C=C @16 SELVAR   6 C=R A=H Auto=YES
       @26 '(Askhi, Bidlo, Price, Return or Volume)' C=C
   #9  @3  'X(-) Value:' C=C @16 XVALUE   3 C=R A=H Auto=YES
       @26 '(' C=C "'n' days" C=C +1 'BEFORE' C=BLUE A=H +1
           'the event date)'  C=C
   #11 @3  'Y(+) Value:' C=C @16 YVALUE   3 C=R A=H Auto=YES
       @26 '(' C=C "'n' days" C=C +1 'AFTER' C=BLUE A=H +1
           'the event date)'  C=C
   #13 @3  'When all of the fields are filled, press ENTER' C=BLUE +1
           'to begin processing.' C=BLUE
   ;

  %Window INFORM Irow=16 Icolumn=5 Rows=8 Columns=67 Color=YELLOW

   Group=USER

   #1  @6  'When processing has completed, this window will be' C=R
   #2  @6  'cleared.  If retrieval was successful, output will' C=R
   #3  @6  'reside in the file <'
       C=R +1 OUTFILE P=YES C=Y A=H +1 '>.' C=R
   ;

  %Let EVFILE = EVENT ;                 /* Default 'Lookup' File Name */
  %Let FLDCHK = 1 ;                            /* Loop Check Variable */

  /*------------------------------------------------------------------*/
  /*           Process The Information Entered By The User            */
  /*------------------------------------------------------------------*/

  %Do %Until (&FLDCHK = 0) ;

      %If (%Upcase(&SYSCMD) = STOP) %Then ENDSAS ;    /* Exit Program */

      %Display EVENT.CRSP ;             /* Display The Primary Window */

      %If (%Upcase(&SYSCMD) = STOP) %Then ENDSAS ;    /* Exit Program */

      /*---------- Uppercase The Values Entered By The User ----------*/

      %Let EVFILE  = %Upcase(&EVFILE) ;           /* 'Event' Filename */
      %Let XCHANGE = %Upcase(&XCHANGE) ;       /* Stock Exchange Code */
      %Let SELVAR  = %Upcase(&SELVAR) ;        /* Variable To Process */

      %Cms State &EVFILE INPDATA A ;             /* Does File Exist ? */

      /*------ Hold RC, Check For Valid Exchange & Variable Name -----*/

      %Let CHK1 = &SYSRC ;
      %Let CHK2 = %Index('NYSE NASD', &XCHANGE) ;
      %Let CHK3 = %Index('PRICE RETURN ASKHI BIDLO VOLUME', &SELVAR) ;

      /*--------- Initialize And Assign Field Check Variables --------*/

      %Let FCHK1 = 0 ;
      %Let FCHK2 = 0 ;
      %Let FCHK3 = 0 ;
      %Let FCHK4 = 0 ;
      %Let FCHK5 = 0 ;
      %Let FCHK6 = 0 ;

      %If (&CHK1 = 0)   %Then %Let FCHK1 = 0 ;  /* Event File Exist ? */
         %Else %Let FCHK1 = 1 ;

      %If (&CHK2 > 0)   %Then %Let FCHK2 = 0 ; /* Exchange Code Valid */
         %Else %Let FCHK2 = 1 ;

      %If (&CHK3 > 0)   %Then %Let FCHK3 = 0 ; /* Variable Name Valid */
         %Else %Let FCHK3 = 1 ;
                                            /* NASDAQ Only Has RETURN */
      %If (&XCHANGE = NASD) %Then
         %If (&SELVAR = RETURN) %Then %Let FCHK4 = 0 ;
            %Else %Let FCHK4 = 1 ;

      %If (&XVALUE > 0) %Then %Let FCHK5 = 0 ;    /* X Greater Than 0 */
         %Else %Let FCHK5 = 1 ;

      %If (&YVALUE > 0) %Then %Let FCHK6 = 0 ;    /* Y Greater Than 0 */
         %Else %Let FCHK6 = 1 ;

      /*------- If An Error Occurred, Display An Error Message -------*/

      %If (%Eval(&FCHK1 + &FCHK2 + &FCHK3 +
                 &FCHK4 + &FCHK5 + &FCHK6) > 0) %Then
         %Do ;

           /*------ Assign Text To The (Error) Message Variables -----*/

           %Let M1 = The INPDATA file &EVFILE does not exist ! ;
           %Let M2 = The EXCHANGE code must be either NYSE or NASD ! ;
           %Let M3 =
                Variables are PRICE, RETURN, ASKHI, BIDLO and VOLUME ! ;
           %Let M4 =
                Only the RETURN is available from the NASDAQ exchange !;
           %Let M5 = The XVALUE must be greater than 0 ! ;
           %Let M6 = The YVALUE must be greater than 0 ! ;

           %Let FLDCHK = 1 ;

           %If (&FCHK1) %Then            /* Event File Does Not Exist */
              %Do ;
                %Let SYSMSG  = &M1 ;
                %Let EVFILE  = ;
              %End ;
             %Else
           %If (&FCHK2) %Then           /* Exchange Code Is Incorrect */
              %Do ;
                %Let SYSMSG  = &M2 ;
                %Let XCHANGE = ;
              %End ;
             %Else
           %If (&FCHK3) %Then           /* Variable Name Is Incorrect */
              %Do ;
                %Let SYSMSG  = &M3 ;
                %Let SELVAR  = ;
              %End ;
             %Else
           %If (&FCHK4) %Then         /* NASDAQ, RETURN Not Specified */
              %Do ;
                %Let SYSMSG  = &M4 ;
                %Let SELVAR  = ;
              %End ;
             %Else
           %If (&FCHK5) %Then                  /* X Value Less Than 1 */
              %Do ;
                %Let SYSMSG  = &M5 ;
                %Let XVALUE  = ;
              %End ;
             %Else
           %If (&FCHK6) %Then                  /* Y Value Less Than 1 */
              %Do ;
                %Let SYSMSG  = &M6 ;
                %Let YVALUE  = ;
              %End ;
         %End ;
        %Else                              /* All Field Values Are OK */
         %Do ;
           %Let FLDCHK  = 0 ;            /* Reset Loop Check Variable */
           %Let INPFILE = &EVFILE INPDATA A ;       /* Event Filename */
           %Let OUTFILE = &EVFILE OUTDATA A ;      /* Output Filename */

           %Display INFORM.USER Noinput ;    /* Display INFORM Window */
         %End ;

  %End ;                                /* End DO UNTIL (FLDCHK) Loop */

  /*---- Assign Array 'Header' Variable, Dataset Name And Libname ----*/

  %If (&SELVAR = PRICE) %Then
     %Do ;
       %Let VAR    = SPR ;
       %Let DBNAME = NYSEAMX.PRICES ;
       Libname NYSEAMX 'J' ;
     %End ;
    %Else
  %If (&SELVAR = RETURN) %Then
     %Do ;
       %Let VAR    = RET ;
       %If (&XCHANGE = NYSE) %Then
          %Do ;
            %Let DBNAME = NYSEAMX.PRICES ;
            Libname NYSEAMX 'J' ;
          %End ;
         %Else
          %Do ;
            %Let DBNAME = NASDAQ.RETURNS ;
            Libname NASDAQ 'M' ;
          %End ;
     %End ;
    %Else
  %If (&SELVAR = ASKHI) %Then
     %Do ;
       %Let VAR    = ASK ;
       %Let DBNAME = NYSEAMX.HILOPRC ;
       Libname NYSEAMX 'K' ;
     %End ;
    %Else
  %If (&SELVAR = BIDLO) %Then
     %Do ;
       %Let VAR    = BID ;
       %Let DBNAME = NYSEAMX.HILOPRC ;
       Libname NYSEAMX 'K' ;
     %End ;
    %Else
  %If (&SELVAR = VOLUME) %Then
     %Do ;
       %Let VAR    = VOL ;
       %Let DBNAME = NYSEAMX.VOLUME ;
       Libname NYSEAMX 'L' ;
     %End ;

   Libname CRSPDATE 'A' ;                     /* Data Formats (Chung) */
   Libname CRSPFMT  'W' ;                  /* Data Formats (Standard) */

   /*-----------------------------------------------------------------*/
   /*               Create The EVENTS Lookup Table File               */
   /*-----------------------------------------------------------------*/

   DATA EVENTS (KEEP=CUSIP DATENO XVALUE YVALUE) ;
     Infile "&INPFILE" End=EOF ;

     RECNO  = 0 ;                                   /* Record Counter */
     XVALUE = 0 ;              /* Date 'Lag':  Days Before Event Date */
     YVALUE = 0 ;               /* Date 'Lead': Days After Event Date */

     /*------------------------ Main Read Loop -----------------------*/

     Do While (^EOF) ;

        Input @1 CUSIP $Char6. @8 DATENO Dateno6. ;

        If (DATENO = .) Then          /* Check If Event Date Is Valid */
           Do ;
             File "&EVFILE BADDATE A" ;
             Put @1   'The event date for CUSIP number <'
                 @35  CUSIP  @42 '> is not' /
                 @1   'a valid CRSP trading date,'
                 @28  'and has been deleted !'        / ;
             Delete ;                           /* Remove This Record */
             Continue ;                 /* Return For The Next Record */
           End ;

        XVALUE = DATENO - &XVALUE ;             /* Compute Date 'Lag' */
        YVALUE = DATENO + &YVALUE ;            /* Compute Date 'Lead' */

        Output EVENTS ;            /* Write The Record To The Dataset */

        RECNO + 1 ;                   /* Increment The Record Counter */

     End ;                                /* End DO WHILE (^EOF) Loop */

     /*---------- Move The Record Total To A Macro Variable ----------*/

     If (EOF) Then
        Call Symput ('RECNO', Put(RECNO,4.)) ;

    Stop ;                           /* Explicitly Halt The Data Step */
   Run ;

   /*---------------- Sort The EVENTS Dataset By Date ----------------*/

   Proc SORT Data=EVENTS Out=BYDATENO ;
     By DATENO ;
   Run ;

   /*-----------------------------------------------------------------*/
   /* Get The Lowest XVALUE and The Highest YVALUE (For Array Bounds) */
   /*-----------------------------------------------------------------*/

   Data _NULL_ ;

     Do KEY = 1, &RECNO ;                   /* First And Last Records */

        Set BYDATENO Point=KEY ;

        If (KEY = 1) Then LOWER = XVALUE ;          /* Lowest X Value */
           Else Do ;                               /* Highest Y Value */
                  UPPER = YVALUE ;
                  Call Symput ('LOWER', Put(LOWER,4.)) ;
                  Call Symput ('UPPER', Put(UPPER,4.)) ;
                  Stop ;             /* Explicitly Halt The Data Step */
                End ;

     End ;                                       /* End DO (KEY) Loop */

   Run ;

   /*-----------------------------------------------------------------*/
   /*      Sort The Lookup Table By CUSIP And Index The Dataset       */
   /*-----------------------------------------------------------------*/

   Proc SORT Data=EVENTS ;
     By CUSIP ;
   Run ;

   Proc DATASETS Library=WORK Nolist ;
     Modify EVENTS ;
     Index Create CUSIP ;
   Run ;

   /*-----------------------------------------------------------------*/
   /*          Retrieve The Data Keyed By The Lookup Table            */
   /*-----------------------------------------------------------------*/

   %Cms Exec Database (CRSP) ;          /* Link To The Database Disks */

   Data _NULL_ ;

     /*- Retrieve Data From &DBNAME By The 'Keys' In EVENTS (Lookup) -*/

     Set EVENTS ;
     Set &DBNAME (Keep=CUSIP &VAR&LOWER--&VAR&UPPER) Key=CUSIP ;

     Array CRSP {&LOWER:&UPPER} &VAR&LOWER--&VAR&UPPER ;

     /*-------------- Write The Data To The OUTDATA File -------------*/

     File "&OUTFILE" Lrecl=72 Blksize=7200 Recfm=FB ;

     Put @1 CUSIP ;

     Do IDX = XVALUE To YVALUE By 1 ;
        Put (CRSP{IDX}) (10.6) @ ;
     End ;

     Put / ;

   Run ;

   %Cms Exec Database (DET2) ;           /* Release The Database Disk */

   EndSAS ;                        /* All Done -- We're Out of Here ! */

%Mend EVENT ;