How to create event windows of cumulative abnormal returns?

I have two dataframes.

Dataframe 1: "fincomp"
Dataframe 1 contains 890 acquisition bids with the following variables:

  • Announcement date (ANDATE)
  • Company ID (PERMNO)
  • Bid ID (ID)
  • ROUND ID used to identify bidding competition rounds(ROUND_ID)
structure(list(ANDATE = structure(c(9521, 6502, 6500, 12359, 
14662, 5212), class = "Date"), PERMNO = c(81238L, 68806L, 68806L, 
NA, 85739L, 39271L), ID = c(533016020, 122837020, 20106020, 1447113020, 
2157920020, 154772043), ROUND_ID = c(26166, 50002, 50002, 16312, 
39087, 50024)), row.names = c(NA, 6L), class = "data.frame")

Dataframe 2: "r"
Dataframe 2 contains daily abnormal returns for each company with the following variables:

  • Company ID (PERMNO)
  • Date (DATE)
  • Daily abnormal return (AR_VM)
structure(list(PERMNO = c(10020L, 10020L, 10020L, 10020L, 10020L, 
10020L), DATE = structure(c(5866, 5870, 5871, 5872, 5873, 5874
), class = "Date"), AR_VM = c(NA, NA, 0.016231, 0.056379, 0.042756, 
-0.001765)), row.names = c(NA, 6L), class = "data.frame")

I want to compute the cumulative abnormal returns for the following event window:

  • -20 days to +180 days

Where the event is the bid announcement date.

In the end, my goal is to produce something like this:

I will be also running a regression where the CARs will be the dependent variable.

In other words, I need to match the two dataframes by PERMNO and date, and compute the cumulative abnormal returns for each company in the period -20 to +180 surrounding each bid announcement. I would like to have a return series at the end, so that I can use it for regression later.

Any idea on how to do this?

So let's take this in parts.

Part 1: Joining the Dataframes

You'll have to decide on what type of join you want to use.

An Inner Join will return only the rows that have a matching PERMNO in each dataframe.

merge(x=fincomp, y = r, by = 'PERMNO')

An Outer Join will return all the rows from each dataframe regardless of if there is a match.

merge(x=fincomp, y=r, by = 'PERMNO', all = T)

A Left Join will return all the rows of fincomp but only the rows of r that have a matching PERMNO.

merge(x=fincomp, y=r, by = 'PERMNO', all.x=T)

A Right Join will return all the rows of r but only the rows of fincomp that have a matching PERMNO.

merge(x=fincomp, y=r, by = 'PERMNO', all.y=T)

Part 2: Calculating the Cumulative Sum of Abnormal Return

I'm assuming that you'll be using an inner join. In order to find the cumulative sum, the function cumsum will do the trick and we'll be creating the new column using the mutate function from the dplyr package.


new_data <- merge(x=fincomp, y=r, by='PERMNO') 

mutate(new_data, AR_Cumulative = cumsum(AR_VM))

That's great, thank you!

How do I make sure the cum-sum formula is used on each stock though and then stopped before the next observation starts, and not just continued through all stocks considering they're in the same columns?

Also, any idea on how to create the event window?

Grouping by is pretty simple to do with the group_by function from the dplyr package, give this code a try:


new_data <- merge(x=fincomp, y=r, by='PERMNO') 

new_data %>%
  group_by(ID) %>%
  mutate(new_data, AR_Cumulative = cumsum(AR_VM))

In this example, I also used the %>% operator found in both the dplyr and magrittr packages. It's really handy for doing multiple operations on the same set of data while keeping it looking nice.

As for creating the event window you could do something like this short example that I wrote up:

dates <- seq(as.Date('2021-01-01'), as.Date('2021-04-30'), by = 'days')

date.dat <- data.frame(dates)

date.dat %>%
  mutate(Time_from_Day_0 = dates - as.Date('2021-02-28'))

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.