r滚动自定义功能

问题描述 投票:0回答:3

我正在尝试使用 Zoo 包在 R 中构建滚动止盈/止损检测功能。

    x <- as.data.frame(rnorm(10000, 0, 1))
    x$cumul <- cumsum(x[, 1])
    plot(x$cumul, type = 'l')
    y <- as.data.frame(x$cumul)

    level_break <- function(x, n, z){
    if (min(c(1:nrow(x))[x[, 1] > z]) <= n
        & (min(c(1:nrow(x))[x[, 1] > z]) < min(c(1:nrow(x))[x[, 1] < -z])
           | min(c(1:nrow(x))[x[, 1] < -z]) > n)){
        level <- 1

    }else if (min(c(1:nrow(x))[x[, 1] < -z]) <= n
           & (min(c(1:nrow(x))[x[, 1] < -z]) < min(c(1:nrow(x))[x[, 1] > z])
              | min(c(1:nrow(x))[x[, 1] > z]) > n)){
        level <- -1

    } else {
        level <- 0
    }
    return(level)
}

library(zoo)
yy <- rollapply(data = y$`x$cumul`, width = 1000, align = 'left', function(x) level_break(y, n = 1000, z = 1))

我确信我做错了什么。您能帮我了解如何使其发挥作用吗?否则我会很高兴得知某个包中有一个专用函数可以完全完成我正在做的事情。

在所有澄清之后:最终的止盈/止损功能:

#################### sl-tp

x <- as.data.frame(rnorm(10000, 0, 1))
x$cumul <- cumsum(x[, 1])
plot(x$cumul, type = 'l')
y <- as.data.frame(x$cumul)


level_break <- function(x, n, tp, sl) {
    if (min(c(1:length(x))[x > tp]) <= n
        & (min(c(1:length(x))[x > tp]) < min(c(1:length(x))[x < sl])
           | is.infinite(min(c(1:length(x))[x < sl])) == T)) {
        level <- 1

    }else if (min(c(1:length(x))[x < sl]) <= n
           & (min(c(1:length(x))[x < sl]) < min(c(1:length(x))[x > tp])
              | is.infinite(min(c(1:length(x))[x > tp])) == T)) {
        level <- -1

    } else {
        level <- 0
    }
    return(level)
}

library(zoo)

level <- 10
window <- 1000

start <- Sys.time()
yy <- rollapply(data = y$`x$cumul`
          , width = window
          , align = 'left'
          , function(x) level_break(x = x, n = window, tp = head(x + level, 1), sl = head(x - level, 1)))
Sys.time() - start

plot(yy, type = 'l')
r zoo
3个回答
6
投票

你的编排逻辑很好。我编写了一个简化版本的 rollapp 来演示它。

x = sample(1:1000,100,replace = T)
stop_loss = function(vec){
  if(vec[10]< 0.75*mean(vec)) return(TRUE)
  return(FALSE)
}

rollapply(x,width = 10,FUN = stop_loss)

输出如下:

[1]  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
[16] FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE
[31]  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE
[46]  TRUE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[61] FALSE  TRUE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
[76] FALSE  TRUE FALSE FALSE  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE FALSE
[91] FALSE

输入 100 时输出 91,宽度为 10-完美。这让你的逻辑有待测试。

看你写的内容,你的输入有问题。您将

dataframe y
传递到
level_break
函数中。一定是
x

现在,您已经编写了将

x
作为
dataframe
的函数,它作为
vector
进入。

这是我将您的代码更改为:

x <- as.data.frame(rnorm(10000, 0, 1))
x$cumul <- cumsum(x[, 1])
plot(x$cumul, type = 'l')
y <- as.data.frame(x$cumul)

level_break <- function(x, n, z){
  if (min(c(1:length(x))[x[1] > z]) <= n
      & (min(c(1:length(x))[x[1] > z]) < min(c(1:length(x))[x[1] < -z])
         | min(c(1:length(x))[x[1] < -z]) > n)){
    level <- 1

  }else if (min(c(1:length(x))[x[1] < -z]) <= n
            & (min(c(1:length(x))[x[1] < -z]) < min(c(1:length(x))[x[1] > z])
               | min(c(1:length(x))[x[1] > z]) > n)){
    level <- -1

  } else {
    level <- 0
  }
  return(level)
}

library(zoo)
yy <- rollapply(data = y$`x$cumul`, width = 1000, align = 'left', function(x) level_break(x, n = 1000, z = 1))

您需要检查最小条件 - 它会引发警告。 :)


0
投票

jackStinger,谢谢你敏锐的眼光。我确实混合了 x-y 和数据帧向量。我更新了代码,它似乎与 rollapply 一起工作得很好:

x <- as.data.frame(rnorm(10000, 0, 1))
x$cumul <- cumsum(x[, 1])
plot(x$cumul, type = 'l')
y <- as.data.frame(x$cumul)


level_break <- function(x, n, z){
    if (min(c(1:length(x))[x > z]) <= n
        & (min(c(1:length(x))[x > z]) < min(c(1:length(x))[x < -z])
           | is.infinite(min(c(1:length(x))[x < -z])) == T)){
        level <- 1

    }else if (min(c(1:length(x))[x < -z]) <= n
           & (min(c(1:length(x))[x < -z]) < min(c(1:length(x))[x > z])
              | is.infinite(min(c(1:length(x))[x > z])) == T)){
        level <- -1

    } else {
        level <- 0
    }
    return(level)
}

level_break(y, n = 1000, z = 21)

library(zoo)

yy <- rollapply(data = y$`x$cumul`, width = 100, align = 'left', function(x) level_break(x, n = 100, z = 1))

plot(yy, type = 'l')

我现在将 x 传递给我的函数,在该函数内它被视为向量。看起来效果很好。最后一行代码 - 绘制预期结果。非常感谢!


0
投票

V hlavních rolích hráli: 潘乌西特尔哈斯 潘·热迪特尔·埃尔纳 马特耶·埃德·利斯卡 Ve vedlejších rolích: 纳撒尼尔·佐佐里尼 托比亚什·珀尔克 什捷潘佩尔茨 卡米尔: 本杰明·尤雷克 马特耶·埃德·利斯卡 雷克维兹蒂: 马克斯·塞巴内克 托比亚什·珀尔克 什捷潘佩尔茨 马特耶·埃德·利斯卡 纳撒尼尔·佐佐里尼 本杰明·尤雷克 斯特日: 马特耶·埃德·利斯卡 纳撒尼尔·佐佐利亚尼

© www.soinside.com 2019 - 2024. All rights reserved.