【问题标题】:Calculate Abnormal Returns using a for() loop使用 for() 循环计算异常收益
【发布时间】:2014-03-28 12:59:55
【问题描述】:

有点复杂!我想使用 Fama-French 在事件日获得异常回报。时间窗口为:活动日前 250 天。

首先,我的 data.frames:

require(quantmod)
require(zoo)

# STOCK DATA.FRAME
BRCM <- as.data.frame(getSymbols.yahoo("BRCM", from="2000-01-01", verbose=F, auto.assign=F))
AAPL <- as.data.frame(getSymbols.yahoo("AAPL", from="2000-01-01", verbose=F, auto.assign=F))
MSFT <- as.data.frame(getSymbols.yahoo("MSFT", from="2000-01-01", verbose=F, auto.assign=F))

BRCM$Company <- c("BRCM")
AAPL$Company <- c("AAPL")
MSFT$Company <- c("MSFT")

BRCM$Return <- Delt(BRCM$BRCM.Adjusted)
AAPL$Return <- Delt(AAPL$AAPL.Adjusted)
MSFT$Return <- Delt(MSFT$MSFT.Adjusted)

colnames(BRCM) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted", "Company", "Return")
colnames(AAPL) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted", "Company", "Return")
colnames(MSFT) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted", "Company", "Return")

data <- rbind(BRCM, AAPL, MSFT)

data$Open <- NULL
data$Close <- NULL
data$High <- NULL
data$Low <- NULL
data$Volume <- NULL
data$Adjusted <- NULL

data$DATE <- row.names(data)

# EVENT DATA.FRAME
COMP <- c("BRCM", "AAPL", "AAPL", "MSFT", "BRCM", "BRCM", "MSFT")
DATE <- c("2003-03-04", "2004-12-01", "2002-12-03", "2008-02-08", "2003-10-10", "2005-12-12", "2003-11-14")

events <- data.frame(COMP, DATE)

events$AR <- paste("")

# FAMA FRENCH DATA.FRAME
date <- data$DATE
Mkt.RF <- sample(c(-2, -1.3, -0.9, -0.5, 0.15, 0.45, 0.95, 1.4, 1.8), size = nrow(data), replace=T)
SMB <- sample(c(-0.54, -0.41, -0.3, -0.21, -0.1, 0.12, 0.23, 0.34, 0.42, 0.6), size = nrow(data), replace= T)
HML <- sample(c(-0.54, -0.41, -0.3, -0.21, -0.1, 0.12, 0.23, 0.34, 0.42, 0.6), size = nrow(data), replace= T)

ff <- data.frame(date, Mkt.RF, SMB, HML)

对不起,我真的不擅长做这些例子。 到目前为止唯一重要的是,我们有 3 个 data.frames

  1. 数据(包含所有股票相关数据)
  2. 事件(包含所有事件相关数据)
  3. ff(包含所有 Fama-French 相关数据)

现在我想使用 for() 循环来计算异常收益 (AR)。 可能有一种更简单的方法可以做到这一点,但我想出了这个并且 我希望那里有一个天才,谁知道我想做什么!

# create R Objects for loop
companies <- as.vector(unique(events$COMP))
days <- as.vector(unique(data$DATE))
W <- lag(zoo(days), -c(0, 250:1))
ES_list <- vector("list", length = length(companies))


 for(i in 1:length(companies)) {

  data_k <- data[which(data$Company==companies[i]),] # all trading days for each firm
  events_k <- events[which(events$COMP==companies[i]),] # all event days for each firm

 for(j in 1:nrow(events_k)) {
  d = which(days==events_k[j,"DATE"])
  Z = W[d,] # time window assigned to each event-day (250 days)
  Y = data_k[which(is.na(match(data_k$DATE, Z) == F)), "RET"] # all Returns of time window (250days)
  X = cbind(rep(1, ncol(W)), ff[which(is.na(match(ff$DATE, Z) == F), c("Mkt.RF", "SMB", "HML"))]) # explaining variables
  b = (t(X) %x% X)^(-1) %x% t(X) %x% Y # my model to get coefficients to calculate abnormal return (AR)
  events_k[j, AR] = data_k[d, "Return"] -b[1] -b[2:4] %x% ff[d,2:4]
  ES_list[i] = events_k 
  }
}

ES = do.call(rbind, ES_list)

我认为这个循环应该可以工作,但它给我带来了错误:

Error in arr.ind && !is.null(d <- dim(x)) : invalid 'x' type in 'x && y'

有谁知道这意味着什么以及如何解决它?

输出应该是事件 (data.frame),其中有一列包含事件日的所有异常回报 (events$AR)。 谢谢你

【问题讨论】:

  • Error in nrow(mydf) : object 'mydf' not found
  • @rawr:谢谢,现在应该是正确的。
  • 我在这行W &lt;- lag(zoo(days), -c(0, 250:1)) 也收到错误,条件长度> 1,这导致动物园系列W 没有列,所以当您X = cbind(rep(1, ncol(W)) 时,我会收到另一个错误, 无效时间参数,因为 ncol(W) 为 NULL。您是否也遇到这些错误?
  • 是的,当我加载了一些额外的包时,我在这一行中遇到了错误。如果只有 base、quantmod 和 zoo,它应该可以工作。
  • 看起来你应该使用矩阵乘法运算符%*%,而不是%x%

标签: r for-loop


【解决方案1】:

我不明白您的代码为什么会失败,但我想我会使用 apply 系列函数而不是 for 循环。另外,我会尝试时间序列对象(我猜quantmod 返回xts 对象),这应该会使窗口选择更容易。

请注意,我使用的是包含 Fama 和 French 每日因子的数据框。 Ian Gow 提供代码here

以下内容返回一个xts 对象,每个事件有一列。从那里您应该能够获得您想要的任何摘要统计信息。如果我离得太远,请告诉我(我不知道更大的目标或代码)。

require(quantmod)
require(zoo)

# get data and find returns
tickers <- c("BRCM", "AAPL", "MSFT")
prices <- lapply(tickers, getSymbols, auto.assign=FALSE, from="2000-01-01")
my.ret <- function(x) {
    y <- dailyReturn(x, type="log")
    names(y) <- strsplit(names(x)[1], "\\.")[[1]][1]
    y
}
returns <- lapply(prices, my.ret)
returns <- merge(Reduce(merge, returns), read.zoo(ff_daily_factors), all=FALSE)

# EVENT DATA.FRAME
COMP <- c("BRCM", "AAPL", "AAPL", "MSFT", "BRCM", "BRCM", "MSFT")
DATE <- c("2003-03-04", "2004-12-01", "2002-12-03", "2008-02-08", "2003-10-10", "2005-12-12", "2003-11-14")

# my function to calculate predicted abnormal returns
my.AR <- function(x, tic, day) {
    x$exret <- x[, tic] - x[, "rf"]
    est.beg <- as.Date(day) - 280
    est.end <- as.Date(day) - 30
    model <- lm(exret ~ mktrf + smb + hml +umd, data=window(x, start=est.beg, end=est.end))
    pred.beg <- as.Date(day) - 29
    pred.end <- as.Date(day) + 29
    exret.hat <- predict(model, window(x, start=pred.beg, end=pred.end))
    exret.hat <- zoo(exret.hat, order.by=as.Date(names(exret.hat)))
    x <- merge(x, exret.hat)
    x$exret - x$exret.hat
}
ARs <- Reduce(merge, mapply(my.AR, tic=COMP, day=DATE, MoreArgs=list(x=returns), SIMPLIFY=FALSE))
names(ARs) <- paste0(COMP, DATE)
returns <- merge(returns, ARs)

这有帮助吗?

【讨论】:

  • @Richard Herron:谢谢你的回答!您的代码完美运行!只是,输出应该是一个与我的 data.frame “事件”完全一样的面板,带有一个附加列 AR。
  • 我只更改了 pred.beg
  • 太棒了。在这种情况下,您可以进行额外的合并以合并退货和 AR。
  • merge(returns, ARs)。我会把这个添加到答案中。
猜你喜欢
  • 1970-01-01
  • 2021-04-25
  • 2020-01-22
  • 2019-12-14
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多