【问题标题】:Algorithmically detecting jumps in a time-series算法检测时间序列中的跳跃
【发布时间】:2019-09-25 10:19:09
【问题描述】:

我有大约 50 个数据集,其中包括 30 天内的所有交易,涉及 5 个交易所的大约 10 对。所有货币对都属于同一资产类别,这意味着它们具有很强的相关性,并期望具有相似的属性,但规模不同。该数据的一个示例是

set.seed(1)

n <- 1000
dates <- seq(as.POSIXct("2019-08-05 00:00:00", tz="UTC"), as.POSIXct("2019-08-05 23:59:00", tz="UTC"), by="1 min")
x <- data.frame("t" = sort(sample(dates, 1000)),"p" = cumsum(sample(c(-1, 1), n, TRUE)))

大致上,我需要确定每天发生的相关局部最小值和最大值。黄色标记是我的兴趣点。与此示例不同,通常每天只有一个这样的点,我每天都单独考虑。但是,很难从我的实际兴趣点中过滤掉噪音。

我的实际目标是找到两人开始跳跃的确切点以及跳跃结束的确切点。这需要尽可能准确,因为我想观察哪个资产首先移动以及哪个资产在哪个时间点跟随(如上所述,它们是高度相关的)。 在两个极值之间,我想最小化距离并最大化相对/绝对变化,因为我的兴趣点通常彼此靠近并且它们的差异很大。

我已经看过其他问题,例如 Finding local maxima and minimaAlgorithm to locate local maxima 以及 this 具有相同目标的算法。但是,我的数据集非常嘈杂。我已经将数据集减少到 5 分钟的间隔,但是,这导致省略了函数中的相关点来识别局部最小值和最大值。因此,考虑到我的目标,这不是一个好的解决方案。

如何使用相当准确的算法来实现我的目标?手动浏览所有时间序列不是一种选择,因为这需要我手动评估 50 * 30 时间序列,这太耗时了。我真的很困惑,试图找到一个合适的解决方案。

如果需要更多代码 sn-ps,我很乐意分享,但是它们没有给我有意义的结果,这与提供最小工作示例的想法相反,因此我决定将它们排除在外暂时。

编辑: 首先,我更新了绘图并向数据集添加了时间戳,以给您一个想法(实际分辨率)。理想情况下,该算法将检测左侧的两个跳跃。内部的两个点是因为它们靠得更近,并且不会被拦截,而外部的点是因为它们的值更极端。事实上,这可能回答了算法是否可以展望未来的问题。是的,如果在 30 次观测(或 30 分钟)范围内还有另一个局部极值,则忽略中间局部极值。 在我的数据中,跳跃从 2% 到 15%,因此跳跃需要至少为 2% 才能考虑。并且只有在达到峰值和谷值之前/之后在同一方向上连续执行 15 步(这可能是可调整的)的阈值时。

一种非常天真的方法是围绕一天的全局最小值和最大值对数据进行子集化。在大多数情况下,这已经对数据进行了去噪并用作指标。但是,当全局极值不在跳跃范围内时,这并不稳健。

希望这能澄清为什么这不是一个统计问题(有一些测试可以确定是否发生了跳跃,但不是跳跃到达时间 afaik)。


如果有人想要一个真实的例子: this是对应图,this是相关时期的原始数据,this是缩减数据集。


【问题讨论】:

  • 请查看"Which site?" 了解一般问题。这是一个比我们在本网站上处理的更高级别的问题;我建议 Stack Exchange Statistics。
  • 也许我的问题描述有缺陷(在这种情况下我道歉并且一定会修改描述),但这主要是一个算法问题。我不需要像先知这样的工具来为我做出预测,不幸的是,对于这个特定问题没有可用的统计解决方案。你能告诉我这个问题在什么方面太高级了,我会相应地澄清。
  • 您的描述并非“有缺陷”,而是不完整。例如,您的左起第二个点表示一个高点,但稍微向右是一个更高的高点。你为什么不选择那个?您需要为局部极值定义规则:算法是否允许展望未来?如果两个局部极值靠近会发生什么(如图表中间所示)?需要多少局部极值与周围点不同?应该在什么范围内计算极值点?等等……
  • 有效积分!我将进行编辑

标签: r algorithm optimization finance quantitative-finance


【解决方案1】:

也许作为一个起点,看看函数streaks 在包PMwR(我维护)中。一个条纹是 定义为指定大小的移动 不会被同样大小的反击打断。这 函数适用于返回,而不是差异,所以我添加 100 到您的数据。

例如:

set.seed(1)
n <- 1000
x <- 100 + cumsum(sample(c(-1, 1), n, TRUE))

plot(x, type = "l")
s <- streaks(x, up = 0.12, down = -0.12)
abline(v = s[, 1])
abline(v = s[, 2])

垂直线显示条纹的开始和结束。

也许您随后可以按所需标准(例如长度)过滤已识别的条纹。要么 你可以玩弄不同的阈值 和向下移动(虽然这不是真的推荐 在当前的实施中,但也许结果 足够好)。例如,上升条纹可能如下所示。绿色的垂直线表示连胜的开始;红线表示它的结束。

plot(x, type = "l")
s <- streaks(x, up = 0.12, down = -0.05)
s <- s[!is.na(s$state) & s$state == "up", ]
abline(v = s[, 1], col = "green")
abline(v = s[, 2], col = "red")

【讨论】:

  • 非常感谢您的努力!看起来很有希望,我会在我的真实数据集上对其进行测试后查看并报告
  • 这似乎正是我要找的!另外,我很高兴看到它非常拒绝噪音。但是,结果仍然是随机的:imgur.com/a/viIHWco(不工作),imgur.com/a/I1xm5zX(工作)。我的真实输入数据是异构规模的,因此结果并不总是如预期的那样。以下是一些货币对的当前价格:0.5; 10; 60; 180; 1400; 5200.我想重新调整它们,但这会扭曲回报(从 5200 到 5400 的跳跃不等于从 99 到 101 的跳跃)。
  • 你调整过up/down参数吗?它们应该反映基础系列的波动性。
  • 我的阈值不够低,现在可以了。还检查了你的包的其余部分,非常有用和很棒的文档!再次感谢,您的解决方案为我节省了很多时间
猜你喜欢
  • 1970-01-01
  • 2017-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多