r - 通过回溯根据其他列值更改 xts 中某些列的值

标签 r finance xts

我有以下 xts 对象(代表长/短条目(第 1 列和第 2 列)和退出(第 3 列和第 4 列)触发器,其中“聚合”信号列应为 1(系统长)、-1(系统很短)或 0(系统是平坦的)。我无法使此功能适用于“聚合”信号列 5...

数据:

         LongEntrySignal ShortEntrySignal LongExitSignal ShortExitSignal Signal
18.02.93               0                0              1               0      0
19.02.93               0                0              0               1      0
22.02.93               1                0              0               0      1
23.02.93               0                0              0               0      0
24.02.93               0                0              0               0      0
25.02.93               0                0              0               0      0
26.02.93               0                0              1               0      0
01.03.93               0                0              1               0      0
04.03.93               0                1              0               0     -1
05.03.93               0                0              0               0      0
11.03.93               0                0              0               1      0
12.03.93               0                0              1               0      0

我想将数据转换为这种形式:

         LongEntrySignal ShortEntrySignal LongExitSignal ShortExitSignal Signal
18.02.93               0                0              1               0      0
19.02.93               0                0              0               1      0
22.02.93               1                0              0               0      1
23.02.93               0                0              0               0      1
24.02.93               0                0              0               0      1
25.02.93               0                0              0               0      1
26.02.93               0                0              1               0      1
01.03.93               0                0              1               0      0
04.03.93               0                1              0               0     -1
05.03.93               0                0              0               0     -1
11.03.93               0                0              0               1     -1
12.03.93               0                0              1               0      0

我尝试对如下所示的函数进行uprogramming(但是id不起作用;注释掉的部分也不起作用并且非常慢 - 我知道在R中使用循环很慢,但这是我唯一的想法) :

padMinusPlusOnes<-function(signals, longEntryColumn=1, shortEntryColumn=2, signalsColumn=5) {   
    ret<-signals
#get all indexes between long entry equals 1 to long exit equals 1 and set signalsColumn for these rows to 1
    ret[(lag(ret)[, longEntryColumn] == 1) & (ret[, signalsColumn] == 0), signalsColumn]<-1
#get all indexes between short entry equals 1 to short exit equals 1 and set signalsColumn for these rows to -1
    ret[(lag(ret)[, shortEntryColumn] == -1) & (ret[, signalsColumn] == 0), signalsColumn]<--1

    return(ret)

#   ret<-signals
#   for (i in 2:NROW(ret)) {
#       if ((ret[i - 1, longEntryColumn] == 1) & (ret[, signalsColumn] == 0)) {
#           ret[i, signalsColumn]<-1
#       }
#       if ((ret[i - 1, shortEntryColumn] == -1) & (ret[, signalsColumn] == 0)) {
#           ret[i, signalsColumn]<--1
#       }
#   }
#   
#   return(ret)
}

感谢您在如何转换数据方面提供的帮助。

亲切的问候,萨摩。

编辑说明:在收到 Prasad Chalasani 和 J. Winchester 的两个非常有用且富有洞察力的答案后,我意识到我遗漏了有关数据结构的重要信息。因此,我更改了上面的数据以更好地反射(reflect)我的数据,并复制了原始数据(基于这两个答案)如下:

数据:

         LongEntrySignal ShortEntrySignal LongExitSignal ShortExitSignal Signal
18.02.93               0                0              0               0      0
19.02.93               0                0              0               0      0
22.02.93               1                0              0               0      1
23.02.93               0                0              0               0      0
24.02.93               0                0              0               0      0
25.02.93               0                0              0               0      0
26.02.93               0                0              1               0      0
01.03.93               0                0              0               0      0
04.03.93               0                1              0               0     -1
05.03.93               0                0              0               0      0
11.03.93               0                0              0               1      0
12.03.93               0                0              0               0      0

我想将数据转换为这种形式:

         LongEntrySignal ShortEntrySignal LongExitSignal ShortExitSignal Signal
18.02.93               0                0              0               0      0
19.02.93               0                0              0               0      0
22.02.93               1                0              0               0      1
23.02.93               0                0              0               0      1
24.02.93               0                0              0               0      1
25.02.93               0                0              0               0      1
26.02.93               0                0              1               0      1
01.03.93               0                0              0               0      0
04.03.93               0                1              0               0     -1
05.03.93               0                0              0               0     -1
11.03.93               0                0              0               1     -1
12.03.93               0                0              0               0      0

最佳答案

您不需要使用循环,也不需要“回顾”。您可以使用矢量化函数 cumsum 来获得您想要的结果。假设您的长进/退场和短进/退场周期不重叠,您可以这样做:首先组成虚拟信号:

n <- 15
zeros <- rep(0,n)
LongEnt <- replace(zeros, c(1, 12), 1)
LongEx <- replace(zeros, c(4, 14), 1)
ShortEnt <- replace(zeros, 6, 1)
ShortEx <- replace(zeros, 10, 1)

现在做一些cumsum魔法来获得正确的“聚合”信号列:

SigLong <- cumsum(LongEnt) - cumsum(LongEx) + LongEx
SigShort <- -cumsum(ShortEnt) + cumsum(ShortEx) - ShortEx
> cbind(LongEnt, LongEx, ShortEnt, ShortEx, Signal = SigLong + SigShort)
      LongEnt LongEx ShortEnt ShortEx Signal
 [1,]       1      0        0       0      1
 [2,]       0      0        0       0      1
 [3,]       0      0        0       0      1
 [4,]       0      1        0       0      1
 [5,]       0      0        0       0      0
 [6,]       0      0        1       0     -1
 [7,]       0      0        0       0     -1
 [8,]       0      0        0       0     -1
 [9,]       0      0        0       0     -1
[10,]       0      0        0       1     -1
[11,]       0      0        0       0      0
[12,]       1      0        0       0      1
[13,]       0      0        0       0      1
[14,]       0      1        0       0      1
[15,]       0      0        0       0      0

更新。根据OP修改后的问题,我们需要处理任意序列的进入/退出信号的情况,并找到第一个进入和相应的第一个退出之间的周期。这是一种通过非常简单的算术运算来做到这一点的方法(即没有昂贵的回溯或 if/else 检查)。我们只需要对 cumsum 函数进行一些小的修改,我将其称为 cumplus - 这就像 cumsum 一样,只不过在计算每个总和之后,它根据是否为正将其替换为 1 或 0:

cumplus <- function(y) Reduce(function(a,b) a + b > 0, y, 0, accum=TRUE)[-1]

(顺便说一句,Reduce 是一种紧凑定义累积函数的好方法,无需显式写出 for 循环 - 请参阅 ?Reduce详情)。

现在以进入/退出信号为例:

LongEnt <- c(1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 
0, 1, 0, 0)
LongEx <- c(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 
1, 0, 0, 1)

x <- LongEnt - LongEx  
z <- cumplus(x)

这几乎就是我们想要的......我们只需在每个个 block 的末尾插入 1 即可。

z <- z - c(0,pmin(0,diff(z)))

> cbind(LongEnt, LongEx, signal = z)
      LongEnt LongEx signal
 [1,]       1      0      1
 [2,]       0      0      1
 [3,]       0      0      1
 [4,]       1      0      1
 [5,]       0      0      1
 [6,]       0      0      1
 [7,]       1      0      1
 [8,]       0      0      1
 [9,]       0      1      1
[10,]       0      0      0
[11,]       0      0      0
[12,]       0      1      0
[13,]       1      0      1
[14,]       0      0      1
[15,]       0      0      1
[16,]       1      0      1
[17,]       0      0      1
[18,]       0      0      1
[19,]       0      1      1
[20,]       0      0      0
[21,]       0      1      0
[22,]       1      0      1
[23,]       0      0      1
[24,]       0      1      1

处理短期入场/出场当然是类似的。

关于r - 通过回溯根据其他列值更改 xts 中某些列的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5135087/

相关文章:

r - 如何通过 R 中的 xts 从分钟数据中提取/子集 day+0 到 day+1 索引时间?

css - Rvest,html_nodes 返回空列表和字符串,使用网站

r - R中过滤数据帧中低频数据的有效方法

r - 将整个页面隐藏在 r markdown 文档中

r - 处理 "accounting"格式的负数

r - R 中的 Quantstrat : Setting a date based exit signal

r - 使用递归函数的并行计算

python - 用 Python 计算 Keras 神经网络的准确性

Python Zipline 离线测试

r - 无法将 data.frame 对象转换为 xts 对象 : Gives POSIXlt error. (R)