Acelerar el cálculo de WMA (promedio móvil ponderado)

Estoy tratando de calcular el promedio móvil exponencial en barras de 15 días, pero quiero ver la "evolución" de la EMA de barra de 15 días en cada (fin de) día / barra. Entonces, esto significa que tengo barras de 15 días. Cuando se reciben nuevos datos a diario, me gustaría volver a calcular EMA utilizando nueva información. En realidad, tengo barras de 15 días y luego, después de cada día, mi nueva barra de 15 días comienza a crecer y se supone que cada barra nueva que aparece se usa para el cálculo de EMA junto con las barras completas de 15 días anteriores.

Dejemos que comencemos en 2012-01-01 (tenemos datos para cada día del calendario para este ejemplo), a fines de 2012-01-15 tenemos la primera barra completa de 15 días. Después de completar 4 barras completas de 15 días el 01-03-2012 podemos comenzar a calcular la EMA de 4 barras (EMA (x, n = 4)). A finales de 2012-03-02 usamos la información que tenemos hasta este momento y calculamos EMA en 2012-03-02 pretendiendo que OHLC para 2012-03-02 es la barra de 15 días en progreso. Entonces tomamos las 4 barras completas y la barra el 2012-03-02 y calculamos EMA (x, n = 4). Luego esperamos otro día, vemos lo que sucedió con la nueva barra de 15 días en progreso (vea la función para.período, acumulativo a continuación para más detalles) y calculamos un nuevo valor para EMA ... Y así durante los próximos 15 días en adelante ... Ver función EMA.cumulativo a continuación para más detalles ...

A continuación, encuentre lo que pude encontrar hasta ahora. El rendimiento no es aceptable para mí y no puedo hacerlo más rápido con mi conocimiento limitado de R.

library(quantmod)

do.call.rbind <- function(lst) {
    while(length(lst) > 1) {
        idxlst <- seq(from=1, to=length(lst), by=2)

        lst <- lapply(idxlst, function(i) {
                    if(i==length(lst)) { return(lst[[i]]) }

                    return(rbind(lst[[i]], lst[[i+1]]))
                })
    }
    lst[[1]]
}

to.period.cumulative <- function(x, name=NULL, period="days", numPeriods=15) {
    if(is.null(name))
        name <- deparse(substitute(x))

    cnames <- c("Open", "High", "Low", "Close")
    if (has.Vo(x)) 
        cnames <- c(cnames, "Volume")

    cnames <- paste(name, cnames, sep=".") 

    if (quantmod:::is.OHLCV(x)) {
        x <- OHLCV(x)
        out <- do.call.rbind( 
                lapply(split(x, f=period, k=numPeriods), 
                        function(x) cbind(rep(first(x[,1]), NROW(x[,1])), 
                                cummax(x[,2]), cummin(x[,3]), x[,4], cumsum(x[,5]))))
    } else if (quantmod:::is.OHLC(x)) {
        x <- OHLC(x)
        out <- do.call.rbind( 
                lapply(split(x, f=period, k=numPeriods), 
                        function(x) cbind(rep(first(x[,1]), NROW(x[,1])), 
                                cummax(x[,2]), cummin(x[,3]), x[,4])))
    } else {
        stop("Object does not have OHLC(V).")
    }

    colnames(out) <- cnames

    return(out)
}

EMA.cumulative<-function(cumulativeBars, nEMA = 4, period="days", numPeriods=15) {
    barsEndptCl <- Cl(cumulativeBars[endpoints(cumulativeBars, on=period,     k=numPeriods)])

    # TODO: This is sloooooooooooooooooow... 
    outEMA <- do.call.rbind(
            lapply(split(Cl(cumulativeBars), period), 
                    function(x) {
                        previousFullBars <- barsEndptCl[index(barsEndptCl) < last(index(x)), ]
                        if (NROW(previousFullBars) >= (nEMA - 1)) {
                                last(EMA(last(rbind(previousFullBars, x), n=(nEMA + 1)), n=nEMA))
                        } else {
                            xts(NA, order.by=index(x))
                        }
                    }))

    colnames(outEMA) <- paste("EMA", nEMA, sep="")

    return(outEMA)
}

getSymbols("SPY", from="2010-01-01")

SPY.cumulative <- to.period.cumulative(SPY, , name="SPY")

system.time(
        SPY.EMA <- EMA.cumulative(SPY.cumulative)
)

En mi sistema se necesita

   user  system elapsed 
  4.708   0.000   4.410 

El tiempo de ejecución aceptable sería inferior a un segundo ... ¿Es posible lograr esto usando R puro?

Esta publicación está vinculada aOptimizar el cálculo de promedios móviles: ¿es posible? donde no recibí respuestas. Ahora pude crear un ejemplo reproducible con una explicación más detallada de lo que quiero acelerar. Espero que la pregunta tenga más sentido ahora.

odas las ideas sobre cómo acelerar esto son muy apreciadas.

Respuestas a la pregunta(2)

Su respuesta a la pregunta