Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Replicating eventstudy2

    Hi,

    I am using Stata 15.1 on Mac. Co-authors and I are attempting to replicate results from the package eventstudy2 from SSC using our own manual code, using the example dataset provided with the package (Earnings_surprises.dta, Factor_returns.dta, and security_returns.dta). The only other package we use is rangestat from SSC.

    We are mainly focused on cumulative average abnormal returns (CAAR) and we get very close to the output from eventstudy2. However, it is not the same which worries us. In a 1-factor CAPM model, eventstudy2 estimates CAAR=0.0321 and we estimate CAAR=0.0325. In a 3-factor model, eventstudy2 estimates CAAR=0.0324 and we estimate CAAR=0.0348. For brevity, I will just post the 1-factor model below.

    We focus on an event window of [-1,1] and all other parameters are set to the default from eventstudy2. We would really appreciate views on why our results differ and if we are missing anything obvious (quite possible!).


    Code:
    ssc install eventstudy2
    net get eventstudy2 
    ssc install rangestat
    The three example datasets look like the following:

    Code:
    //Earnings_surprises.dta
    clear
    input int Date double Earnings_surprise float(Market_reference Security_id)
    18477 .142857149243355 4 1
    18312 .294117659330368 4 2
    17772 .333333343267441 4 3
    18317 .179775282740593 4 4
    18319 .151898726820946 4 5
    end
    format %d Date
    Code:
    //Factor_returns.dta
    clear
    input int Date byte Market_reference float(MKT SMB HML risk_free_rate)
    17714 3   -.01556425  .003552195  -.006175981 .00013698408
    17715 3  -.008983069  .008519101  .0018280167  .0006432207
    17716 3 -.0023612224 -.009305347   .007052137 .00055780174
    17717 3  -.006097221  .012784534  .0011224622   .000604795
    17720 3   .017947385 -.017388338 -.0012865672   .000684176
    end
    format %d Date
    Code:
    //security_returns.dta
    clear
    input int Date long Trading_volume double Price float(Market_reference Security_id Return)
    16440 1111600  23.7 4 1 -.014553014
    16441 1262300 23.53 4 1 -.007172996
    16442 1083000 23.73 4 1  .008499787
    16443  671900 23.58 4 1 -.006321113
    16446 1075000 23.92 4 1     .014419
    end
    format %d Date
    Produce CAAR from eventstudy2 as a benchmark result (CAARE in carfile.dta):
    Code:
    net get eventstudy2                
    use Earnings_surprises.dta, clear                    
    eventstudy2 Security_id Date using Security_returns if Earnings_surprise > 0.05, ret(Return) car1LB(-1) car1UB(1)  evwlb(-1) evwub(1) mod(FM) marketfile(Factor_returns) mar(MKT) idmar(Market_reference) risk(risk_free_rate)  minesw(1)  minevw(1) replace                    
    use carfile, clear
    Our code to replicate:
    Code:
    use security_returns.dta, clear
    merge 1:1 Security_id Date using Earnings_surprises.dta //merge with earnings_surprises
    drop if _merge==2 //drop earnings_surprises if not matched to any security returns
    drop _merge
    merge m:1 Date Market_reference using Factor_returns.dta //merge with factor returns
    drop if _merge!=3 //drop if cannot match factor returns with security returns (this will remove id's 101-104)
    drop _merge
    egen id=group(Security_id) 
    gen ReturnE=Return-risk_free_rate //calculate excess returns
    gen eventdummy = Earnings_surprise!=.& Earnings_surprise!=0 //generate a dummy==1 for each earnings surprise observation
    gen eventdummy05= Earnings_surprise>0.05&Earnings_surprise!=. //generate dummy==1 if earnings surprise>0.05
    gen eventwindow=0 //begin calculating three-day window [-1,1]
    sort id Date
    forvalues i=1/3 {
    replace eventwindow=`i'  if eventdummy05[_n+2-`i']==1
    } //label days around event day as [1,2,3] for [-1,0,1]
    gen windowdummy =eventwindow !=0 //create an event window dummy
    rangestat (reg) ReturnE MKT, interval(Date -270 -20) by(id) //estimate OLS regression by firm over interval -20 to -270
    gen AbnReturn=. //create abnormal return
    forvalues i=1/3{
    replace AbnReturn= ReturnE -b_MKT[_n-`i']*MKT - b_cons[_n-`i'] if eventwindow==`i'
    } //calculate abnormal returns for event window days
    replace AbnReturn=. if reg_nobs<1 //drop abnormal return if estimation window has less than 1 observation
    
    by id: gen CAAR= AbnReturn[_n-1]+AbnReturn[_n]+AbnReturn[_n+1]  if eventdummy05==1 //calculate cumulative abnormal return per firm
    sum CAAR //calculate cumulative average abnormal return
    Many thanks.








  • #2
    Dear Glen,

    Thank you very much for using eventstudy2 and your questions.

    There are a few reasons why users sometimes cannot exactly replicate the results produced by eventstudy2:

    1) eventstudy2 expects discrete returns as inputs (unless the log option is specified) but internally works with continuously compounded returns ("log returns”). Consequently, the output is also based on continuously compounded returns. For good reasons, this cannot be changed. There is information on this in the helpfile. This might explain the deviation of your results from eventsudy2's output. Switching the "logreturns" option on might alleviate some of it.

    2) There might be an issue with nearmrg.ado, which is another very useful user-written command which eventstudy2 uses internally. If not modified with stable sorts (https://www.stata.com/statalist/arch.../msg00459.html), it sometimes makes eventstudy2 shifting event dates by one or two days for reasons that I have not yet fully understood. It is not just that nearmrg creates different results for different runs on the same data (which would be justified in scenarios with inconclusive matching possibilities), nearmrg really creates issues when everything should be unambiguous. Therefore, the first thing I do when installing nearmrg on a new machine is that I "stable" all its sorts. This reliably mitigates this issue.

    3) In more complex data sets where securities are traded on different markets, where there are different holidays, or if securities simply have some missing returns, eventstudy2 applies a quite complex algorithm based on Maynes and Rumsey’s JBF article (https://www.sciencedirect.com/scienc...85R?via%3Dihub). It is, in my opinion, the best way of handling missing returns, however, its programming is very complex and users typically cannot replicate this in their rather simplistic attempts the replicate eventstudy2’s results. There is a section of this in my recent Stata Journal publication (https://journals.sagepub.com/doi/abs...6867X211025835).

    Best
    Thomas

    Comment


    • #3
      Dear Thomas,

      Thank you very much for the detailed reply.

      I have followed your advice in 1) and used the log returns option. In the 1-factor model, the estimated CAAR from our code=0.0325 and in eventstudy2=0.0325, so this is good! In the 3-factor model (MKT, SMB, HML), our code=0.0348 and in eventstudy2=0.0335, so it is off very slightly.

      Could you perhaps explicitly explain how one could follow 2) and install nearmrg and change its sorts to "stable"? For example, would I install nearmrg after I have installed eventstudy2 and edit its ado file?

      For 3), your approach seems reasonable and I can review the links you kindly provide.

      Many thanks again.

      Glen

      Comment


      • #4
        Dear Glen,

        The last time I checked, nearmrg was still available via "ssc install nearmrg". I hope it still is.

        After downloading it, you have to search for the file nearmrg.ado on your harddrive. Please open it in the Stata editor, replace all "sort ..." with "sort ...., stable", save the changes and close all instances of Stata. On the next start of Stata, the changes will be effective.

        Best Thomas

        Comment


        • #5
          Dear Glen,

          Just another thought on the minor deviation when you use the 3FM.

          When you specify a riskfree rate in eventstudy2, it is substracted from both the security and market returns but not from the other factors, as the latter are zero investment portfolios. I am not 100% sure whether your code is consistent with that. I see a deduction of rf from the security returns but not the market return. While this slight difference might end up in the intercept in the 1FM and do no further harm, it might create the minor delta in the 3FM.
          Best Thomas

          Comment


          • #6
            Dear Thomas:

            Can you please specifiy how to run eventstudy2 for subsample, for exaple, I have panel data for different event date, like exeutive appointment, I will be spliting them into different groups, like different industry, how can I run it using eventstudy2 for event study? I was trying to use loop, but after completing couple of firms, they were displaying like "*** out of .event completed", but actually I haven't get it done yet, thus I wouldn't be able to run the different industry subsample completely, I have attached my code :
            Click image for larger version

Name:	Screenshot 2023-12-28 153940.png
Views:	1
Size:	143.3 KB
ID:	1738335



            Looking forward to hearing from you. Many thanks
            sincerely |
            Emiliy

            Comment

            Working...
            X