【问题标题】:R programming cumulative returns period calculations using data tableR编程使用数据表计算累积回报期
【发布时间】:2016-04-22 13:21:29
【问题描述】:

我想就如何创建新的股票累积回报列数据请求一些帮助。我的数据结构如下:

Month      Stock    Ret
    
Jan-2001    A       0.01    
Feb-2001    B       0.02    
Jan-2002    B       0.01    
Feb-2002    B       0.03

数据为 10 年。我想计算每只股票以 12 个月为增量的累积回报。

例如,第一个回报期将涵盖 2001 年 1 月至 2001 年 12 月。第二个时期是从 2001 年 2 月到 2002 年 1 月等。

这些计算将针对每只股票进行,并在每个周期计算中使用非累积回报。由于多年来我有很多股票,我想看看是否有比 for 循环更有效的方法来进行这些计算。

我一直在寻找尝试使用 data.table 包的方法,但我不确定如何做到这一点。

编辑:

也许我的循环函数可以更好地解释我想要实现的目标。

my.data <- data.frame(Date = seq.Date(as.Date('2001-01-01'), by ='month', length = 24), stock = factor(c(rep('A', 2*12), rep('B', 2*12))), Ret = c(rep(c(.02,.01,0,.03,.02,.01,02,.01,0,.03,.02,.01), 2)))  

final_table <- list()
num_periods <- 2*12-12


for(i in unique(my.data$stock)){

  ts_i = ts(my.data[my.data$stock==i, 'Ret'])

  table_i = matrix(nrow=length(ts_i), ncol=15)

  num_periods = length(ts_i)-12

  table_i[,1] = ts_i

  table_i[,14] = i

  table_i[,15] = ts(my.data[my.data$stock==i,'Date'])

  for(j in 1:num_periods){
     myperiod = cumprod(ts_i[j:(j+11)]+1)-1
     table_i[12+j,2:13] = myperiod
  }
 colnames(table_i) = c('original', paste0('p',-12:-2),'p1','stock','Date')
 final_table[[i]] = table_i
}

new.my.data = do.call('rbind',final_table)

new.my.data = na.omit(new.my.data)

【问题讨论】:

  • 问题缺乏可重复的例子
  • 也许我的循环函数可以更好地解释我想要实现的目标。

标签: r data.table


【解决方案1】:

如果我理解正确,您想要个股的年 Ret 总和。首先,我会通过

从您的数据中提取年份
df <- cbind(do.call('rbind',strsplit(df$Month,"-")),df[,c(2,3)])
names(df)[c(1,2)] <- c("Month","Year")

然后按年份和库存汇总数据

aggregate(df[,"Ret"],by=list("Year" = df$Year,"Stock"=df$Stock),FUN=sum)

以这种格式生成 df

  Year Stock    x
1 2001     A 0.04
2 2002     B 0.04
3 2003     B 0.02

并且将其可视化应该不是问题。

编辑:

这个怎么样?

aggregate(df[,"Ret"],by=list("Year" = df$Year,"Stock"=df$stock),FUN= function(x) {return (cumprod (x+1)-1)} )

应该会产生这样的结果:

  Year Stock        x.1        x.2        x.3        x.4        x.5       x.6         x.7        x.8        x.9       x.10       x.11       x.12
1 2001     A 0.02000000 0.03020000 0.03020000 0.06110600 0.08232812 0.09315140 2.27945420 2.31224875 2.31224875 2.41161621 2.47984853 2.51464702
2 2002     A 0.02000000 0.03020000 0.03020000 0.06110600 0.08232812 0.09315140 2.27945420 2.31224875 2.31224875 2.41161621 2.47984853 2.51464702
3 2001     B 0.02000000 0.03020000 0.03020000 0.06110600 0.08232812 0.09315140 2.27945420 2.31224875 2.31224875 2.41161621 2.47984853 2.51464702
4 2002     B 0.02000000 0.03020000 0.03020000 0.06110600 0.08232812 0.09315140 2.27945420 2.31224875 2.31224875 2.41161621 2.47984853 2.51464702

这是每年报告一次,但我认为您可以对月/年进行操作和分类,以便轻松满足您的要求。

【讨论】:

  • 您好 Marek,感谢您的回复。你提供的例子不是我想要的。我编辑了我的问题以包含我正在寻找的示例代码。
【解决方案2】:

我认为 cumprod 函数可以进行您想要的计算:

taxes <- c(0.2, 0.4, 0.3)
cum_taxes = cumprod(taxes + 1) - 1

因此,问题的技巧部分是将数据分解为所需的块,即不同的年份。 split 函数是一个不错的选择: (让我在拆分之前将字符串日期值转换为 Date 类型并对其进行排序...)

df <- tibble(a = c('1991-10-01', '1991-11-01', '1991-12-01', '1992-01-01','1992-02-01'), 
              b = c(0.5, 0.6, 0.8, 1.2, 1.4))
df <- df %>% 
  mutate(
    a = as.Date(a),
    y = year(a)
  ) %>% 
  arrange(
    a
  )

split_df <- split(df, df$y)

现在,我们可以为每个数据子集应用 cumprod。 由于 split_df 是一个列表,我们希望对每个列表元素执行此操作(同上)。

split_df[[1]]$cum_taxes = cumprod(split_df[[1]]$b + 1) - 1

split_df[[2]]$cum_taxes = cumprod(split_df[[2]]$b + 1) - 1

但这不是重复的好解决方案,而是让我们使用 tidyverse mapmap2 函数来完成这项工作:

cum_taxes <- map(split_df, ~(cumprod(.x$b + 1) - 1))
merged_df <- map2(split_df, cum_taxes, ~tibble(.x, cum_taxes=.y))
df <- do.call(rbind, merged_df)

或者……在一块……

df <- tibble(a = c('1991-10-01', '1991-11-01', '1991-12-01', '1992-01-01','1992-02-01'), 
              b = c(0.5, 0.6, 0.8, 1.2, 1.4))
df <- df %>% 
  mutate(
    a = as.Date(a),
    y = year(a)
  ) %>% 
  arrange(
    a
  )
split_df <- split(df, df$y)

cum_taxes <- map(split_df, ~(cumprod(.$b + 1) - 1))
df <- do.call(rbind, 
              map2(split_df, cum_taxes, ~tibble(.x, cum_taxes=.y)))

【讨论】:

    猜你喜欢
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    • 2013-12-02
    • 2020-08-12
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    • 1970-01-01
    相关资源
    最近更新 更多