使用R或mysql来计算时间段的回报?

时间:2012-01-26 07:40:54

标签: mysql sql r

我正在尝试为数据集中的每个唯一成员(在下面的示例中由Code标识)计算各种时间段返回(每月,每季度,每年等)。该数据集将包含大约500种股票的20年期间的月度定价信息。下面是一个数据示例:

         Date Code    Price Dividend
1  2005-01-31  xyz  1000.00     20.0
2  2005-01-31  abc     1.00      0.1
3  2005-02-28  xyz  1030.00     20.0
4  2005-02-28  abc     1.01      0.1
5  2005-03-31  xyz  1071.20     20.0
6  2005-03-31  abc     1.03      0.1
7  2005-04-30  xyz  1124.76     20.0

我对R很新,但认为有一个更有效的解决方案,而不是循环遍历每个Code,然后是每个Date,如下所示:

uniqueDates <- unique(data$Date)
uniqueCodes <- unique(data$Code

for  (date in uniqueDates) {
  for (code in uniqueCodes) {
    nextDate <- seq.Date(from=stock_data$Date[i], by="3 months",length.out=2)[2]
    curPrice <- data$Price[data$Date == date]
    futPrice <- data$Price[data$Date == nextDate]
    data$ret[(data$Date == date) & (data$Code == code)] <- (futPrice/curPrice)-1
  }
}

此方法本身存在一个问题,seq.Date并不总是返回当月的最后一天。

不幸的是,数据不统一(公司/代码的数量随时间变化),因此使用简单的行偏移将不起作用。计算必须与CodeDate匹配,并具有所需的日期偏移量。

我最初尝试使用seq.Date功能

选择未来日期
data$ret = (data[(data$Date == (seq.Date(from = data$Date, by="3 month", length.out=2)[2])), "Price"] / data$Price) - 1

但是这会产生错误,因为seq.Date需要一个条目。

> Error in seq.Date(from = stock_data$Date, by = "3 month", length.out =
> 2) :    'from' must be of length 1

我认为R很适合这种类型的计算,但也许不是。由于所有数据都在mysql数据库中,我现在认为直接在数据库中执行此计算可能更快/更容易。

任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:2)

加载数据:

tc='
  Date Code    Price Dividend
  2005-01-31  xyz  1000.00     20.0
  2005-01-31  abc     1.00      0.1
  2005-02-28  xyz  1030.00     20.0
  2005-02-28  abc     1.01      0.1
  2005-03-31  xyz  1071.20     20.0
  2005-03-31  abc     1.03      0.1
  2005-04-30  xyz  1124.76     20.0'

df = read.table(text=tc,header=T)
df$Date=as.Date(df$Date,"%Y-%m-%d")

首先,我会按日期组织数据:

library(plyr)
pp1=reshape(df,timevar='Code',idvar='Date',direction='wide')

然后,您希望获得每月,每季度,每年等返回。 为此,有几个选项,一个可能是:

制作数据动物园或xts类。即

library(xts)
pp1[2:ncol(pp1)]  = as.xts(pp1[2:ncol(pp1)],order.by=pp1$Date)


#let's create a function for calculating returns.
rets<-function(x,lag=1){
  return(diff(log(x),lag))
}

由于此数据库是每月一次,因此退货的滞后将是: 每月= 1,quaterly = 3,year = 12。例如,让我们计算每月回报 为xyz。

lagged=1 #for monthly

这会计算xyz的每月回报

pp1$returns_xyz= c(NA,rets(pp1$Price.xyz,lagged))

获得所有回报:

#create matrix of returns

pricelist= ls(pp1)[grep('Price',ls(pp1))]

returnsmatrix = data.frame(matrix(rep(0,(nrow(pp1)-1)*length(pricelist)),ncol=length(pricelist)))

j=1
for(i in pricelist){
    n = which(names(pp1) == i)
    returnsmatrix[,j] =  rets(pp1[,n],1)
    j=j+1
}


#column names

codename= gsub("Price.", "", pricelist, fixed = TRUE)


names(returnsmatrix)=paste('ret',codename,sep='.')


returnsmatrix

答案 1 :(得分:2)

您可以使用quantmod和xts包轻松完成此操作。使用AndresT答案中的数据:

library(quantmod)  # loads xts too
pp1 <- reshape(df,timevar='Code',idvar='Date',direction='wide')
# create an xts object
x <- xts(pp1[,-1], pp1[,1])
# only get the "Price.*" columns
p <- getPrice(x)
# run the periodReturn function on each column
r <- apply(p, 2, periodReturn, period="monthly", type="log")
# merge prior result into a multi-column object
r <- do.call(merge, r)
# rename columns
names(r) <- paste("monthly.return",
  sapply(strsplit(names(p),"\\."), "[", 2), sep=".")

这会留下一个r xts对象,其中包含:

           monthly.return.xyz monthly.return.abc
2005-01-31         0.00000000        0.000000000
2005-02-28         0.02955880        0.009950331
2005-03-31         0.03922071        0.019608471
2005-04-30         0.04879016                 NA