I'm a newbie to R and I am facing some problems with the creation of a technical indicator. More specifically, I want to create an indicator, Fibonacci
, which will be added to the chartSeries
and will consist of 5 horizontal lines. The data I am working with are the closing prices of a stock. So the graph I want to create will have one horizontal line in the point of the max closing price, one horizontal line in the point of the min closing price and three horizontal lines between the previous two. The code I wrote in order to take the five values of a time series of closing prices of a stock is the following:
Fibonacci <- function(x) {
x <- try.xts(x, error = as.matrix)
n <- nrow(x)
min <- runMin(x,n=n)
max <- runMax(x,n=n)
high <- 0.62*(max-min) + min
middle <- 0.5*(max-min) + min
low <- 0.38*(max-min) + min
res <-cbind(na.spline(min),na.spline(max),na.spline(high),
na.spline(middle),na.spline(low))
colnames(res)<- c("min","max","high","middle","low")
reclass (res, x)
}
I also wrote the following code in order to add the technical indicator to the existing chartSeries
plot of quantmod
package :
addFibonacci<- function(col = "red",overlay = TRUE){
stopifnot("package:TTR" %in% search() || require("TTR", quietly = TRUE))
lchob <- quantmod:::get.current.chob()
x <- as.matrix(lchob@xdata)
chobTA <- new("chobTA")
chobTA@new <- !overlay
if (!is.OHLC(x))
stop("Fibonacci requires HL series")
else {
fibon <- Fibonacci(Cl(x))
}
[email protected] <- fibon[lchob@xsubset]
chobTA@call <- match.call()
chobTA@on <- 1
chobTA@params <- list(xrange = lchob@xrange, colors = lchob@colors,
color.vol = [email protected], multi.col = [email protected],
spacing = lchob@spacing, width = lchob@width, bp = lchob@bp,
x.labels = [email protected], time.scale = [email protected],
col = col)
if (is.null(sys.call(-1))) {
TA <- [email protected]$TA
[email protected]$TA <- c(TA, chobTA)
lchob@windows <- lchob@windows + ifelse(chobTA@new, 1,
0)
chartSeries.chob <- quantmod:::chartSeries.chob
do.call(chartSeries.chob, list(lchob))
invisible(chobTA)
}
else {
return(chobTA)
}
}
The problem is that the indicator is not getting added to the chart and I am also getting the following error message:
Error in do.call([email protected]$TA[[j]]@name, list([email protected]$TA[[j]])) :
'what' must be a character string or a function
Any ideas for what I am doing wrong?
Rather than writing the add*
function from scratch, you could just use newTA
:
> library(quantmod)
> getSymbols("AAPL")
[1] "AAPL"
> addFibonacci <- newTA(Fibonacci,on=1)
> chartSeries(AAPL, TA="addFibonacci()")
Error in addFibonacci() : could not find function "get.current.chob"
Hmm, apparently get.current.chob
isn't exported... that's okay, we can just change the function ourselves. After calling addFibonacci <- newTA(Fibonacci,on=1)
, addFibonacci
is defined as:
addFibonacci <- function (..., on = 1, legend = "auto")
{
#lchob <- get.current.chob()
lchob <- quantmod:::get.current.chob()
x <- as.matrix(lchob@xdata)
x <- Fibonacci(x = x)
yrange <- NULL
chobTA <- new("chobTA")
if (NCOL(x) == 1) {
[email protected] <- x[lchob@xsubset]
}
else [email protected] <- x[lchob@xsubset, ]
chobTA@name <- "chartTA"
if (any(is.na(on))) {
chobTA@new <- TRUE
}
else {
chobTA@new <- FALSE
chobTA@on <- on
}
chobTA@call <- match.call()
legend.name <- gsub("^add", "", deparse(match.call()))
gpars <- c(list(...), list())[unique(names(c(list(), list(...))))]
chobTA@params <- list(xrange = lchob@xrange, yrange = yrange,
colors = lchob@colors, color.vol = [email protected], multi.col = [email protected],
spacing = lchob@spacing, width = lchob@width, bp = lchob@bp,
x.labels = [email protected], time.scale = [email protected],
isLogical = is.logical(x), legend = legend, legend.name = legend.name,
pars = list(gpars))
if (is.null(sys.call(-1))) {
TA <- [email protected]$TA
[email protected]$TA <- c(TA, chobTA)
lchob@windows <- lchob@windows + ifelse(chobTA@new, 1,
0)
chartSeries.chob <- chartSeries.chob
do.call("chartSeries.chob", list(lchob))
invisible(chobTA)
}
else {
return(chobTA)
}
}
And you can see where I replaced the call to get.current.chob()
with quantmod:::get.current.chob()
. Now it should work.
chartSeries(AAPL, TA="addFibonacci()")
Success!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With