我有以下 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/