Search code examples
rloopsfor-looprepeattrading

Checking for condition present in multiple rows


I have a dataframe with columns LastPrice and KCT. The code then creates a third column, SignalBinary, and records on it a 1 when LastPrice > KCT for three consecutive rows.

(e.g. records a 1 in SignalBinary[1] when LastPrice[1] > KCT[1] AND LastPrice[2] > KCT[2] AND LastPrice[3] > KCT[3], and so on for every row)

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))

for(j in 1:nrow(df)) {
  df$SignalBinary[j] <- ifelse (  
    df$LastPrice[j] > df$KCT[j] 
    & df$LastPrice[j+1] > df$KCT[j+1] 
    & df$LastPrice[j+2] > df$KCT[j+2],
    1, 0)}

It works fine. But it is very basic. If I wanted to check for example LastPrice > KCT on 100 consecutive rows, I would need to write down the condition 100 times. Not ideal. Hence I would like to rewrite the code to be able to specify variable RowsToCheck = X, so as to check for the condition in X rows, without having to write the condition X times.

A for loop would work if I were to be checking for LastPrice > KCT in any 3 consecutive rows (i.e. using OR operators), rather than in 3 consecutive rows (i.e. using AND operators).


Solution

  • Can do this simply (and fast!) with data.table:

    library(data.table)
    setDT(df)
    df[, check := as.integer(LastPrice > KCT)]
    df[, Roll := Reduce('+',shift(check, 0:2L, type = "lead")) >= 3]
    

    Just change the 0:2 to 0:99 or 0:n, and the >=3 condition, and you are good to go.

    EDIT: As Frank points out, you can also use:

     df[, Roll := do.call(pmin, shift(check, 0:2, type="lead"))]
    

    I'm inclined to prefer this method as you only need to change one input as you vary the number of rows.

    I should also point out that this is extendable to the lagging case by changing the type argument to "lag"