Эффективное вычисление «переменной (с числом точек)» скользящей средней в R - PullRequest
2 голосов
/ 07 октября 2010

Я пытаюсь реализовать переменную экспоненциальную скользящую среднюю для временных рядов внутридневных данных (т.е. 10 секунд). Под переменной я подразумеваю, что размер окна, включенного в скользящую среднюю, зависит от другого фактора (то есть волатильности). Я думал о следующем:

MA (t) = альфа (t) * цена (t) + (1-альфа (t)) MA (t-1),

, где альфа соответствует, например, изменяющемуся индексу волатильности.

В тесте на огромные серии (более 100000) очков это вычисление вызывает у меня "неприятности". У меня есть полные векторы альфа и цена, но для текущих значений МА мне всегда нужно только что вычисленное значение. Таким образом, пока я не вижу векторизованного решения ????

У меня была еще одна идея - попытаться напрямую применить реализованную функцию EMA (.., n = f ()) к каждой точке данных, всегда имея различное значение для f (). Но я пока не нахожу быстрого решения.

Буду очень любезен, если кто-нибудь сможет мне помочь с моей проблемой ??? Даже другие предложения о том, как построить переменную скользящую среднюю, были бы хороши.

Спасибо заранее Мартин

Ответы [ 3 ]

3 голосов
/ 07 октября 2010

Очень эффективная операция скользящего среднего также возможна через 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)) 

Это было только слева, возможны другие варианты.

0 голосов
/ 10 октября 2010

Я только что добавил функцию VMA в пакет TTR, чтобы сделать это.Например:

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 часов.

0 голосов
/ 07 октября 2010

Для временных рядов смотрите функцию 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 с весами, определяемыми совокупным произведением альфа.

Обозначение: я предположил, что индекс лежит где-то между 0 и 1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...