“变量(包括的点数)”的高效计算R中的移动平均线

发布于 2024-09-26 07:09:00 字数 449 浏览 7 评论 0原文

我正在尝试对日内数据的时间序列(即 10 秒)实现可变指数移动平均值。我所说的变量是指移动平均线中包含的窗口大小取决于另一个因素(即波动性)。我在考虑以下内容:

MA(t)=alpha(t)*price(t) + (1-alpha(t))MA(t-1),

其中 alpha 对应于例如变化的波动率指数。

在对大系列(超过 100000)点的回测中,这种计算给我带来了“麻烦”。我有完整的向量 alpha 和价格,但对于 MA 的当前值,我总是需要之前计算的值。因此,到目前为止我还没有看到矢量化解决方案???

我的另一个想法是尝试将已实现的 EMA(..,n=f()) 函数直接应用于每个数据点,方法是始终使用不同的 f() 值。但到目前为止我也没有找到快速的解决方案。

如果有人能帮助我解决我的问题,那就太好了???甚至关于如何构建可变移动平均线的其他建议也很棒。

提前谢谢很多 马丁

I'm trying to implement a variable exponential moving average on a time series of intraday data (i.e 10 seconds). By variable, I mean that the size of the window included in the moving average depends on another factor (i.e. volatility). I was thinking of the following:

MA(t)=alpha(t)*price(t) + (1-alpha(t))MA(t-1),

where alpha corresponds for example to a changing volatility index.

In a backtest on huge series (more than 100000) points, this computation causes me "troubles". I have the complete vectors alpha and price, but for the current values of MA I always need the value just calculated before. Thus, so far I do not see a vectorized solution????

Another idea, I had, was trying to directly apply the implemented EMA(..,n=f()) function to every data point, by always having a different value for f(). But I do not find a fast solution neither so far.

Would be very kind if somebody could help me with my problem??? Even other suggestions of how constructing a variable moving average would be great.

Thx a lot in advance
Martin

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沫雨熙 2024-10-03 07:09:00

通过 filter() 也可以实现非常高效的移动平均操作:

  ## create a weight vector -- this one has equal weights, other schemes possible
  weights <- rep(1/nobs, nobs)     

  ## and apply it as a one-sided moving average calculations, see help(filter)
  movavg <- as.vector(filter(somevector, weights, method="convolution", side=1)) 

这只是左侧,其他选择也是可能的。

A very efficient moving average operation is also possible via filter():

  ## create a weight vector -- this one has equal weights, other schemes possible
  weights <- rep(1/nobs, nobs)     

  ## and apply it as a one-sided moving average calculations, see help(filter)
  movavg <- as.vector(filter(somevector, weights, method="convolution", side=1)) 

That was left-sided only, other choices are possible.

謌踐踏愛綪 2024-10-03 07:09:00

对于时间序列,请参阅zoo包中的函数rollmean

实际上,您计算的不是移动平均值,而是某种加权累积平均值。 (加权)移动平均值类似于:

price <- runif(100,10,1000)
alpha <- rbeta(100,1,0.5)

tp <- embed(price,2)
ta <- embed(alpha,2)

MA1 <- apply(cbind(tp,ta),1,function(x){
    weighted.mean(x[1:2],w=2*x[3:4]/sum(x))
})

确保重新调整权重,使它们总和等于观测值的数量。

对于您自己的计算,您可以尝试类似的方法:

MAt <- price*alpha

ma.MAt <- matrix(rep(MAt,each=n),nrow=n)
ma.MAt[upper.tri(ma.MAt)] <- 0

tt1 <- sapply(1:n,function(x){
  tmp <- rev(c(rep(0,n-x),1,cumprod(rev(alpha[1:(x-1)])))[1:n])
  sum(ma.MAt[i,]*tmp)
})

这将平均值计算为 MAt 的线性组合,权重由 alpha 的累积乘积定义。

旁注:我假设索引位于 0 和 1 之间。

For timeseries, see the function rollmean in the zoo package.

You actually don't calculate a moving average, but some kind of a weighted cumulative average. A (weighted) moving average would be something like :

price <- runif(100,10,1000)
alpha <- rbeta(100,1,0.5)

tp <- embed(price,2)
ta <- embed(alpha,2)

MA1 <- apply(cbind(tp,ta),1,function(x){
    weighted.mean(x[1:2],w=2*x[3:4]/sum(x))
})

Make sure you rescale the weights so they sum to the amount of observations.

For your own calculation, you could try something like :

MAt <- price*alpha

ma.MAt <- matrix(rep(MAt,each=n),nrow=n)
ma.MAt[upper.tri(ma.MAt)] <- 0

tt1 <- sapply(1:n,function(x){
  tmp <- rev(c(rep(0,n-x),1,cumprod(rev(alpha[1:(x-1)])))[1:n])
  sum(ma.MAt[i,]*tmp)
})

This calculates the averages as linear combinations of MAt, with weights defined by the cumulative product of alpha.

On a sidenote : I assumed the index to lie somewhere between 0 and 1.

屋顶上的小猫咪 2024-10-03 07:09:00

我刚刚向 TTR 包添加了一个 VMA 函数来执行此操作。例如:

library(quantmod)  # loads TTR
getSymbols("SPY")
SPY$absCMO <- abs(CMO(Cl(SPY),20))/100
SPY$vma <- VMA(Cl(SPY), SPY$absCMO)
chartSeries(SPY,TA="addTA(SPY$vma,on=1,col='blue')")

x <- xts(rnorm(1e6),Sys.time()-1e6:1)
y <- xts(runif(1e6),Sys.time()-1e6:1)
system.time(VMA(x,y))  # < 0.5s on a 2.2Ghz Centrino

文档中的一些注释:

'VMA'计算可变长度
基于绝对值的移动平均线
'w' 的值。较高(较低)值
'w' 会导致 'VMA' 做出反应
更快(更慢)。

预编译的二进制文件应该位于R-forge 在 24 小时内。

I just added a VMA function to the TTR package to do this. For example:

library(quantmod)  # loads TTR
getSymbols("SPY")
SPY$absCMO <- abs(CMO(Cl(SPY),20))/100
SPY$vma <- VMA(Cl(SPY), SPY$absCMO)
chartSeries(SPY,TA="addTA(SPY$vma,on=1,col='blue')")

x <- xts(rnorm(1e6),Sys.time()-1e6:1)
y <- xts(runif(1e6),Sys.time()-1e6:1)
system.time(VMA(x,y))  # < 0.5s on a 2.2Ghz Centrino

A couple notes from the documentation:

‘VMA’ calculate a variable-length
moving average based on the absolute
value of ‘w’. Higher (lower) values
of ‘w’ will cause ‘VMA’ to react
faster (slower).

The pre-compiled binaries should be on R-forge within 24 hours.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文