Looking at your Stack Overflow question, I think the main issue is that runMin() and runMax() functions require univariate (single column) data, but the OHLCV data from getSymbols() has multiple columns. Here's a potential solution with improvements to create a working Fibonacci retracement indicator:
library(quantmod) # Improved Fibonacci function with more standard retracement levels Fibonacci <- function(x, n = 50, price_col = "Close") { # Convert to xts if needed x <- try.xts(x, error = as.matrix) # Extract the appropriate price column if (price_col == "Close") { price_data <- Cl(x) } else if (price_col == "High") { price_data <- Hi(x) } else if (price_col == "Low") { price_data <- Lo(x) } else if (price_col == "HL") { # Use High for max and Low for min (more accurate for Fibonacci) lo <- runMin(Lo(x), n = n) hi <- runMax(Hi(x), n = n) } else { price_data <- Cl(x) # Default to Close } # Calculate rolling min/max if not using HL method if (price_col != "HL") { lo <- runMin(price_data, n = n) hi <- runMax(price_data, n = n) } # Calculate Fibonacci retracement levels (standard levels) fib_0 <- lo # 0% level (bottom) fib_236 <- 0.236 * (hi - lo) + lo # 23.6% fib_382 <- 0.382 * (hi - lo) + lo # 38.2% fib_50 <- 0.5 * (hi - lo) + lo # 50% fib_618 <- 0.618 * (hi - lo) + lo # 61.8% fib_786 <- 0.786 * (hi - lo) + lo # 78.6% fib_100 <- hi # 100% level (top) # Combine results res <- cbind(fib_0, fib_236, fib_382, fib_50, fib_618, fib_786, fib_100) # Apply na.spline to smooth any NA values res <- apply(res, 2, na.spline) # Set column names colnames(res) <- c("Fib_0", "Fib_23.6", "Fib_38.2", "Fib_50", "Fib_61.8", "Fib_78.6", "Fib_100") # Reclass to maintain xts properties reclass(res, x) } # Create the TA indicator using newTA addFibonacci <- newTA(FUN = Fibonacci, preFUN = NULL, col = c("darkred", "red", "orange", "yellow", "green", "blue", "darkblue"), legend = "Fibonacci", on = 1) # Example usage getSymbols("AAPL", from = "2023-01-01") # Method 1: Using Close prices chartSeries(AAPL, theme = chartTheme("white"), TA = "addFibonacci(n=50, price_col='Close')") # Method 2: Using High/Low for more accurate support/resistance chartSeries(AAPL, theme = chartTheme("white"), TA = "addFibonacci(n=50, price_col='HL')") Alternatively, If you want a simpler version that just fixes your original code: library(quantmod) Fibonacci <- function(x) { x <- try.xts(x, error = as.matrix) # Fix: Extract Close prices to make it univariate x_close <- Cl(x) n <- nrow(x_close) # Now runMin/runMax will work min <- runMin(x_close, n = n) max <- runMax(x_close, 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) } # Get data and create indicator getSymbols("AAPL") addFibonacci <- newTA(Fibonacci, on = 1, col = c("blue", "red", "green", "yellow", "orange")) chartSeries(AAPL, TA = "addFibonacci()") Key changes applied: Used Cl(x) to extract only Close prices, making the data univariate Added flexibility to choose which price column to use Added standard Fibonacci levels (23.6%, 38.2%, 50%, 61.8%, 78.6%) Improved the High/Low method for more accurate support/resistance levels Added proper color coding for visual clarity The error you were getting (runMin only supports univariate 'x') was because AAPL data has multiple columns (Open, High, Low, Close, Volume), but runMin() and runMax() need single-column data. The fix is to extract just one price column before applying these functions. This may help - All the best! Gregg Powell Sierra Vista, AZ On Sunday, August 17th, 2025 at 12:56 AM, André Luiz Tietböhl Ramos <andreltra...@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@xdata) > x <- Fibonacci(x = x) > yrange <- NULL > chobTA <- new("chobTA") > if (NCOL(x) == 1) { > chobTA@TA.values <- x[lchob@xsubset] > } > else chobTA@TA.values <- 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 = lc...@color.vol, multi.col > = lc...@multi.col, > spacing = lchob@spacing, width = lchob@width, bp = lchob@bp, > x.labels = lchob@x.labels, time.scale = lchob@time.scale, > isLogical = is.logical(x), legend = legend, legend.name = legend.name, > pars = list(gpars)) > if (is.null(sys.call(-1))) { > TA <- lc...@passed.args$TA > lc...@passed.args$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) > }} > > 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@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 > and provide commented, minimal, self-contained, reproducible code.
signature.asc
Description: OpenPGP digital signature
______________________________________________ R-help@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 and provide commented, minimal, self-contained, reproducible code.