R data.table以三角形为单位的最后N行的总和减少距离

时间:2016-04-18 09:00:37

标签: r data.table

首先对问题的标题表示道歉,我不知道该怎么说。假设我有一个数据表 DT_RET ,它具有一段时间内股票的回报加上一个名为 N 的回测的保留期。例如。它看起来像这样:

Date          ReturnSinceYesterday        N    
2016-01-01    0.01                        5
2016-01-02    -0.025                      5 
2016-01-03    -0.021                      5
2016-01-04    0.005                       5
...
2016-01-01    0.01                        7
2016-01-02    -0.025                      7 
2016-01-03    -0.021                      7
2016-01-04    0.005                       7
...

现在我要添加到每一行,添加一个 TotalReturn 字段,对于某些给定的 N ,给出返回的最后一个 N 天并坚持到今天。例如。如果 N 5 ,最后 5返回+ 1.0 a,b,c,d,e 这将是:

((a.b.c.d.e - 1.0) + (b.c.d.e - 1.0) + (c.d.e - 1.0) + (d.e - 1.0) + (e - 1.0)) 

所以我的问题是如何做到这一点(使用data.table功能或其他R包)。

EDIT(上面的公式修正):

作为具体示例(根据要求),如果 N 3 且输入数据为:

Date          ReturnSinceYesterday        N    
2016-01-01    0.01                        3
2016-01-02    -0.025                      3 
2016-01-03    -0.021                      3
2016-01-04    0.005                       3

然后输出为:

Date         ReturnSinceYesterday         N     TotalReturn
2016-01-01    0.01                        3     NA          
2016-01-02    -0.025                      3     NA
2016-01-03    -0.021                      3     -0.1024
2016-01-04    0.005                       3     -0.05181

前两行有NA,因为计算的前置值不足。第三行的值为 -0.1024

a = 1.01
b = 0.975
c = 0.979
TotalReturn = ((a.b.c) -1) + ((b.c) - 1) + (c - 1)
TotalReturn = ((1.01 * 0.975 * 0.979) - 1) + ((0.975 * 0.979) - 1) + (0.979 - 1)
TotalReturn = -0.1024

由于

1 个答案:

答案 0 :(得分:3)

使用RcppRoll即可:

require(RcppRoll)
DT[,base := 1 + ReturnSinceYesterday]
DT[,TotalReturn := rowSums(sapply(seq_len(N), function(i) roll_prodr(base,i)-1))]

导致:

> DT
         Date ReturnSinceYesterday N  base TotalReturn
1: 2016-01-01                0.010 3 1.010          NA
2: 2016-01-02               -0.025 3 0.975          NA
3: 2016-01-03               -0.021 3 0.979 -0.10240475
4: 2016-01-04                0.005 3 1.005 -0.05180738
5: 2016-01-05                0.100 3 1.100  0.28778450

为什么呢?关键部分是:

> DT[, sapply(seq_len(3), function(i) roll_prodr(base,i)-1)]
       [,1]      [,2]        [,3]
[1,]  0.010        NA          NA
[2,] -0.025 -0.015250          NA
[3,] -0.021 -0.045475 -0.03592975
[4,]  0.005 -0.016105 -0.04070238
[5,]  0.100  0.105500  0.08228450

这为您提供了一个数据表 [,1] = c - 1[,2] = (b.c) -1[,3] = (a.b.c) -1。由于它是一个窗口函数,它依赖于N.因此,您可以在原始数据中使用data.tables by参数。

这也是关键部分。如果函数变慢,我猜是因为每个N都有一个NxM Tables构建。这可能会导致计算问题。您可以尝试使用((a.b.c) -1) + ((b.c) - 1) + (c - 1)自行实施?RcppRoll::rollit。我想这会更有效率

编辑: 例2例

require(data.table)
DT <- fread("Date          ReturnSinceYesterday        N    
2016-01-01    0.01                        3
            2016-01-02    -0.025                      3 
            2016-01-03    -0.021                      3
            2016-01-04    0.005                       2
            2016-01-05    0.1                         2")



require(RcppRoll)
DT[,base := 1 + ReturnSinceYesterday]

DT[, TotalReturn := rowSums(sapply(seq_len(N), function(i) roll_prodr(base,i)-1)), N]

结果和数据:

         Date ReturnSinceYesterday N  base TotalReturn
1: 2016-01-01                0.010 3 1.010          NA
2: 2016-01-02               -0.025 3 0.975          NA
3: 2016-01-03               -0.021 3 0.979  -0.1024048
4: 2016-01-04                0.005 2 1.005          NA
5: 2016-01-05                0.100 2 1.100   0.2055000