问题
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