R/abnormal_returns.R

#' Abnormal Returns
#'
#' This function calculates the abnormal returns based on the input and aggregates them across assets.
#' Returns the normal residuals, AR, CAR, SCAR, and their averages over multiple assets.
#' @param return.data should be a data frame containing dates (Date) in the first column and returns in the rest.
#' @param market.data should be a data frame containing dates (Date) in the first column and market returns in the second.
#' @param model should be a chracter string: "constant-mean-return" or "market"
#' @param event.date should be a single row of the data frame created by the MakeEvents function.
#' @param event.window should be a vector of two elements representing the number of observations prior to and after the event date.
#' @param estimation.window is a numeric value representing the number of observations to estimate the normal returns over.
#' @keywords Keywords
#' @export
#' @examples
#' Examples
#' AbnormalReturns(return.data = ReturnData, market.data = MarketData, model = "constant-mean-return",
#' event.window = c(10,10), estimation.window = 90)
#' AbnormalReturns(return.data = ReturnData, market.data = MarketData, model = "market",
#' event.window = c(10,10), estimation.window = 90)

# This function calculates the abnormal returns based on the input and aggregates them across assets.
# Input:
# return.data should be a data frame containing dates (Date) in the first column and returns in the rest.
# market.data should be a data frame containing dates (Date) in the first column and market returns in the second.
# model should be a chracter string: "constant-mean-return" or "market"
# event.date should be a single row of the data frame created by the MakeEvents function.
# event.window should be a vector of two elements representing the number of observations prior to and after the event date.
# estimation.window is a numeric value representing the number of observations to estimate the normal returns over.
# Output:
# Returns a list of results including the normal residuals, AR, CAR, SCAR for a individual asset and the averages if multiple assets are included.
# Note that since we only study one asset, the individual and averages are the same. Returning the individual results for multiple assets has not been implemented!

AbnormalReturns <- function(return.data, market.data, model, event.date, event.window, estimation.window){
  # Set number of observations and assets in return.data and and event time vector
  observations <- nrow(return.data)
  assets <- ncol(return.data) - 1
  event.time <- c(-event.window[1]:event.window[2])

  # Set dates for estimation and event windows
  Event.date <- event.date[,2]
  Event.date.index <- match(Event.date, return.data$Date)
  event.dates <- return.data$Date[(Event.date.index - event.window[1]):(Event.date.index + event.window[2])]
  estimation.dates <- return.data$Date[(Event.date.index - event.window[1] - estimation.window):(Event.date.index - event.window[1] - 1)]

  # Create return and market estimation subsets
  estimation.return <- return.data[return.data$Date %in% estimation.dates,]
  estimation.market <- market.data[market.data$Date %in% estimation.dates,]

  # Create return and market event window subsets
  event.return <- return.data[return.data$Date %in% event.dates,]
  event.market <- market.data[market.data$Date %in% event.dates,]

  # Create result container for abnormal returns, cumulative abnormal returns, and standardized abnormal returns
  normal.residuals <- return.data[return.data$Date %in% estimation.dates,]
  AR <- cbind(event.time, return.data[return.data$Date %in% event.dates,])
  CAR <- AR
  SCAR <- AR

  if(model == "constant-mean-return"){
    normal.residuals <- ConstantMeanReturn(return.data = estimation.return, residuals = TRUE)
    normal.model <- ConstantMeanReturn(return.data = estimation.return, residuals = FALSE)
    for(i in 1:assets){
      AR[,i+2] <- event.return[,i+1] - as.numeric(normal.model[i])
      CAR[, i+2] <- cumsum(AR[,i+2])
      SCAR[,i+2] <- CAR[,i+2] / ((1 / (estimation.window - 2)) * as.numeric((t(normal.residuals[,i+1]) %*% normal.residuals[,i+1])))
    }
  }

  if(model == "market"){
    normal.residuals <- MarketModel(return.data = estimation.return, market.data = estimation.market, residuals = TRUE)
    normal.model <- MarketModel(return.data = estimation.return, market.data = estimation.market, residuals = FALSE)
    for(i in 1:assets){
      if(assets == 1){
        AR[,i+2] <- event.return[,i+1] - normal.model$coefficients[1] - (normal.model$coefficients[2] * event.market[,2])
      } else{
        AR[,i+2] <- event.return[,i+1] - normal.model[[i]]$coefficients[1] - (normal.model[[i]]$coefficients[2] * event.market[,2])
      }
      CAR[,i+2] <- cumsum(AR[,i+2])
      SCAR[,i+2] <- CAR[,i+2] / ((1 / (estimation.window - 2)) * as.numeric((t(normal.residuals[,i+1]) %*% normal.residuals[,i+1])))
    }
  }

  if(assets == 1){
    averages <- data.frame(cbind(event.dates, event.time, AR[,3:(assets+2)], CAR[,3:(assets+2)], SCAR[,3:(assets+2)]))
  } else {
    averages <- data.frame(cbind(event.dates, event.time, rowSums(AR[,3:(assets+2)])/assets, rowSums(CAR[,3:(assets+2)])/assets, rowSums(SCAR[,3:(assets+2)])/assets))
  }

  averages[,1] <- as.Date(averages[,1])
  names(averages) <- c("Date", "Event Time", "AR", "CAR", "SCAR")

  result <- list(normal.residuals, AR, CAR, SCAR, averages)
  names(result) <- c("Normal Residuals", "AR", "CAR", "SCAR", "Averages")

  return(result)
}
wbach12/p9eventstudy documentation built on May 4, 2019, 7:43 p.m.