Here's the R code:

DV <- function(HLC, n=2, bounded=FALSE) {

# "HLC" is an _xts_ object with "High", "Low", and "Close"

# columns, in that order.

# This is David Varadi's alternative to the RSI(2). Calculations

# taken from the marketsci blog -- http://marketsci.wordpress.com

# Author of this implementation: Joshua Ulrich

# Calculate each day's high/low mean

hlMean <- rowMeans( HLC[,-3] )

# Calculate the running Mean of the Close divided by the

# high/low mean, then subtract 1.

res <- runMean( HLC[,3] / hlMean, n ) - 1

# If we want the bounded DV...

if(bounded) {

# Set the range to calculated the bounded DV

rng <- 252:NROW(res)

# Grab the index of the unbounded results, so we can convert

# the bounded results back to an xts object.

indx <- index(res)

# A simple percent rank function hack

pctRank <- function(x,i) match(x[i], sort(coredata(x[(i-251):i])))

# Apply the percent rank function to the coredata of our results

res <- sapply(rng, function(i) pctRank(res, i) / 252)

# Convert the bounded results to xts

res <- xts(c(rep(NA,251),res), indx)

}

# Return results

return(res)

}

## 6 comments:

hello josh,

If I want to sell the stock when the RSI retereat from the 90 or buy it when the RSI above 10 again how can I modify the code?

Hi Bear,

You need to use a lagged value of RSI in addition to the current value. The code below shows how to do it.

library(TTR)price <- .xts(20*cumprod(1+rnorm(50)/100),Sys.Date()-50:1)

rsi <- RSI(price,2)

rsiLag <- lag(rsi)

sig <- rep(0,50)

sig <- ifelse(rsiLag > 90 & rsi < 90, -1, sig)

sig <- ifelse(rsiLag < 10 & rsi > 10, 1, sig)

So

sigwill be '1' if yesterday's RSI (rsiLag) is less than 10 and today's RSI (rsi) is greater than 10.Hope that helps,

Josh

Thanks

Actually I am testing RSI(price,14), so the indicator may be under 20 or above 80 for a time and I use FOR loop instead of ifelse and lag but FOR is slow in R.

Is there any better solution?

The solution I posted above is better. You just have to change the "n" for the RSI function to "14" and the upper and lower bounds in the ifelse() statements to 80 and 20.

Hello Joshua,

Is there a reason why the result is sometimes of typeof "list" instead of "doubles" ?

When I load my datas from 1970 with quantmod the result is typeof "list"; and when I start from 1980 the result is typeof "double".

Thank you.

jipibelanger,

The result should always be an xts object. I'm not sure how you're getting a "list", but the high / low data prior to 1980 is poor for most Yahoo data.

Post a Comment