André Luiz Tietböhl Ramos
2025-Aug-16 21:04 UTC
[R] Fibonacci technical analysis using data from getSymbols and quantmod
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]]
Eric Berger
2025-Aug-17 09:03 UTC
[R] Fibonacci technical analysis using data from getSymbols and quantmod
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
> and provide commented, minimal, self-contained, reproducible code.
>
[[alternative HTML version deleted]]
Bert Gunter
2025-Aug-17 09:07 UTC
[R] Fibonacci technical analysis using data from getSymbols and quantmod
I think you would do better posting on the R finance SIG list, https://stat.ethz.ch/mailman/listinfo/r-sig-finance, if it's still active rather than here for such a specific and technical post. Alternatively, and better, would be to check to see if the quantmod package has its own mailing list and post there, if so. (Unless Eric's ChatGPT code works for you of course). -- Bert On Sun, Aug 17, 2025 at 12: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 > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
Gregg Powell
2025-Aug-18 13:38 UTC
[R] Fibonacci technical analysis using data from getSymbols and quantmod
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
<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
> and provide commented, minimal, self-contained, reproducible code.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 603 bytes
Desc: OpenPGP digital signature
URL:
<https://stat.ethz.ch/pipermail/r-help/attachments/20250818/c5f00e9e/attachment.sig>