joshuaulrich / TTR

Technical analysis and other functions to construct technical trading rules with R
GNU General Public License v2.0
330 stars 103 forks source link

[R-Forge #2646] An improvement for the TTR::DVI function #2

Closed joshuaulrich closed 9 years ago

joshuaulrich commented 9 years ago

Submitted by: ivan popivanov Assigned to: Joshua Ulrich R-Forge link

(A copy of my email sent to the maintainer)

Hello,

Let me first outline the 'problem' I see with the TTR::DVI indicator:

library(quantmod) spy=getSymbols('SPY', from='1900-01-01', auto.assign=FALSE) spy.dvi.all = DVI(Cl(spy)) spy.dvi = DVI(Cl(spy)['2011-01-01']) spy.dvi.all['2012-01'] spy.dvi['2012-01']

The values for month of January are different. The reason is that when the rolling pctRank is performed on the 2011+ set, there are NAs in the mag and str vectors so the function ends up with different rankings.

In my opinion, we should start the computations later, when there are no NAs in the mag and str vector for the lookup period (defined by n). Please see the attachment for an illustration of the idea.

Regards, Ivan

Followups:

Date: 2013-04-19 03:32 Sender: Joshua Ulrich Replaced pctRank function with runPercentRank.

joshuaulrich commented 7 years ago

The R-Forge bug report included an attached file with the following contents:

DVIEx = function (price, n = 252, wts = c(0.8, 0.2), smooth = 3, magnitude = c(5, 
    100, 5), stretch = c(10, 100, 2)) 
{
    price <- try.xts(price, error = as.matrix)
    wts.sum <- sum(wts)
    wts[1] <- wts[1]/wts.sum
    wts[2] <- wts[2]/wts.sum
    r <- price/SMA(price, smooth) - 1
    mag <- SMA((SMA(r, magnitude[1]) + SMA(r, magnitude[2])/10)/2, 
        magnitude[3])
    b <- ifelse(price > lag(price), 1, -1)
    str <- SMA((runSum(b, stretch[1]) + runSum(b, stretch[2])/10)/2, 
        stretch[3])
    pctRank <- function(x, i) match(x[i], sort(coredata(x[(i - 
        (n - 1)):i])))
    dvi.mag <- dvi.str <- rep(NA, NROW(price))

    ii = 1
    len = NROW(price)

    # Find the first index for each both mag and str are not NAs
    while (ii <= len && (is.na(mag[ii]) || is.na(str[ii]))) {
        ii = ii + 1
    }

    # We want to start with n non-NA values
    ii = ii + n

    if (ii > len ) return(NULL)

    while (ii <= len) {
        dvi.mag[ii] <- pctRank(mag, ii)/n
        dvi.str[ii] <- pctRank(str, ii)/n
        ii = ii + 1
    }

    dvi <- wts[1] * dvi.mag + wts[2] * dvi.str
    reclass(cbind(dvi.mag, dvi.str, dvi), price)
}