15 일 막대의 지수 이동 평균을 계산하려고하지만 각 (끝) 날/막대의 15 일 막대 EMA의 "진화"를보고 싶습니다. 그래서, 나는 15 일간의 술집을 가지고 있음을 의미합니다. 새로운 데이터가 매일 들어 오면 새로운 정보를 사용하여 EMA를 다시 계산하고 싶습니다. 실제로 나는 15 일간의 바를 가지고 있고, 매일 매일 새로운 15 일간의 바가 커지기 시작하고 새로운 바가 EMA 계산에 사용되기로되어 있습니다.WMA (Weighted Moving Average) 계산 속도 향상
2012-01-01 (이 예에서는 각 캘린더 날짜에 대한 데이터가 있음)에서 시작한다고 가정 해 보겠습니다. 2012-01-15 끝 부분에 첫 번째 완전한 15 일 표시 줄이 있습니다. 2012-03-01에 4 일간의 15 일간의 바가 완료되면 4 바 EMA (EMA (x, n = 4))를 계산할 수 있습니다. 2012-03-02 끝에서 우리는이 순간까지 가지고있는 정보를 사용하고 2012-03-02에 대한 EMA를 계산합니다. 2012-03-02에 대한 OHLC가 진행중인 15 일 바입니다. 그래서 우리는 2012-03-02에 4 개의 완전한 막대와 막대를 가져 와서 EMA (x, n = 4)를 계산합니다. 그런 다음 다른 날을 기다리며, 진행중인 새로운 15 일 바가 어떻게되었는지 확인하고 (자세한 내용은 to.period.cumulative의 기능 참조) EMA에 대한 새로운 가치를 계산합니다 ... 앞으로 15 일 동안 ... 함수 EMA 자세한 내용은 아래에서 ...
아래에서 지금까지 무엇을 생각해 낼 수 있었는지 찾아보십시오. 성능은 나에게는 받아 들일 수 없으며 제한된 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)
)
는 그것이이 사용하는 순수 R을 달성 할 수 ...
user system elapsed
4.708 0.000 4.410
가능한 실행 시간이 1 초 미만이 될 것이라고한다?
이 게시물은 Optimize moving averages calculation - is it possible?에 연결되어있어서 답변을 찾을 수 없습니다. 이제는 속도를 높이려는 것에 대한 자세한 설명과 함께 재현 가능한 예제를 만들 수있었습니다. 나는 그 질문이 더 이해되기를 바란다.
속도를 높이는 방법에 대한 아이디어는 높이 평가됩니다.
허, 그렇다면 문제가 있습니다. 우리가 매일 데이터를 가지고 있다고합시다. 15 일 단위/바에 4 바 EMA (EMA (x, n = 4))를 계산하고 싶습니다. 따라서 to.period를 사용하여 일일 데이터를 15 일 막대로 변환합니다. 그렇게 쉬울 것입니다. 내가 원하는 것은 매일 15 일 바에 4 일간 EMA가 나타나기를 원합니다. 새로운 데이터가 계속 유입되면서 (거의) EMA의 실시간 그래프를 그리기를 원합니다. 마지막으로 알려진 데이터를 전체 15 일 막대로 간주합니다 (예 : 3 일 "오래된"일지라도). 그런 다음 당신이 지금 알고있는 것과 15 일 전의 모든 막대를 가져 와서 EMA를 계산하십시오. 더 좋아? – Samo
조슈아, 친절한 제안에 감사드립니다.그냥 경계와 출발 조건을 알리기 위해서 : 나는 작은 트레이딩 계좌를 가진 파트 타임 무익한 소매 상인/프로그래머로서 내 트레이딩을 지원하기위한 플랫폼으로서 R을 선택한 취미 (또는 프로그래밍 연습)로 만든다. 실제로) 활동. 나는 어떤 법인에 대해서도 상업적 목적으로 이것을 개발하지 않을 것이다. 나는 당신이 창조 한 모든 것과 자유 시간에 제공되는 모든 지원에 대해 매우 감사하고 있습니다. "무료"에 대한 다른 아이디어가 없다면 나는 확실히 당신의 친절한 제안을 받아 들일 것입니다. – Samo
여호수아, 이것에 대한 수입이 없습니다. 죄송합니다. C를 R과 함께 사용하는 방법을 배우는 데 "밀고 주셔서"고맙습니다. TTR의 C 및 Fortran 코드에 감사드립니다. – Samo