apply - test multiple conditions before moving rows

£可爱£侵袭症+ 提交于 2019-12-24 07:58:53

问题


I want to use apply to iterate over a matrix comparing open and high prices to a limit.

I originally used a while loop but it was slow so moved to apply.

I have tried to +1 to the StartingRow as below.

Summary <- matrix(data=NA, nrow=1, ncol=1)
Overall <- matrix(data=NA, nrow=1, ncol=2)
Open <- matrix(data=NA, nrow=1, ncol=1)

MSingle <- function(x, StartingRow=1, Limit=0.01, StopLoss=0.01){
  Open = x[1]
  High = x[2]
  Low = x[3]
  #If the difference between High and Open exceeds Limit the function ends.
  if (!is.na(High-Open[StartingRow]) > Limit){
    Summary <<- 1
    Open <<- Open
    Row <<- cbind(Summary, Open)
    Overall <<- rbind(Overall, Row)
  }
  #If the difference between Open and Low exceeds the Stoploss the function ends.
  else if (!is.na(Open[StartingRow]-Low) > StopLoss){
    Summary <<- 0
    Open <<- Open
    Row <<- cbind(Summary, Open)
    Overall <<- rbind(Overall, Row)
  }
  #If neither of these are met then I want to compare the original Open price at time t...
  #...with the high and low prices at time t+1, t+2, and so on, until either of the first two...
  #...conditions is met.
  else{
    StartingRow = StartingRow + 1
  }
}

apply(EUR_USD2, 1, MSingle)

CORRECTION: This was initially lapply but it was an error on my part when copying code over, the result described is from apply.

Example of Matrix EUR_USD2

       Open    High     Low   Close
[1,] 1.20037 1.20100 1.20037 1.20100
[2,] 1.20083 1.20095 1.20017 1.20030
[3,] 1.20035 1.20043 1.20035 1.20043
[4,] 1.20041 1.20050 1.20031 1.20046
[5,] 1.20049 1.20049 1.20046 1.20048`
[6,] 1.20050 1.20050 1.20048 1.20048
[7,] 1.20050 1.20069 1.20032 1.20048
[8,] 1.20048 1.20054 1.20027 1.20050
[9,] 1.20051 1.20087 1.20047 1.20087
[10,] 1.20082 1.20097 1.20076 1.20094

Intended results:

High[1] = 1.20100
Open[1] = 1.20037
Difference is 0.00063 (which is < Limit)

Therefore I want to retain the same Open[1] but move to High[2].

High[2] = 1.20095
Open[1] = 1.20037

Difference is 0.00058 (which is < Limit) and so on, until the difference is greater than Limit (or less than stoploss) at which point the function starts again but with Open[2].

Result of apply:

     Summary    Open
          NA      NA
Open       1 1.20037
Open       1 1.20083
Open       1 1.20035
Open       1 1.20041
Open       1 1.20049
Open       1 1.20050
Open       1 1.20050
Open       1 1.20048
Open       1 1.20051

This result however is only comparing the (High-Open) to Limit for the same period.

I want to compare High-Open (the difference) to the Limit. If this exceeds the limit then the first condition is met. If the condition is not met then I want to retain the same Open price but compare that to the High of the next period and test again against the Limit.

Only then do I want apply to move onto comparing the Open and High from period 2 to Limit.

The Open price must remain the same until the condition is met. Currently apply is comparing High(t=1)-Open(t=1) to Limit but does not compare the Open to any future periods High Values.


回答1:


I'm not completely sure I understood the output you are expecting (you could add to your post and example of the exact result you expect), but something similar to what I propose might work:

s <- "Open High Low Close
1.20037 1.20100 1.20037 1.20100
1.20083 1.20095 1.20017 1.20030
1.20035 1.20043 1.20035 1.20043
1.20041 1.20050 1.20031 1.20046
1.20049 1.20049 1.20046 1.20048
1.20050 1.20050 1.20048 1.20048
1.20050 1.20069 1.20032 1.20048
1.20048 1.20054 1.20027 1.20050
1.20051 1.20087 1.20047 1.20087
1.20082 1.20097 1.20076 1.20094"

EUR_USD2 <- read.delim(textConnection(s), sep = " ")

myfun <- function(x, df, Limit, StopLoss) {

  highComp <- which(df$High - df$Open[x] > Limit)
  highCompMin <- if(length(highComp) == 0) 0 else min(highComp)
  lowComp <- which(df$Open[x] - df$Low > StopLoss)
  lowCompMin <- if(length(lowComp) == 0) 0 else min(lowComp)

  if(highCompMin == 0 & lowCompMin == 0) {
    result <- c(Summary = NA, Open = df$Open[x])
  } else if (highCompMin >= lowCompMin) {
    result <- c(Summary = 1, Open = df$Open[x])
  } else if (lowCompMin > highCompMin) {
    result <- c(Summary = 0, Open = df$Open[x])
  } else {
    result <- c(Summary = NA, Open = df$Open[x])
  }

  return(result)

}

t(sapply(1:nrow(EUR_USD2), function(x) myfun(x, df = EUR_USD2,
                                             Limit = 0.00062, StopLoss = 0.0005)))

### OUTPUT:
#      Summary    Open
# [1,]       1 1.20037
# [2,]       0 1.20083
# [3,]       1 1.20035
# [4,]      NA 1.20041
# [5,]      NA 1.20049
# [6,]      NA 1.20050
# [7,]      NA 1.20050
# [8,]      NA 1.20048
# [9,]      NA 1.20051
# [10,]      0 1.20082

For each row i compares EUR_USD2$Open[i] with the whole High and Low columns to find the minimum index that fulfills the comparisons and then sets Summary according to the result. The value is set to NA in case no value fulfills the comparisons.



来源:https://stackoverflow.com/questions/56838974/apply-test-multiple-conditions-before-moving-rows

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!