[R] Fibonacci technical analysis using data from getSymbols and quantmod

Eric Berger
2025-08-17T09:03:42Z

Hi Andre,
I have used quantmod but not these functions. I dumped your code into
ChatGPT5 and it gave the following answer which will hopefully be of help:

You?re getting that error because AAPL is an *OHLCV xts with multiple
columns*. runMin() / runMax() only accept a *single column (univariate)
series*. Two solid ways to fix it:

library(quantmod)

Fibonacci <- function(x, n = 55) {
  x <- try.xts(x, error = as.matrix)
  x  <- Cl(x)                           # <- make it univariate

  lo <- runMin(x, n = n)
  hi <- runMax(x, n = n)

  high   <- 0.618 * (hi - lo) + lo
  middle <- 0.5   * (hi - lo) + lo
  low    <- 0.382 * (hi - lo) + lo

  res <- cbind(na.spline(lo), na.spline(hi),
               na.spline(high), na.spline(middle), na.spline(low))
  colnames(res) <-
c("min","max","high","middle","low")
  reclass(res, x)
}

getSymbols("AAPL")
addFibonacci <- newTA(function(x) Fibonacci(x, n = 55), on = 1)
chartSeries(AAPL, TA = "addFibonacci()")

ALTERNATIVE FIX


library(quantmod)

Fibonacci <- function(x, n = 55) {
  x <- try.xts(x, error = as.matrix)

  lo <- runMin(Lo(x), n = n)            # rolling min of Lows
  hi <- runMax(Hi(x), n = n)            # rolling max of Highs

  high   <- 0.618 * (hi - lo) + lo
  middle <- 0.5   * (hi - lo) + lo
  low    <- 0.382 * (hi - lo) + lo

  res <- cbind(na.spline(lo), na.spline(hi),
               na.spline(high), na.spline(middle), na.spline(low))
  colnames(res) <-
c("min","max","high","middle","low")
  reclass(res, x)
}

getSymbols("AAPL")
addFibonacci <- newTA(function(x) Fibonacci(x, n = 55), on = 1)
chartSeries(AAPL, TA = "addFibonacci()")


HTH,

Eric



On Sun, Aug 17, 2025 at 10:56?AM Andr? Luiz Tietb?hl Ramos <
andreltramos at gmail.com> wrote:

> Hello,
>
> I'd like to integrate the Fibonacci graph as a TA indicator for stock
> analysis.  So fat I wasn't able to do so.  From the web, I found
something
> (below) but it didn't work either.
>
> My goal is to develop a function that uses the price column of a data frame
> along with the start and end dates of the period of interest, which are
> obtained from either its index or a given data frame column.  From these
> data the Fibonacci levels from the indicator are plotted.
>
>
>
https://stackoverflow.com/questions/20192913/how-to-create-a-technical-indicator-in-quantmod-package/79737478#79737478
>
> The Fibonacci function and indicator are below,
>
> 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)}
>
> addFibonacci <- function (..., on = 1, legend = "auto") {
>     #lchob <- get.current.chob()
>     lchob <- quantmod:::get.current.chob()
>     x <- as.matrix(lchob at xdata)
>     x <- Fibonacci(x = x)
>     yrange <- NULL
>     chobTA <- new("chobTA")
>     if (NCOL(x) == 1) {
>         chobTA at TA.values <- x[lchob at xsubset]
>     }
>     else chobTA at TA.values <- x[lchob at xsubset, ]
>     chobTA at name <- "chartTA"
>     if (any(is.na(on))) {
>         chobTA at new <- TRUE
>     }
>     else {
>         chobTA at new <- FALSE
>         chobTA at on <- on
>     }
>     chobTA at call <- match.call()
>     legend.name <- gsub("^add", "",
deparse(match.call()))
>     gpars <- c(list(...), list())[unique(names(c(list(), list(...))))]
>     chobTA at params <- list(xrange = lchob at xrange, yrange = yrange,
>         colors = lchob at colors, color.vol = lchob at color.vol, multi.col
> = lchob at multi.col,
>         spacing = lchob at spacing, width = lchob at width, bp = lchob at
bp,
>         x.labels = lchob at x.labels, time.scale = lchob at time.scale,
>         isLogical = is.logical(x), legend = legend, legend.name >
legend.name,
>         pars = list(gpars))
>     if (is.null(sys.call(-1))) {
>         TA <- lchob at passed.args$TA
>         lchob at passed.args$TA <- c(TA, chobTA)
>         lchob at windows <- lchob at windows + ifelse(chobTA at new, 1,
>             0)
>         chartSeries.chob <- chartSeries.chob
>         do.call("chartSeries.chob", list(lchob))
>         invisible(chobTA)
>     }
>     else {
>         return(chobTA)
>     }}
>
> Using the TA indicator function suggested I got,
>
> R> getSymbols("AAPL")
>
> [1] "AAPL"
> R> addFibonacci <- newTA(Fibonacci,on=1)
> R> chartSeries(AAPL, TA="addFibonacci()")
> Error in runMin(x, n = n) (from #4) :
>   ncol(x) > 1. runMin only supports univariate 'x'
> R> R> Fibonacci(AAPL)
> Error in runMin(x, n = n) (from #4) :
>   ncol(x) > 1. runMin only supports univariate 'x'
> R>
>
> Any help is greatly appreciated.
>
>
> Regards,
>
> --
> Andr? Luiz Tietbohl Ramos, PhD
>
>         [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> https://www.R-project.org/posting-guide.html