引用多行条件(for循环)

时间:2016-04-07 00:27:02

标签: r for-loop financial trading

我在使用for循环引用多行中发生的条件时遇到了问题。

这个想法如下。有一个包含LastPrice和KCT列的数据框。想要将SignalBinary列添加到数据帧,如果

1)LastPrice [j]> KCT [j]连续3行,&

2)LastPrice [j + 1] - LastPrice [j + 1 + 3]>在行j + 1到j + 1 + 10(即10行以下)的任何行中的图12中的

然后想在SignalBinary [i]中记录1。

df <- data.frame(nrow =20, ncol =2)
df <- data.frame(LastPrice = c(1221,1220,1220,1217,1216,1218,1216,1216,1217,1220,1219,1218,1220,1216,1217,1218,1218,1207,1206,1205), KCT = c(1218,1218,1219,1218,1221,1217,1217,1216,1219,1216,1217,1216,1219,1217,1218,1217,1217,1217,1219,1217))
df$SignalBinary <-for(j in1:20){for(i in1:10){ifelse (df$LastPrice[j]> df$KCT[j]& df$LastPrice[j+1]> df$KCT[j+1]& df$LastPrice[j+2]> df$KCT[j+2]& df$LastPrice[j+i]- df$LastPrice[j+i+3]>12,1,0)}}

基于这些数据,本来希望代码在第10行和第11行记录1,在其余部分记录0。但我做错了什么。运行代码不会给出错误消息,但它不会创建df $ SignalBinary。运行df $ SignalBinary表示NULL。

BTW的目的是将代码应用于大型价格数据库,以运行二进制信号的统计数据。

希望有人可以提供帮助。非常感谢你

2 个答案:

答案 0 :(得分:0)

有一件事是不正确的,那就是你没有从你的ifelse陈述中返回任何东西(如果条件是(不是),你当前有1和0作为动作)。我认为(但不要引用我)我已经以更简单的方式解决了您的问题,而没有使用嵌套的for循环。

df <- data.frame(nrow = 20, ncol = 2)
df <- data.frame(LastPrice = c( 1221, 1220, 1220, 1217, 1216,  1218 , 1216, 1216, 1217, 1220,     1219, 1218, 1220, 1216, 1217, 1218, 1218, 1207, 1206, 1205), KCT = c( 1218, 1218, 1219, 1218, 1221,  1217 , 1217, 1216, 1219, 1216, 1217, 1216, 1219, 1217, 1218, 1217, 1217, 1217, 1219, 1217))

df$SignalBinary <- as.numeric(df$LastPrice >= df$KCT & 
                      c(rep(FALSE ,3), diff(df$LastPrice, lag=3) >= 3)) 

所以我设置了向量必须满足的两个条件。首先,df$LastPrice必须大于(或等于)df$KCT。其次,df$LastPrice之间的滞后差必须大于或等于3.我用FALSE填充前3个值,使两个矢量具有可比较的长度。如果两个条件都满足,则会记录我转换为数字的TRUE,然后将新列放在data.frame中。

只需将您玩具示例中的值替换为应用程序所需的值,我认为这应该有效。

答案 1 :(得分:0)

解决!发布解决方案。比我想象的要复杂得多。不得不将StrongMove的大小从12改为3,否则根据我在本例中提供的数据不会得到任何信号。

#Data
df <- data.frame(LastPrice = c( 1221, 1220, 1220, 1217, 1216,  1218 , 1216, 1216, 1217, 1220, 1219, 1218, 1220, 1216, 1217, 1218, 1218, 1207, 1206, 1205), KCT = c( 1218, 1218, 1219, 1218, 1221,  1217 , 1217, 1216, 1219, 1216, 1217, 1216, 1219, 1217, 1218, 1217, 1217, 1217, 1219, 1217))

#Define inputs
StrongMoveWindow = 10     # up to this far below the current row
StrongMoveDur = 3         # check row against another this far down
StrongMoveSize = 3        # for a difference at least this big
PvsKCTDur = 3

#Set variables and define loop boundaries
base_rows = 1:(nrow(df) - StrongMoveDur)  # can't check more than this
candidate_max = pmin(base_rows + StrongMoveWindow, nrow(df) - StrongMoveDur) # for a given base row, this is the maximum row to start checking against
df$StrongMove = rep(NA, nrow(df))
df$SignalBinary = rep(NA, nrow(df)) # pre-allocate a vector of results

#Make StrongMove variable
for (i in seq_along(base_rows)) {
  df$StrongMove[i] = as.numeric(
    any(
      df$LastPrice[(i + 1):candidate_max[i]] - 
        df$LastPrice[((i + 1):candidate_max[i]) + StrongMoveDur] > StrongMoveSize))}

#Make ContPvsKCT variable
library(data.table)
setDT(df)
df[, SingPvsKCT := as.integer(LastPrice > KCT)]
df[, ContPvsKCT := do.call(pmin, shift(SingPvsKCT, 0:(PvsKCTDur-1), type="lead"))]

#Make SignalBinary variable
df$SignalBinary <- ifelse (df$ContPvsKCT == 1 & df$StrongMove == 1, 1, 0)

非常感谢@Gregor @HubertL @Chris @Psidom @brittenb @Frank