diff --git a/NAMESPACE b/NAMESPACE
index a42f6df04..aac23c2b9 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -246,6 +246,11 @@ S3method(three_white_soldiers,data.frame)
S3method(three_white_soldiers,default)
S3method(three_white_soldiers,matrix)
S3method(three_white_soldiers,plotly)
+S3method(trading_volume,data.frame)
+S3method(trading_volume,default)
+S3method(trading_volume,matrix)
+S3method(trading_volume,numeric)
+S3method(trading_volume,plotly)
S3method(two_crows,data.frame)
S3method(two_crows,default)
S3method(two_crows,matrix)
@@ -369,9 +374,11 @@ export(three_line_strike)
export(three_outside)
export(three_stars_in_the_south)
export(three_white_soldiers)
+export(trading_volume)
export(triangular_moving_average)
export(triple_exponential_moving_average)
export(two_crows)
export(ultimate_oscillator)
+export(volume)
export(weighted_moving_average)
useDynLib(talib, .registration = TRUE)
diff --git a/R/chart.R b/R/chart.R
index 9199a2632..862d00819 100644
--- a/R/chart.R
+++ b/R/chart.R
@@ -23,6 +23,8 @@
#'
#' @param x An OHLC object to be charted.
#' @param type A [character] of [length] 1. Either `candlestick` or `ohlc`.
+#' @param idx A [vector] with the same [length] of `x`. If passed it will replace the x-axis labels. See `vignette("charting")` for more details.
+#' @param title An optional [character] vector of [length] 1.
#' @param ... Parameters passed into [plotly::plot_ly]
#'
#' @example man/examples/charting.R
@@ -31,6 +33,8 @@
chart <- function(
x,
type = "candlestick",
+ idx = NULL,
+ title,
...
) {
## clear env if called
@@ -54,6 +58,7 @@ chart.default <- function(
x,
type = "candlestick",
idx = NULL,
+ title,
...
) {
## default chart function
@@ -71,6 +76,15 @@ chart.default <- function(
## 3. chart: The user-facing TA chart.
## This is empty and is constructed on the fly
## via plotly::subplot.
+
+ ## extract title
+ if (missing(title)) {
+ chart_title <- input_name(
+ substitute(x)
+ )
+ } else {
+ chart_title <- title
+ }
.color_values <- .chart_theme()
.plotting_environment$sub <- .plotting_environment$chart <- list()
@@ -81,8 +95,27 @@ chart.default <- function(
## NOTE: it is also a hard requirement on
## {plotly} side
x <- as.data.frame(x)
- x$idx <- if (is.null(idx)) 1:nrow(x) else idx
+ x$idx <- if (is.null(idx)) {
+ ## check if rownames can be
+ ## converted to integer
+ is_valid <- suppressWarnings(
+ !is.na(as.integer(rownames(x)[1]))
+ )
+ if (is_valid) {
+ as.integer(
+ rownames(x)
+ )
+ } else {
+ rownames(x)
+ }
+ } else {
+ idx
+ }
.plotting_environment$x <- data_frame <- x
+ .plotting_environment$idx <- list(
+ label = x$idx,
+ index = seq_along(x$idx)
+ )
## generate price chart
## based on type. can be either
@@ -129,18 +162,50 @@ chart.default <- function(
alpha = 1 ## This should be controlled from .chart_theme()
)
),
+
+ ## remove legend
+ ## there is no reason to display
+ ## it in the legend.
+ ##
+ ## If there is demand for it we can
+ ## implement a heuristic to determine intervals
+ ## for 1h, 2h, etc. Similar to {cryptoQuotes}
+ showlegend = FALSE,
...
)
+ ## construct chart meta data
+ ##
+ ## There is no relevant information in the range 1:N
+ ## so if the rownames only contrains integers the chart will
+ ## skip it
+ if (is.integer(.plotting_environment$idx$label)) {
+ title_text <- sprintf(
+ fmt = "Ticker: %s
N: %d ",
+ chart_title,
+ nrow(x)
+ )
+ } else {
+ title_text <- sprintf(
+ fmt = "Ticker: %s
N: %d Period: %s ",
+ chart_title,
+ nrow(x),
+ paste(
+ .plotting_environment$idx$label[1],
+ "-",
+ .plotting_environment$idx$label[length(
+ .plotting_environment$idx$label
+ )]
+ )
+ )
+ }
+
## store in main chart
## (see description)
.plotting_environment$main <- .chart_layout(
x = price_chart,
- title_text = sprintf(
- "Ticker: %s
Period: %s",
- deparse(substitute(x)),
- "Period Value"
- )
+ title_text = title_text,
+ idx = idx
)
.plotting_environment$main
diff --git a/R/chart_elements.R b/R/chart_elements.R
index 83b8ce6a7..051451b27 100644
--- a/R/chart_elements.R
+++ b/R/chart_elements.R
@@ -1,11 +1,16 @@
-.chart_layout <- function(x, title_text, ...) {
+.chart_layout <- function(
+ x,
+ title_text,
+ idx = NULL,
+ ...
+) {
## extract chart theme
## from R/chart_options.R
chart_theme <- .chart_theme()
## hardcoded layout elements
## and added flexibility in ellipsis
- plotly::layout(
+ plotly_object <- plotly::layout(
p = x,
paper_bgcolor = chart_theme$paper_bgcolor,
plot_bgcolor = chart_theme$plot_bgcolor,
@@ -18,9 +23,11 @@
color = chart_theme$font_color
),
yaxis = list(
+ title = '',
gridcolor = chart_theme$grid_color
),
xaxis = list(
+ title = '',
gridcolor = chart_theme$grid_color,
rangeslider = list(
visible = getOption(
@@ -31,7 +38,10 @@
"talib.chart.slider.size",
default = 0.05
)
- )
+ ),
+ tickvals = seq_along(idx),
+ tickmode = "auto",
+ ticktext = idx
),
## legend start
@@ -75,6 +85,29 @@
...
)
+
+ ## add chart configurations
+ ## for TA
+ plotly::config(
+ p = plotly_object,
+
+ ## options for support
+ ## and resistance lines
+ modeBarButtonsToAdd = c(
+ "drawline",
+ "drawrect",
+ "eraseshape"
+ ),
+
+ ## remove {plotly} logo
+ ## to reduce clutter
+ ##
+ ## NOTE: Some of the other
+ ## buttons is most likely
+ ## redundant too. These will be
+ ## removed later (TM)
+ displaylogo = FALSE
+ )
}
@@ -101,3 +134,187 @@ add_title <- function(
)
)
}
+
+#' @title subchart
+#'
+#' @details
+#' A helper function for creating subcharts with prespecified
+#' xaxis and x values
+#'
+#' @param data [data.frame]
+#' @param ... arguments passed onto [plotly::plot_ly]
+#'
+#' @keywords internal
+subchart <- function(
+ data,
+ ...
+) {
+ ## main plotly object to
+ ## be added to the chart
+ plotly_object <- plotly::plot_ly(
+ data = data,
+ x = ~idx,
+ ...
+ )
+
+ ## finalize subcart
+ plotly_object <- plotly::layout(
+ plotly_object,
+
+ ## if this part is not added
+ ## there is mismatch between the
+ ## main chart and the subscharts
+ xaxis = list(
+ tickvals = seq_along(data$idx),
+ ticktext = data$idx,
+ ticmode = "auto"
+ )
+ )
+
+ ## readd configuations
+ ##
+ ## NOTE: This is repeated code
+ ## from .chart_layout()
+ ## - should be consolidated at
+ ## some point (TM)
+ plotly_object <- plotly::config(
+ p = plotly_object,
+
+ ## options for support
+ ## and resistance lines
+ modeBarButtonsToAdd = c(
+ "drawline",
+ "drawrect",
+ "eraseshape"
+ ),
+
+ ## remove {plotly} logo
+ ## to reduce clutter
+ ##
+ ## NOTE: Some of the other
+ ## buttons is most likely
+ ## redundant too. These will be
+ ## removed later (TM)
+ displaylogo = FALSE
+ )
+
+ return(plotly_object)
+}
+
+add_ribbons <- function(
+ plotly_object,
+ data,
+ x,
+ y,
+ ymin,
+ ymax,
+ color,
+ alpha,
+ showlegend,
+ legendgroup,
+ name,
+ dash
+) {
+ ## this function adds ribbons
+ ## to existing plots. It addresses the following
+ ## issue with plotly::add_ribbons: When adding lines it will
+ ## box on the right, but not on the left.
+
+ ## check if y have been passed
+ ## and
+ y_passed <- as.numeric(
+ !missing(y)
+ )
+
+ ## the name can apply to to each
+ ## line
+ if (length(name) < 3) {
+ name <- rep(name, 3)
+ }
+
+ if (length(dash) < 3) {
+ dash <- rep(dash, 3)
+ }
+
+ ## add ribbon without lines
+ plotly_object <- plotly::add_ribbons(
+ p = plotly_object,
+ inherit = FALSE,
+ data = data,
+ x = x,
+ ymin = ymin,
+ ymax = ymax,
+ line = list(
+ color = "transparent"
+ ),
+ fillcolor = plotly::toRGB(
+ x = color,
+ alpha = alpha * 0.5
+ ),
+ showlegend = showlegend,
+ legendgroup = legendgroup,
+ name = name[1]
+ )
+
+ if (!missing(y)) {
+ plotly_object <- plotly::add_lines(
+ p = plotly_object,
+ x = x,
+ y = y,
+ line = list(
+ color = plotly::toRGB(
+ x = color,
+ alpha = alpha
+ ),
+ dash = dash[1]
+ ),
+ showlegend = FALSE,
+ legendgroup = legendgroup,
+ inherit = FALSE,
+ name = name[1]
+ )
+ }
+
+ ## add lower line to the
+ ## plot
+ plotly_object <- plotly::add_lines(
+ p = plotly_object,
+ x = x,
+ y = ymin,
+ line = list(
+ color = plotly::toRGB(
+ x = color,
+ alpha = alpha
+ ),
+ dash = dash[2]
+ ),
+ showlegend = FALSE,
+ legendgroup = legendgroup,
+ inherit = FALSE,
+ name = name[2]
+ )
+
+ ## add upperline to the
+ ## plot
+ plotly_object <- plotly::add_lines(
+ p = plotly_object,
+ x = x,
+ y = ymax,
+ line = list(
+ color = plotly::toRGB(
+ x = color,
+ alpha = alpha
+ ),
+ dash = dash[3]
+ ),
+ showlegend = FALSE,
+ legendgroup = legendgroup,
+ inherit = FALSE,
+ name = name[3]
+ )
+
+ ## return plot
+ return(
+ plotly_object
+ )
+}
diff --git a/R/chart_indicator.R b/R/chart_indicator.R
index b978af695..a7ce14797 100644
--- a/R/chart_indicator.R
+++ b/R/chart_indicator.R
@@ -19,6 +19,21 @@
#'
#' @author Serkan Korkmaz
indicator <- function(FUN, ...) {
+ ## resolve function name of no
+ ## title have been passed
+ title <- input_name(
+ substitute(
+ FUN
+ )
+ )
+
+ ## clean up title
+ if (any(grepl(x = title, pattern = "_"))) {
+ title <- to_title(
+ title
+ )
+ }
+
## plotting environment
## does exist
chart_called <- TRUE
@@ -39,10 +54,39 @@ indicator <- function(FUN, ...) {
## object to trigger .plotly
## method downstream
plt <- plotly::plot_ly()
+
+ if (has_arg(idx)) {
+ idx <- eval.parent(
+ match.call()[["idx"]]
+ )
+ } else {
+ idx <- NULL
+ }
+
+ .plotting_environment$idx$label <- idx
+
+ if (has_arg(data)) {
+ data <- eval.parent(
+ match.call()[["data"]]
+ )
+ } else {
+ stop("'data'-argument has to be provided.")
+ }
}
## construct {plotly}-object
## based on FUN
+ ##
+ ## Note to future self:
+ ##
+ ## You could add chart layouting here
+ ## to avoid having to do it for each plotly method
+ ## but it would require you to add an identifier
+ ## of whether its a subplot or not.
+ ##
+ ## `outcome` by itself is just directly returned
+ ## and is not attached to the plotting environment
+ ## downstream
outcome <- do.call(
what = FUN,
args = list(
@@ -75,17 +119,27 @@ indicator <- function(FUN, ...) {
margin = 0.02,
heights = heights
),
- showlegend = TRUE
+ showlegend = TRUE,
+ yaxis = list(title = ''),
+ xaxis = list(
+ title = '',
+ tickmode = "auto"
+ )
)
.plotting_environment$chart <- fig
- return(fig)
+ return(
+ fig
+ )
}
## reconstruct charting
## as if called from chart()
- .chart_layout(
+ outcome <- .chart_layout(
x = outcome,
- title_text = "title_text"
+ title_text = title,
+ idx = if (is.null(idx)) 1:nrow(data) else idx
)
+
+ outcome
}
diff --git a/R/chart_pattern.R b/R/chart_pattern.R
index bf2ddb8ee..e52990172 100644
--- a/R/chart_pattern.R
+++ b/R/chart_pattern.R
@@ -3,7 +3,8 @@ pattern <- function(
x, # pattern
high,
low,
- pattern_name = "Doji"
+ pattern_name = "Doji",
+ agnostic = FALSE
) {
## chart theme controls
chart_theme <- .chart_theme()
@@ -50,17 +51,40 @@ pattern <- function(
p <- plotly::add_trace(
p = p,
x = idx_bull,
- y = low[idx_bull] - offset[idx_bull],
+ y = if (agnostic) {
+ high[idx_bull] - offset[idx_bull]
+ } else {
+ low[idx_bull] - offset[idx_bull]
+ },
type = "scatter",
mode = "markers+text",
marker = list(
- symbol = "triangle-up",
- color = chart_theme$bull_color,
+ symbol = if (agnostic) {
+ "triangle-down"
+ } else {
+ "triangle-up"
+ },
+ color = if (agnostic) {
+ chart_theme$font_color
+ } else {
+ chart_theme$bull_color
+ },
size = 10
),
text = bull_text,
- textposition = "bottom center",
- textfont = list(color = chart_theme$bull_color, size = 10),
+ textposition = if (agnostic) {
+ "top center"
+ } else {
+ "bottom center"
+ },
+ textfont = list(
+ color = if (agnostic) {
+ chart_theme$font_color
+ } else {
+ chart_theme$bull_color
+ },
+ size = 10
+ ),
hoverinfo = "skip",
name = "Bearish",
inherit = FALSE,
diff --git a/R/series.R b/R/series.R
index 7e241db0b..97705dfe1 100644
--- a/R/series.R
+++ b/R/series.R
@@ -40,13 +40,19 @@ series.plotly <- function(
dotsQ$data <- quote(.plotting_environment$x)
}
- as.data.frame(
+ out <- as.data.frame(
do.call(
series.formula,
c(list(x = formula, default = default), dotsQ),
quote = FALSE
)
)
+
+ ## set subset attribute
+ ## for the
+ attr(out, "subset") <- eval(dotsQ$subset)
+
+ out
}
#' @export
@@ -96,6 +102,10 @@ series.formula <- function(
)
}
+ ## set subset attribute
+ ## for the
+ attr(out, "subset") <- eval(dotsQ$subset)
+
as.data.frame(
out
)
diff --git a/R/ta_ACCBANDS.R b/R/ta_ACCBANDS.R
index b693b4315..b193cb1a4 100644
--- a/R/ta_ACCBANDS.R
+++ b/R/ta_ACCBANDS.R
@@ -124,10 +124,12 @@ acceleration_bands.plotly <- function(
x,
cols,
n = 10,
+ color = "steelblue",
+ alpha = 0.5,
...
) {
- ## prepare series
- ## from
+ ## prepare HLC series
+ ## for the acceleration bands
HLC <- series(
x = x,
formula = cols,
@@ -135,20 +137,28 @@ acceleration_bands.plotly <- function(
...
)
- ## calculate acceleration
- ## bands and return as
- ## data.frame
- .indicator <- as.data.frame(
- .Call(
- "impl_ta_ACCBANDS",
- HLC[[1]],
- HLC[[2]],
- HLC[[3]],
- as.integer(n)
- )
+ ## calculate indicator
+ ## and return as data.frame
+ .indicator <- acceleration_bands.default(
+ x = HLC,
+ cols = rebuild_formula(
+ names(HLC)
+ ),
+ n = n
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ HLC
+ )
+
+ ## acceleration bands by itself
+ ## makes no sense - throw an error
+ ## if not provided
+ if (is.null(.plotting_environment$main)) {
+ stop("No existing chart found.", call. = FALSE)
+ }
## add upper, middle and lower bands
## to the main chart - wrapped in local
@@ -156,46 +166,19 @@ acceleration_bands.plotly <- function(
##
## NOTE: Otherwise it will only evaluate
## and add the last element
- for (i in seq_len(ncol(HLC))) {
- local({
- j <- i
-
- .plotting_environment$main <- plotly::add_lines(
- .plotting_environment$main,
- data = .indicator,
- x = ~idx,
- y = ~ .indicator[, j],
- inherit = FALSE,
- line = list(
- color = '#4682b4'
- ),
- showlegend = FALSE,
- legendgroup = 'acceleration_band',
- name = c(
- "Upper Band",
- "Middle Band",
- "Lower Band"
- )[j],
- )
- })
- }
-
- .plotting_environment$main <- plotly::add_ribbons(
- p = .plotting_environment$main,
- inherit = FALSE,
+ .plotting_environment$main <- add_ribbons(
+ plotly_object = .plotting_environment$main,
data = .indicator,
x = ~idx,
- ymin = ~ .indicator[, 3],
- ymax = ~ .indicator[, 1],
- fillcolor = plotly::toRGB("#4682b4", alpha = 0.2),
- line = list(
- color = "transparent"
- ),
+ y = ~middle,
+ ymin = ~lower,
+ ymax = ~upper,
+ color = color,
+ alpha = alpha,
showlegend = TRUE,
legendgroup = 'acceleration_band',
- name = paste0(
- "Acceleration Bands"
- )
+ name = c("Acceleration Bands", "B", "C"),
+ dash = NULL
)
.plotting_environment$main
diff --git a/R/ta_AD.R b/R/ta_AD.R
index a80034e45..dd521589d 100644
--- a/R/ta_AD.R
+++ b/R/ta_AD.R
@@ -121,6 +121,7 @@ chaikin_AD_line.plotly <- function(
...
) {
## prepare HLCV series
+ ## for the chaikin A/D line
HLCV <- series(
x = x,
formula = cols,
@@ -128,51 +129,42 @@ chaikin_AD_line.plotly <- function(
...
)
- ## construct the chaikin A/D
- ## line and store as data.frame
- ## for plotly
- .indicator <- data.frame(
- AD_line = .Call(
- "impl_ta_AD",
- HLCV[[1]],
- HLCV[[2]],
- HLCV[[3]],
- HLCV[[4]]
+ ## calculate indicator
+ ## and return as data.grame
+ .indicator <- chaikin_AD_line.default(
+ x = HLCV,
+ cols = rebuild_formula(
+ names(HLCV)
)
)
- ## add idx for the axis
- ## TODO: this should be passed
- ## upstream instead
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ HLCV
+ )
- ## chart indicator
- ## as subplot
- output <- add_title(
- ## generate plot
- ## as line
- plotly::plot_ly(
- data = .indicator,
- x = ~idx,
- y = ~AD_line,
- type = "scatter",
- mode = "lines",
- showlegend = FALSE
- ),
- ## add title to
- ## the plot
- text = "Chaikin A/D Line"
+ ## construct chart
+ ## element
+ plotly_object <- subchart(
+ data = .indicator,
+ y = ~AD_line,
+ type = "scatter",
+ mode = "lines",
+ showlegend = FALSE
)
- ## pass to sub as
- ## list to preserve
- ## types
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = "Chaikin A/D Line"
+ )
+ }
+
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(output)
+ list(plotly_object)
)
- ## return plot
- ## if called directly
- output
+ plotly_object
}
diff --git a/R/ta_ADOSC.R b/R/ta_ADOSC.R
index ae59d9803..0643cb3a4 100644
--- a/R/ta_ADOSC.R
+++ b/R/ta_ADOSC.R
@@ -129,9 +129,11 @@ chaikin_AD_oscillator.plotly <- function(
cols,
fast = 3,
slow = 10,
+ color = "steelblue",
...
) {
- ## prepare series
+ ## prepare HLCV series
+ ## for the chaikin A/D line
HLCV <- series(
x = x,
formula = cols,
@@ -139,53 +141,67 @@ chaikin_AD_oscillator.plotly <- function(
...
)
- .indicator <- data.frame(
- AD_line = .Call(
- "impl_ta_ADOSC",
- HLCV[[1]],
- HLCV[[2]],
- HLCV[[3]],
- HLCV[[4]],
- as.integer(fast),
- as.integer(slow)
- )
+ ## calculate indicator
+ ## and return as data.frame
+ .indicator <- chaikin_AD_oscillator.default(
+ x = HLCV,
+ cols = rebuild_formula(
+ names(HLCV)
+ ),
+ fast = fast,
+ slow = slow
)
- .indicator$idx <- 1:nrow(.indicator)
- ad_col <- "#1f77b4"
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ HLCV
+ )
- ad_plot <- plotly::plot_ly(
+ plotly_object <- subchart(
data = .indicator,
- x = ~idx,
- y = ~AD_line,
+ y = ~AD_oscillator,
type = "scatter",
mode = "lines",
- line = list(color = ad_col),
+ line = list(
+ color = plotly::toRGB(
+ x = color,
+ alpha = 1
+ )
+ ),
name = "AD",
legendgroup = "ChaikinOscillator",
showlegend = FALSE
)
- # dashed y = 0 line in the same color
- ad_plot <- plotly::add_lines(
- p = ad_plot,
+ plotly_object <- plotly::add_lines(
+ p = plotly_object,
x = .indicator$idx,
y = 0,
- line = list(color = ad_col, dash = "dash"),
+ line = list(
+ color = plotly::toRGB(
+ x = color,
+ alpha = 1
+ ),
+ dash = "dot"
+ ),
showlegend = FALSE,
hoverinfo = "skip",
legendgroup = "ChaikinOscillator",
name = "Zero"
)
- ad_plot <- add_title(
- x = ad_plot,
- text = "Chaikin A/D Oscillator"
- )
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = "Chaikin A/D Oscillator"
+ )
+ }
+
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(ad_plot)
+ list(plotly_object)
)
- ad_plot
+ plotly_object
}
diff --git a/R/ta_AROON.R b/R/ta_AROON.R
index 8bdd3e0bb..b33296d8c 100644
--- a/R/ta_AROON.R
+++ b/R/ta_AROON.R
@@ -121,6 +121,8 @@ aroon.plotly <- function(
n = 10,
...
) {
+ ## prepare HL series
+ ## for the aroon oscillator
HL <- series(
x = x,
formula = cols,
@@ -128,49 +130,53 @@ aroon.plotly <- function(
...
)
- .indicator <- as.data.frame(
- .Call(
- "impl_ta_AROON",
- HL[[1]],
- HL[[2]],
- as.integer(n)
- )
+ ## calculate indicator
+ ## and return as data.frame
+ .indicator <- aroon.default(
+ x = HL,
+ cols = rebuild_formula(
+ names(HL)
+ ),
+ n = n
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ HL
+ )
- ad_plot <- plotly::plot_ly(
+ ## construct chart
+ ## element
+ plotly_object <- subchart(
data = .indicator,
- x = ~idx,
y = ~aroon_down,
type = "scatter",
mode = "lines",
- # line = list(color = ad_col),
name = "AD",
legendgroup = "Aroon",
showlegend = FALSE
)
- # dashed y = 0 line in the same color
- ad_plot <- plotly::add_lines(
- p = ad_plot,
+ plotly_object <- plotly::add_lines(
+ p = plotly_object,
x = .indicator$idx,
y = ~aroon_up,
- # line = list(color = ad_col, dash = "dash"),
showlegend = FALSE,
- hoverinfo = "skip",
- legendgroup = "Aroon",
- name = "Zero"
+ legendgroup = "Aroon"
)
- ad_plot <- add_title(
- x = ad_plot,
- text = "Aroon"
- )
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = "Aroon"
+ )
+ }
+
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(ad_plot)
+ list(plotly_object)
)
- ad_plot
+ plotly_object
}
diff --git a/R/ta_AROONOSC.R b/R/ta_AROONOSC.R
index a481a16a3..9fc14e166 100644
--- a/R/ta_AROONOSC.R
+++ b/R/ta_AROONOSC.R
@@ -120,6 +120,8 @@ aroon_oscillator.plotly <- function(
n = 10,
...
) {
+ ## prepare HL series
+ ## for the aroon oscillator
HL <- series(
x = x,
formula = cols,
@@ -127,37 +129,48 @@ aroon_oscillator.plotly <- function(
...
)
- .indicator <- data.frame(
- aroon_oscillator = .Call(
- "impl_ta_AROONOSC",
- HL[[1]],
- HL[[2]],
- as.integer(n)
- )
+ ## calculate indicator
+ ## and return as data.frame
+ .indicator <- aroon_oscillator.default(
+ x = HL,
+ cols = rebuild_formula(
+ names(HL)
+ ),
+ n = n
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ HL
+ )
- ad_plot <- plotly::plot_ly(
+ ## construct chart
+ ## element
+ plotly_object <- subchart(
data = .indicator,
- x = ~idx,
y = ~aroon_oscillator,
type = "scatter",
mode = "lines",
- # line = list(color = ad_col),
- name = "AD",
+ name = sprintf(
+ fmt = "AD(%d)",
+ n
+ ),
legendgroup = "Aroon",
showlegend = FALSE
)
- ad_plot <- add_title(
- x = ad_plot,
- text = "Aroon Oscillator"
- )
+ if (!is.null(.plotting_environment$main)) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = "Aroon Oscillator"
+ )
+ }
+
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(ad_plot)
+ list(plotly_object)
)
- ad_plot
+ plotly_object
}
diff --git a/R/ta_BBANDS.R b/R/ta_BBANDS.R
index efb634342..11fb25d97 100644
--- a/R/ta_BBANDS.R
+++ b/R/ta_BBANDS.R
@@ -185,10 +185,13 @@ bollinger_bands.plotly <- function(
ma = SMA(n = 10),
up = 2,
down = 2,
+ color = "steelblue",
+ alpha = 0.5,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for the bollinger
+ ## bands
x <- series(
x = x,
formula = cols,
@@ -196,61 +199,46 @@ bollinger_bands.plotly <- function(
...
)
- .indicator <- as.data.frame(
- .Call(
- "impl_ta_BBANDS",
- as.double(x[[1]]),
- ma$n,
- as.numeric(up),
- as.numeric(down),
- as.integer(ma$maType)
- )
+ ## calculate indicator
+ ## and return as data.frame
+ .indicator <- bollinger_bands.default(
+ x = x,
+ cols = rebuild_formula(
+ names(x)
+ ),
+ ma = ma,
+ up = up,
+ down = down
)
- .indicator$idx <- 1:nrow(.indicator)
-
- ## constuct chart
- ## element
- for (i in seq_len(ncol(.indicator) - 1)) {
- local({
- j <- i
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
- .plotting_environment$main <- plotly::add_lines(
- .plotting_environment$main,
- data = .indicator,
- x = ~idx,
- y = ~ .indicator[, j],
- inherit = FALSE,
- line = list(
- color = '#4682b4'
- ),
- showlegend = FALSE,
- legendgroup = 'bollinger_band',
- name = c(
- "Upper Band",
- "Middle Band",
- "Lower Band"
- )[j],
- )
- })
+ ## acceleration bands by itself
+ ## makes no sense - throw an error
+ ## if not provided
+ if (is.null(.plotting_environment$main)) {
+ stop("No existing chart found.", call. = FALSE)
}
- .plotting_environment$main <- plotly::add_ribbons(
- p = .plotting_environment$main,
- inherit = FALSE,
+ ## constuct chart
+ ## element
+ .plotting_environment$main <- add_ribbons(
+ plotly_object = .plotting_environment$main,
data = .indicator,
x = ~idx,
- ymin = ~ .indicator[, 3],
- ymax = ~ .indicator[, 1],
- fillcolor = plotly::toRGB("#4682b4", alpha = 0.2),
- line = list(
- color = "transparent"
- ),
+ y = ~middle,
+ ymin = ~lower,
+ ymax = ~upper,
+ color = color,
+ alpha = alpha,
showlegend = TRUE,
- legendgroup = 'bollinger_band',
- name = paste0(
- "BBand"
- )
+ legendgroup = "Bollinger Bands",
+ name = c("Bollinger Bands", "middle", "upper"),
+ dash = NULL
)
.plotting_environment$main
diff --git a/R/ta_CCI.R b/R/ta_CCI.R
index c399d1d33..a0e0db43e 100644
--- a/R/ta_CCI.R
+++ b/R/ta_CCI.R
@@ -109,6 +109,8 @@ commodity_channel_index.matrix <- function(
x,
cols,
n = 10,
+ upper = 100,
+ lower = -100,
...
) {
as.matrix(
@@ -123,10 +125,12 @@ commodity_channel_index.plotly <- function(
x,
cols,
n = 10,
+ lower = -100,
+ upper = 100,
...
) {
- ## prepare series
- ## from {plotly}-object
+ ## prepare HLC series
+ ## for the commodity channel index
HLC <- as.data.frame(
series(
x = x,
@@ -136,23 +140,32 @@ commodity_channel_index.plotly <- function(
)
)
- ## construct indicator
- .indicator <- as.data.frame(
- .Call(
- "impl_ta_CCI",
- HLC[[1]],
- HLC[[2]],
- HLC[[3]],
- as.integer(n)
- )
+ ## calculate indicator
+ ## and return as data.frame
+ .indicator <- commodity_channel_index.default(
+ x = HLC,
+ cols = rebuild_formula(
+ names(HLC)
+ ),
+ n = n
+ )
+
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ HLC
)
- colnames(.indicator) <- "CCI"
- .indicator$idx <- 1:nrow(.indicator)
+ ## commodity channels by itself
+ ## makes no sense - throw an error
+ ## if not provided
+ if (!main_chart_exists()) {
+ stop("No existing chart found.", call. = FALSE)
+ }
## construct plot with ribbons
## on upper and lower limits
- output <- plotly::plot_ly(
+ plotly_object <- plotly::plot_ly(
data = .indicator,
x = ~idx,
y = ~CCI,
@@ -161,30 +174,34 @@ commodity_channel_index.plotly <- function(
showlegend = FALSE
)
- output <- plotly::add_ribbons(
- output,
- x = ~idx,
- ymin = rep(-100, nrow(.indicator)),
- ymax = rep(100, nrow(.indicator)),
- line = list(width = 0),
- fillcolor = plotly::toRGB(
- x = "lightgray",
- alpha = 0.2
- )
+ plotly_object <- add_ribbons(
+ plotly_object = plotly_object,
+ data = .indicator,
+ x = ~ 1:nrow(.indicator),
+ ymin = rep(lower, nrow(.indicator)),
+ ymax = rep(upper, nrow(.indicator)),
+ color = "lightgray",
+ alpha = 0.1,
+ showlegend = FALSE,
+ legendgroup = "placeholder",
+ name = "CCI",
+ dash = "dot"
)
- output <- add_title(
- x = output,
- text = sprintf(
- "Commodity Channel Index (%d)",
- n
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = sprintf(
+ "Commodity Channel Index (%d)",
+ n
+ )
)
- )
+ }
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(output)
+ list(plotly_object)
)
- output
+ plotly_object
}
diff --git a/R/ta_CDL2CROWS.R b/R/ta_CDL2CROWS.R
index 6fb58d88c..af9a06b7f 100644
--- a/R/ta_CDL2CROWS.R
+++ b/R/ta_CDL2CROWS.R
@@ -145,10 +145,16 @@ two_crows.plotly <- function(
## indicators
.indicator <- two_crows.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ two_crows.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Two Crows"
+ pattern_name = "Two Crows",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDL3BLACKCROWS.R b/R/ta_CDL3BLACKCROWS.R
index 4f91c148c..b46864d7d 100644
--- a/R/ta_CDL3BLACKCROWS.R
+++ b/R/ta_CDL3BLACKCROWS.R
@@ -145,10 +145,16 @@ three_black_crows.plotly <- function(
## indicators
.indicator <- three_black_crows.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ three_black_crows.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Three Black Crows"
+ pattern_name = "Three Black Crows",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDL3INSIDE.R b/R/ta_CDL3INSIDE.R
index a16a3cffd..6875a2854 100644
--- a/R/ta_CDL3INSIDE.R
+++ b/R/ta_CDL3INSIDE.R
@@ -145,10 +145,16 @@ three_inside.plotly <- function(
## indicators
.indicator <- three_inside.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ three_inside.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Three Inside"
+ pattern_name = "Three Inside",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDL3LINESTRIKE.R b/R/ta_CDL3LINESTRIKE.R
index b02176815..eb9bcf824 100644
--- a/R/ta_CDL3LINESTRIKE.R
+++ b/R/ta_CDL3LINESTRIKE.R
@@ -145,10 +145,16 @@ three_line_strike.plotly <- function(
## indicators
.indicator <- three_line_strike.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ three_line_strike.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Three Line Strike"
+ pattern_name = "Three Line Strike",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDL3OUTSIDE.R b/R/ta_CDL3OUTSIDE.R
index 53339b54b..34055e2d4 100644
--- a/R/ta_CDL3OUTSIDE.R
+++ b/R/ta_CDL3OUTSIDE.R
@@ -145,10 +145,16 @@ three_outside.plotly <- function(
## indicators
.indicator <- three_outside.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ three_outside.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Three Outside"
+ pattern_name = "Three Outside",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDL3STARSINSOUTH.R b/R/ta_CDL3STARSINSOUTH.R
index c8722d037..ef4dc9a7d 100644
--- a/R/ta_CDL3STARSINSOUTH.R
+++ b/R/ta_CDL3STARSINSOUTH.R
@@ -145,10 +145,16 @@ three_stars_in_the_south.plotly <- function(
## indicators
.indicator <- three_stars_in_the_south.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ three_stars_in_the_south.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Three Stars in the South"
+ pattern_name = "Three Stars in the South",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDL3WHITESOLDIERS.R b/R/ta_CDL3WHITESOLDIERS.R
index 5ff1c524e..6918b4d0e 100644
--- a/R/ta_CDL3WHITESOLDIERS.R
+++ b/R/ta_CDL3WHITESOLDIERS.R
@@ -145,10 +145,16 @@ three_white_soldiers.plotly <- function(
## indicators
.indicator <- three_white_soldiers.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ three_white_soldiers.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Three White Soldiers"
+ pattern_name = "Three White Soldiers",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLABANDONEDBABY.R b/R/ta_CDLABANDONEDBABY.R
index c2dde44d0..bbfd635d7 100644
--- a/R/ta_CDLABANDONEDBABY.R
+++ b/R/ta_CDLABANDONEDBABY.R
@@ -150,10 +150,16 @@ abandoned_baby.plotly <- function(
## indicators
.indicator <- abandoned_baby.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -161,7 +167,8 @@ abandoned_baby.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Abandoned Baby"
+ pattern_name = "Abandoned Baby",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLADVANCEBLOCK.R b/R/ta_CDLADVANCEBLOCK.R
index 9ddfeda8a..6cf3a61fb 100644
--- a/R/ta_CDLADVANCEBLOCK.R
+++ b/R/ta_CDLADVANCEBLOCK.R
@@ -145,10 +145,16 @@ advance_block.plotly <- function(
## indicators
.indicator <- advance_block.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ advance_block.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Advance Block"
+ pattern_name = "Advance Block",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLBELTHOLD.R b/R/ta_CDLBELTHOLD.R
index 00ed85df0..3a977d6d7 100644
--- a/R/ta_CDLBELTHOLD.R
+++ b/R/ta_CDLBELTHOLD.R
@@ -145,10 +145,16 @@ belt_hold.plotly <- function(
## indicators
.indicator <- belt_hold.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ belt_hold.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Belt Hold"
+ pattern_name = "Belt Hold",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLBREAKAWAY.R b/R/ta_CDLBREAKAWAY.R
index 946013d8a..4dd1fabd3 100644
--- a/R/ta_CDLBREAKAWAY.R
+++ b/R/ta_CDLBREAKAWAY.R
@@ -145,10 +145,16 @@ break_away.plotly <- function(
## indicators
.indicator <- break_away.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ break_away.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Break Away"
+ pattern_name = "Break Away",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLCLOSINGMARUBOZU.R b/R/ta_CDLCLOSINGMARUBOZU.R
index 4eae5cc36..3f9627661 100644
--- a/R/ta_CDLCLOSINGMARUBOZU.R
+++ b/R/ta_CDLCLOSINGMARUBOZU.R
@@ -145,10 +145,16 @@ closing_marubozu.plotly <- function(
## indicators
.indicator <- closing_marubozu.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ closing_marubozu.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Closing Marubozu"
+ pattern_name = "Closing Marubozu",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLCONCEALBABYSWALL.R b/R/ta_CDLCONCEALBABYSWALL.R
index 307ca485b..e874465c9 100644
--- a/R/ta_CDLCONCEALBABYSWALL.R
+++ b/R/ta_CDLCONCEALBABYSWALL.R
@@ -145,10 +145,16 @@ concealing_baby_swallow.plotly <- function(
## indicators
.indicator <- concealing_baby_swallow.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ concealing_baby_swallow.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Concealing Baby Swallow"
+ pattern_name = "Conceal Baby Swallow",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLCOUNTERATTACK.R b/R/ta_CDLCOUNTERATTACK.R
index 430a03e3f..dabf26c7f 100644
--- a/R/ta_CDLCOUNTERATTACK.R
+++ b/R/ta_CDLCOUNTERATTACK.R
@@ -145,10 +145,16 @@ counter_attack.plotly <- function(
## indicators
.indicator <- counter_attack.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ counter_attack.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Counter Attack"
+ pattern_name = "Counter Attack",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLDARKCLOUDCOVER.R b/R/ta_CDLDARKCLOUDCOVER.R
index 11512d9ec..b3872e61c 100644
--- a/R/ta_CDLDARKCLOUDCOVER.R
+++ b/R/ta_CDLDARKCLOUDCOVER.R
@@ -150,10 +150,16 @@ dark_cloud_cover.plotly <- function(
## indicators
.indicator <- dark_cloud_cover.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -161,7 +167,8 @@ dark_cloud_cover.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Dark Cloud Cover"
+ pattern_name = "Dark Cloud Cover",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLDOJI.R b/R/ta_CDLDOJI.R
index a3e1daa28..f547d5ff0 100644
--- a/R/ta_CDLDOJI.R
+++ b/R/ta_CDLDOJI.R
@@ -145,10 +145,16 @@ doji.plotly <- function(
## indicators
.indicator <- doji.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ doji.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Doji"
+ pattern_name = "Doji",
+ agnostic = TRUE
)
.plotting_environment$main
diff --git a/R/ta_CDLDOJISTAR.R b/R/ta_CDLDOJISTAR.R
index d0138897a..ab4d89996 100644
--- a/R/ta_CDLDOJISTAR.R
+++ b/R/ta_CDLDOJISTAR.R
@@ -145,10 +145,16 @@ doji_star.plotly <- function(
## indicators
.indicator <- doji_star.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ doji_star.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Doji Star"
+ pattern_name = "Doji Star",
+ agnostic = TRUE
)
.plotting_environment$main
diff --git a/R/ta_CDLDRAGONFLYDOJI.R b/R/ta_CDLDRAGONFLYDOJI.R
index ff3e89736..4982583e6 100644
--- a/R/ta_CDLDRAGONFLYDOJI.R
+++ b/R/ta_CDLDRAGONFLYDOJI.R
@@ -145,10 +145,16 @@ dragonfly_doji.plotly <- function(
## indicators
.indicator <- dragonfly_doji.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ dragonfly_doji.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Dragonfly Doji"
+ pattern_name = "Dragonfly Doji",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLENGULFING.R b/R/ta_CDLENGULFING.R
index ee0b47adc..e90405b70 100644
--- a/R/ta_CDLENGULFING.R
+++ b/R/ta_CDLENGULFING.R
@@ -145,10 +145,16 @@ engulfing.plotly <- function(
## indicators
.indicator <- engulfing.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ engulfing.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Two Crows"
+ pattern_name = "Engulfing",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLEVENINGDOJISTAR.R b/R/ta_CDLEVENINGDOJISTAR.R
index 9db7e8f20..5c2543a6c 100644
--- a/R/ta_CDLEVENINGDOJISTAR.R
+++ b/R/ta_CDLEVENINGDOJISTAR.R
@@ -150,10 +150,16 @@ evening_doji_star.plotly <- function(
## indicators
.indicator <- evening_doji_star.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -161,7 +167,8 @@ evening_doji_star.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Evening Doji Star"
+ pattern_name = "Evening Doji Star",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLGAPSIDESIDEWHITE.R b/R/ta_CDLGAPSIDESIDEWHITE.R
index b6d9b50b3..5c47e46d6 100644
--- a/R/ta_CDLGAPSIDESIDEWHITE.R
+++ b/R/ta_CDLGAPSIDESIDEWHITE.R
@@ -145,10 +145,16 @@ gaps_side_white.plotly <- function(
## indicators
.indicator <- gaps_side_white.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ gaps_side_white.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Gaps-side White"
+ pattern_name = "Gap-side White",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLGRAVESTONEDOJI.R b/R/ta_CDLGRAVESTONEDOJI.R
index a13c7c592..707f0db3e 100644
--- a/R/ta_CDLGRAVESTONEDOJI.R
+++ b/R/ta_CDLGRAVESTONEDOJI.R
@@ -145,10 +145,16 @@ gravestone_doji.plotly <- function(
## indicators
.indicator <- gravestone_doji.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ gravestone_doji.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Gravestone Doji"
+ pattern_name = "Gravestone Doji",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLHAMMER.R b/R/ta_CDLHAMMER.R
index 5b36e1251..f2277e706 100644
--- a/R/ta_CDLHAMMER.R
+++ b/R/ta_CDLHAMMER.R
@@ -145,10 +145,16 @@ hammer.plotly <- function(
## indicators
.indicator <- hammer.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ hammer.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Hammer"
+ pattern_name = "Hammer",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLHANGINGMAN.R b/R/ta_CDLHANGINGMAN.R
index e405f8e27..e1931a7fc 100644
--- a/R/ta_CDLHANGINGMAN.R
+++ b/R/ta_CDLHANGINGMAN.R
@@ -145,10 +145,16 @@ hanging_man.plotly <- function(
## indicators
.indicator <- hanging_man.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ hanging_man.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Hanging Man"
+ pattern_name = "Hanging Man",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CDLHARAMI.R b/R/ta_CDLHARAMI.R
index de5183daf..d8ad96f61 100644
--- a/R/ta_CDLHARAMI.R
+++ b/R/ta_CDLHARAMI.R
@@ -145,10 +145,16 @@ harami.plotly <- function(
## indicators
.indicator <- harami.default(
x = OHLC,
- cols = ~ open + high + low + close
+ cols = rebuild_formula(
+ names(OHLC)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ OHLC
+ )
## chart patterns
.plotting_environment$main <- pattern(
@@ -156,7 +162,8 @@ harami.plotly <- function(
x = .indicator,
high = OHLC[[2]],
low = OHLC[[3]],
- pattern_name = "Harami"
+ pattern_name = "Harami",
+ agnostic = FALSE
)
.plotting_environment$main
diff --git a/R/ta_CMO.R b/R/ta_CMO.R
index cfd7d95aa..669ac3201 100644
--- a/R/ta_CMO.R
+++ b/R/ta_CMO.R
@@ -157,10 +157,14 @@ chande_momentum_oscillator.plotly <- function(
x,
cols,
n = 10,
+ upper = 50,
+ lower = -50,
+ alpha = 0.7,
...
) {
- ## prepare series
- ## from {plotly}-object
+ ## prepare univariate
+ ## series for the chande momentum
+ ## indicator
x <- as.data.frame(
series(
x = x,
@@ -170,56 +174,60 @@ chande_momentum_oscillator.plotly <- function(
)
)
- ## construct indicator
- ## NOTE: NextMethod might be risky
- ## here
- .indicator <- as.data.frame(
- .Call(
- "impl_ta_CMO",
- x[[1]],
- as.integer(n)
- )
+ ## calculate indicator
+ ## and return as data.frame
+ .indicator <- chande_momentum_oscillator.default(
+ x = x,
+ cols = rebuild_formula(
+ names(x)
+ ),
+ n = n
)
- colnames(.indicator) <- "CMO"
-
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
## construct plot with ribbons
## on upper and lower limits
- output <- plotly::plot_ly(
+ plotly_object <- subchart(
data = .indicator,
- x = ~idx,
y = ~CMO,
type = "scatter",
mode = "lines",
showlegend = FALSE
)
- output <- plotly::add_ribbons(
- output,
- x = ~idx,
- ymin = rep(-50, nrow(.indicator)),
- ymax = rep(50, nrow(.indicator)),
- line = list(width = 0),
- fillcolor = plotly::toRGB(
- x = "lightgray",
- alpha = 0.2
- )
+ plotly_object <- add_ribbons(
+ plotly_object = plotly_object,
+ data = .indicator,
+ x = ~ 1:nrow(.indicator),
+ ymin = rep(lower, nrow(.indicator)),
+ ymax = rep(upper, nrow(.indicator)),
+ alpha = alpha,
+ color = "lightgray",
+ showlegend = FALSE,
+ legendgroup = "cmo_area",
+ name = "cmo_area",
+ dash = "dot"
)
- output <- add_title(
- x = output,
- text = sprintf(
- "Chande Momentum Indicator (%d)",
- n
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = sprintf(
+ "Chande Momentum Indicator (%d)",
+ n
+ )
)
- )
+ }
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(output)
+ list(plotly_object)
)
- output
+ plotly_object
}
diff --git a/R/ta_DEMA.R b/R/ta_DEMA.R
index 1d1c1ceeb..645adf678 100644
--- a/R/ta_DEMA.R
+++ b/R/ta_DEMA.R
@@ -90,7 +90,7 @@ DEMA.default <- function(
colnames(x) <- paste0("dema_", colnames(x))
- x
+ as.data.frame(x)
}
#' @rdname DEMA
@@ -154,8 +154,8 @@ DEMA.plotly <- function(
n = 10,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for DEMA
x <- as.data.frame(
series(
x = x,
@@ -165,9 +165,21 @@ DEMA.plotly <- function(
)
)
- ## indicator
- .indicator <- as.data.frame(NextMethod())
- .indicator$idx <- 1:nrow(.indicator)
+ ## calculator indicator
+ ## and return as data.frame
+ .indicator <- DEMA.default(
+ x = x,
+ cols = rebuild_formula(
+ x = names(x)
+ ),
+ n = 10
+ )
+
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
for (i in 1:ncol(x)) {
local({
@@ -176,7 +188,7 @@ DEMA.plotly <- function(
.plotting_environment$main,
data = .indicator,
x = ~idx,
- y = ~ .indicator[, j],
+ y = ~ .indicator[[j]],
type = "scatter",
mode = "lines",
name = sprintf("DEMA(%d)", n),
diff --git a/R/ta_EMA.R b/R/ta_EMA.R
index bbd228407..c906e687a 100644
--- a/R/ta_EMA.R
+++ b/R/ta_EMA.R
@@ -89,7 +89,7 @@ EMA.default <- function(
colnames(x) <- paste0("ema_", colnames(x))
- x
+ as.data.frame(x)
}
#' @rdname EMA
@@ -153,8 +153,8 @@ EMA.plotly <- function(
n = 10,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for EMA
x <- as.data.frame(
series(
x = x,
@@ -164,9 +164,21 @@ EMA.plotly <- function(
)
)
- ## indicator
- .indicator <- as.data.frame(NextMethod())
- .indicator$idx <- 1:nrow(.indicator)
+ ## calculator indicator
+ ## and return as data.frame
+ .indicator <- EMA.default(
+ x = x,
+ cols = rebuild_formula(
+ x = names(x)
+ ),
+ n = n
+ )
+
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
for (i in 1:ncol(x)) {
local({
@@ -175,7 +187,7 @@ EMA.plotly <- function(
.plotting_environment$main,
data = .indicator,
x = ~idx,
- y = ~ .indicator[, j],
+ y = .indicator[[j]],
type = "scatter",
mode = "lines",
name = sprintf("EMA(%d)", n),
diff --git a/R/ta_HT_DCPERIOD.R b/R/ta_HT_DCPERIOD.R
index 437a84a18..3c9628c25 100644
--- a/R/ta_HT_DCPERIOD.R
+++ b/R/ta_HT_DCPERIOD.R
@@ -160,22 +160,38 @@ ht_dcperiod.plotly <- function(
##
.indicator <- ht_dcperiod.default(
x = x,
- cols = cols
+ cols = rebuild_formula(
+ names(x)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
- output <- plotly::plot_ly(
+ ## construct plotly object
+ ## as lines + markers
+ plotly_object <- subchart(
data = .indicator,
- name = "Dominant Cycle Period",
- x = ~idx,
- y = ~dominant_cycle_period
+ y = ~dominant_cycle_period,
+ type = "scatter",
+ mode = "lines+markers",
+ name = "DC Period"
)
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = "Dominant Cycle Period"
+ )
+ }
+
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(output)
+ list(plotly_object)
)
- output
+ plotly_object
}
diff --git a/R/ta_HT_DCPHASE.R b/R/ta_HT_DCPHASE.R
index 21cfd6a84..0307d4eee 100644
--- a/R/ta_HT_DCPHASE.R
+++ b/R/ta_HT_DCPHASE.R
@@ -145,8 +145,8 @@ ht_dc_phase.plotly <- function(
cols,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for DC phase
x <- as.data.frame(
series(
x = x,
@@ -156,26 +156,42 @@ ht_dc_phase.plotly <- function(
)
)
- ## construct indicator
- ##
+ ## construct DC phase
+ ## as data.frame
.indicator <- ht_dc_phase.default(
x = x,
- cols = cols
+ cols = rebuild_formula(
+ names(x)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
- output <- plotly::plot_ly(
+ ## construct indicator
+ ## as plotly object
+ plotly_object <- subchart(
data = .indicator,
- name = "Dominant Cycle Phase",
- x = ~idx,
- y = ~dominant_cycle_phase
+ y = ~dominant_cycle_phase,
+ type = "scatter",
+ mode = "markers",
+ name = "DC Phase"
)
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = "Dominant Cycle Phase"
+ )
+ }
+
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(output)
+ list(plotly_object)
)
- output
+ plotly_object
}
diff --git a/R/ta_HT_PHASOR.R b/R/ta_HT_PHASOR.R
index 7dfd6ad98..6d3a4dca4 100644
--- a/R/ta_HT_PHASOR.R
+++ b/R/ta_HT_PHASOR.R
@@ -143,8 +143,9 @@ ht_phasor.plotly <- function(
cols,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for phasor
+ ## components
x <- as.data.frame(
series(
x = x,
@@ -154,34 +155,52 @@ ht_phasor.plotly <- function(
)
)
- ## construct indicator
- ##
+ ## construct phasor indicators
+ ## as data.frame
.indicator <- ht_phasor.default(
x = x,
- cols = cols
+ cols = rebuild_formula(
+ names(x)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
- output <- plotly::plot_ly(
+ ## construct plotly
+ ## object
+ plotly_object <- subchart(
data = .indicator,
- name = "Phasor Components",
- x = ~idx,
- y = ~inphase
+ y = ~inphase,
+ type = "scatter",
+ mode = "lines",
+ name = "Inphase",
+ legendgroup = "phasor_components"
)
- output <- plotly::add_lines(
- output,
+ plotly_object <- plotly::add_lines(
+ p = plotly_object,
+ data = .indicator,
x = ~idx,
y = ~quadrature,
- data = .indicator,
- inherit = FALSE
+ name = "Quadrature",
+ legendgroup = "phasor_components"
)
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = "Phasor Components"
+ )
+ }
+
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(output)
+ list(plotly_object)
)
- output
+ plotly_object
}
diff --git a/R/ta_HT_SINE.R b/R/ta_HT_SINE.R
index ff7ac7a0c..c1305a522 100644
--- a/R/ta_HT_SINE.R
+++ b/R/ta_HT_SINE.R
@@ -144,8 +144,8 @@ ht_sine_wave.plotly <- function(
cols,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## seris for sine wave
x <- as.data.frame(
series(
x = x,
@@ -155,35 +155,52 @@ ht_sine_wave.plotly <- function(
)
)
- ## construct indicator
- ##
+ ## construct sine wave
+ ## as data.frame
.indicator <- ht_sine_wave.default(
x = x,
- cols = cols,
- ...
+ cols = rebuild_formula(
+ names(x)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
- output <- plotly::plot_ly(
+ ## construct plotly
+ ## object
+ plotly_object <- subchart(
data = .indicator,
- name = "Sine Wave",
- x = ~idx,
- y = ~sine
+ y = ~sine,
+ type = "scatter",
+ mode = "lines",
+ name = "Sine",
+ legendgroup = "sinewave"
)
- output <- plotly::add_lines(
- p = output,
+ plotly_object <- plotly::add_lines(
+ p = plotly_object,
x = ~idx,
y = ~leadsine,
data = .indicator,
- inherit = FALSE
+ name = "Lead Sine",
+ legendgroup = "sinewave"
)
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = "Sine Wave"
+ )
+ }
+
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(output)
+ list(plotly_object)
)
- output
+ plotly_object
}
diff --git a/R/ta_HT_TRENDLINE.R b/R/ta_HT_TRENDLINE.R
index d27982db4..e1c550c06 100644
--- a/R/ta_HT_TRENDLINE.R
+++ b/R/ta_HT_TRENDLINE.R
@@ -146,8 +146,8 @@ ht_trendline.plotly <- function(
cols,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate series
+ ## for the trendline
x <- as.data.frame(
series(
x = x,
@@ -157,13 +157,22 @@ ht_trendline.plotly <- function(
)
)
- ## indicator
+ ## calculate trendline indicator
+ ## and return as data.frame
.indicator <- ht_trendline.default(
x = x,
- cols = cols
+ cols = rebuild_formula(
+ names(x)
+ )
+ )
+
+ ## add idx conditional
+ ## on whether idx is passed
+ .indicator$idx <- add_idx(
+ x
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## construct plotly object
for (i in 1:ncol(x)) {
local({
j <- i
@@ -174,7 +183,7 @@ ht_trendline.plotly <- function(
y = ~ .indicator[, j],
type = "scatter",
mode = "lines",
- name = sprintf("Trendline"),
+ name = "Trendline",
inherit = FALSE
)
})
diff --git a/R/ta_HT_TRENDMODE.R b/R/ta_HT_TRENDMODE.R
index 942f98f08..a8e8daa6c 100644
--- a/R/ta_HT_TRENDMODE.R
+++ b/R/ta_HT_TRENDMODE.R
@@ -145,44 +145,53 @@ ht_trendmode.plotly <- function(
cols,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for the the
+ ## trendmode
x <- as.data.frame(
series(
x = x,
- formula = ~ open + high + low + close,
- default = ~ open + high + low + close,
+ formula = cols,
+ default = ~open,
...
)
)
- ## indicator
+ ## calculate the trendmode
+ ## and return as data.frame
.indicator <- ht_trendmode.default(
x = x,
- cols = cols
+ cols = rebuild_formula(
+ names(x)
+ )
)
- .indicator$idx <- 1:nrow(.indicator)
- .indicator$mid_price <- rowMeans(
- x[, c(2, 4)]
+ ## add idx based on the
+ ## univariate series
+ .indicator$idx <- add_idx(
+ x
)
- ## locate all trend modes
- trend_idx <- which(.indicator[[1]] == 1)
-
- .plotting_environment$main <- plotly::add_trace(
- .plotting_environment$main,
- x = ~ idx[trend_idx],
- y = ~ .indicator$mid_price[trend_idx],
+ plotly_object <- subchart(
+ data = .indicator,
+ y = ~dominant_cycle_period,
type = "scatter",
- mode = "markers",
- marker = list(
- symbol = "star",
- size = 10
- ),
- name = sprintf("KAMA(%d)", 3),
- inherit = FALSE
+ mode = "lines",
+ name = "Trendmode",
+ line = list(shape = "hvh")
+ )
+
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = "Trendmode"
+ )
+ }
+
+ .plotting_environment$sub <- c(
+ .plotting_environment$sub,
+ list(plotly_object)
)
- .plotting_environment$main
+ plotly_object
}
diff --git a/R/ta_KAMA.R b/R/ta_KAMA.R
index f66e85918..b84825d6a 100644
--- a/R/ta_KAMA.R
+++ b/R/ta_KAMA.R
@@ -89,7 +89,7 @@ KAMA.default <- function(
colnames(x) <- paste0("kama_", colnames(x))
- x
+ as.data.frame(x)
}
#' @rdname KAMA
@@ -153,8 +153,8 @@ KAMA.plotly <- function(
n = 10,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for KAMA
x <- as.data.frame(
series(
x = x,
@@ -164,9 +164,21 @@ KAMA.plotly <- function(
)
)
- ## indicator
- .indicator <- as.data.frame(NextMethod())
- .indicator$idx <- 1:nrow(.indicator)
+ ## calculator indicator
+ ## and return as data.frame
+ .indicator <- KAMA.default(
+ x = x,
+ cols = rebuild_formula(
+ x = names(x)
+ ),
+ n = n
+ )
+
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
for (i in 1:ncol(x)) {
local({
@@ -175,7 +187,7 @@ KAMA.plotly <- function(
.plotting_environment$main,
data = .indicator,
x = ~idx,
- y = ~ .indicator[, j],
+ y = ~ .indicator[[j]],
type = "scatter",
mode = "lines",
name = sprintf("KAMA(%d)", n),
diff --git a/R/ta_MACD.R b/R/ta_MACD.R
index c74db364b..fa7256830 100644
--- a/R/ta_MACD.R
+++ b/R/ta_MACD.R
@@ -261,8 +261,8 @@ moving_average_convergence_divergence.plotly <- function(
signal = 9,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for MACD
x <- series(
x = x,
formula = cols,
@@ -270,61 +270,86 @@ moving_average_convergence_divergence.plotly <- function(
...
)
- ## construct indicator
- ##
+ ## calculator indicator
+ ## and return as data.frame
.indicator <- moving_average_convergence_divergence.default(
x = x,
- cols = cols,
+ cols = rebuild_formula(
+ names(x)
+ ),
fast = fast,
slow = slow,
signal = signal
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
+
+ ## calculate directions for bull
+ ## and bear candles
.indicator$direction <- .indicator$signal >= .indicator$macd
- ## theme
+ ## generate plotly object
+ ## of the indicator
chart_theme <- .chart_theme()
- ## generate indicator plot
- output <- plotly::plot_ly(
+
+ ## construct plotly object
+ plotly_object <- subchart(
data = .indicator,
- showlegend = FALSE,
- name = 'MACD',
- x = ~idx,
y = ~histogram,
color = ~direction,
colors = c(
chart_theme$bull_color,
chart_theme$bear_color
),
- type = 'bar'
+ type = 'bar',
+ showlegend = FALSE
)
- output <- plotly::add_lines(
- output,
+ plotly_object <- plotly::add_lines(
+ plotly_object,
x = ~idx,
y = ~signal,
data = .indicator,
- inherit = FALSE
+ inherit = FALSE,
+ name = sprintf(
+ fmt = "Signal(%d)",
+ if (is.list(signal)) signal$n else signal
+ )
)
- output <- plotly::add_lines(
- output,
+ plotly_object <- plotly::add_lines(
+ plotly_object,
x = ~idx,
y = ~macd,
data = .indicator,
- inherit = FALSE
+ inherit = FALSE,
+ name = sprintf(
+ fmt = "MACD(%d, %d)",
+ if (is.list(fast)) fast$n else fast,
+ if (is.list(slow)) slow$n else slow
+ )
)
- output <- add_title(
- x = output,
- text = "MACD"
- )
+ if (!is.null(.plotting_environment$main)) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = sprintf(
+ fmt = "MACD(%d, %d, %d)",
+ if (is.list(fast)) fast$n else fast,
+ if (is.list(slow)) slow$n else slow,
+ if (is.list(signal)) signal$n else signal
+ )
+ )
+ }
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(output)
+ list(plotly_object)
)
- output
+ plotly_object
}
diff --git a/R/ta_MAMA.R b/R/ta_MAMA.R
index d6a0e0d21..c3d2f9bef 100644
--- a/R/ta_MAMA.R
+++ b/R/ta_MAMA.R
@@ -89,7 +89,7 @@ MAMA.default <- function(
colnames(x) <- paste0("mama_", colnames(x))
- x
+ as.data.frame(x)
}
#' @rdname MAMA
@@ -153,8 +153,8 @@ MAMA.plotly <- function(
n = 10,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for MAMA
x <- as.data.frame(
series(
x = x,
@@ -164,9 +164,21 @@ MAMA.plotly <- function(
)
)
- ## indicator
- .indicator <- as.data.frame(NextMethod())
- .indicator$idx <- 1:nrow(.indicator)
+ ## calculator indicator
+ ## and return as data.frame
+ .indicator <- MAMA.default(
+ x = x,
+ cols = rebuild_formula(
+ x = names(x)
+ ),
+ n = n
+ )
+
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
for (i in 1:ncol(x)) {
local({
@@ -175,7 +187,7 @@ MAMA.plotly <- function(
.plotting_environment$main,
data = .indicator,
x = ~idx,
- y = ~ .indicator[, j],
+ y = ~ .indicator[[j]],
type = "scatter",
mode = "lines",
name = sprintf("MAMA(%d)", n),
diff --git a/R/ta_MFI.R b/R/ta_MFI.R
index b7cbc3c8e..5793bf915 100644
--- a/R/ta_MFI.R
+++ b/R/ta_MFI.R
@@ -120,6 +120,8 @@ money_flow_index.plotly <- function(
x,
cols,
n = 10,
+ lower = -20,
+ upper = 80,
...
) {
## prepare series
@@ -131,40 +133,38 @@ money_flow_index.plotly <- function(
...
)
- ## calculate acceleration
- ## bands and return as
+ ## calculate money flow index
+ ## and return as
## data.frame
- .indicator <- as.data.frame(
- .Call(
- "impl_ta_MFI",
- HLCV[[1]],
- HLCV[[2]],
- HLCV[[3]],
- HLCV[[4]],
- as.integer(n)
- )
+ .indicator <- money_flow_index.default(
+ x = HLCV,
+ cols = rebuild_formula(
+ names(HLCV)
+ ),
+ n = n
)
- colnames(.indicator)[1] <- "MFI"
-
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ HLCV
+ )
## construct plot with ribbons
## on upper and lower limits
- output <- plotly::plot_ly(
+ plotly_object <- subchart(
data = .indicator,
- x = ~idx,
y = ~MFI,
type = "scatter",
mode = "lines",
showlegend = FALSE
)
- output <- plotly::add_ribbons(
- output,
+ plotly_object <- plotly::add_ribbons(
+ plotly_object,
x = ~idx,
- ymin = rep(-20, nrow(.indicator)),
- ymax = rep(70, nrow(.indicator)),
+ ymin = rep(lower, nrow(.indicator)),
+ ymax = rep(upper, nrow(.indicator)),
line = list(width = 0),
fillcolor = plotly::toRGB(
x = "lightgray",
@@ -172,18 +172,20 @@ money_flow_index.plotly <- function(
)
)
- output <- add_title(
- x = output,
- text = sprintf(
- "Money Flow Index (%d)",
- n
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = sprintf(
+ "Money Flow Index (%d)",
+ n
+ )
)
- )
+ }
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(output)
+ list(plotly_object)
)
- output
+ plotly_object
}
diff --git a/R/ta_OBV.R b/R/ta_OBV.R
index ccf840b69..1f1f811b5 100644
--- a/R/ta_OBV.R
+++ b/R/ta_OBV.R
@@ -128,42 +128,44 @@ on_balance_volume.plotly <- function(
...
)
- ## calculate acceleration
- ## bands and return as
- ## data.frame
- .indicator <- as.data.frame(
- .Call(
- "impl_ta_OBV",
- CV[[1]],
- CV[[2]]
- )
+ ## calculate on balance volume
+ ## and return as data.frame
+ .indicator <- on_balance_volume.default(
+ x = CV,
+ cols = rebuild_formula(
+ x = names(CV)
+ ),
+ n = n
)
- colnames(.indicator)[1] <- "OBV"
-
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ CV
+ )
- ## Create
- output <- plotly::plot_ly(
+ ## construct plot
+ plotly_object <- subchart(
data = .indicator,
- x = ~idx,
y = ~OBV,
type = "scatter",
mode = "lines",
- # line = list(color = ad_col),
name = "On-Balance Volume",
legendgroup = "obv",
showlegend = TRUE
)
- output <- add_title(
- x = output,
- text = "On-Balance Volume (OBV)"
- )
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = "On-Balance Volume (OBV)"
+ )
+ }
+
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(output)
+ list(plotly_object)
)
- output
+ plotly_object
}
diff --git a/R/ta_RSI.R b/R/ta_RSI.R
index 8b2826a9d..9fbb4e302 100644
--- a/R/ta_RSI.R
+++ b/R/ta_RSI.R
@@ -55,7 +55,8 @@ relative_strength_index.default <- function(
paste0(
"'cols' has to be length 1. ",
"Got length ",
- length(all.vars(cols))
+ length(all.vars(cols)),
+ paste(all.vars(cols), collapse = " and ")
)
)
}
@@ -143,10 +144,12 @@ relative_strength_index.plotly <- function(
n = 10,
lower_band = 20,
upper_band = 80,
+ color = "lightgray",
+ alpha = 0.2,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate series
+ ## for RSI
x <- as.data.frame(
series(
x = x,
@@ -156,31 +159,50 @@ relative_strength_index.plotly <- function(
)
)
- ## indicator
- .indicator <- as.data.frame(NextMethod())
- .indicator$idx <- 1:nrow(.indicator)
+ ## calculate indicator
+ ## and return as data.frame
+ .indicator <- relative_strength_index.default(
+ x = x,
+ ## pass the column
+ ## based on 'x'
+ cols = rebuild_formula(
+ names(x)
+ ),
+ n = n
+ )
- rsi_plot <- plotly::plot_ly(
- .indicator,
- x = ~idx,
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
+
+ ## generate plotly object
+ ## of the indicator
+ plotly_object <- subchart(
+ data = .indicator,
y = ~RSI,
type = "scatter",
mode = "lines",
showlegend = FALSE
)
- rsi_plot <- plotly::add_ribbons(
- rsi_plot,
+
+ plotly_object <- plotly::add_ribbons(
+ plotly_object,
x = ~idx,
ymin = rep(lower_band, nrow(.indicator)),
ymax = rep(upper_band, nrow(.indicator)),
line = list(width = 0),
- fillcolor = "rgba(160,160,160,0.20)"
+ fillcolor = plotly::toRGB(
+ x = color,
+ alpha = alpha
+ )
)
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(rsi_plot)
+ list(plotly_object)
)
- rsi_plot
+ plotly_object
}
diff --git a/R/ta_SMA.R b/R/ta_SMA.R
index eae9a9968..9723ce37e 100644
--- a/R/ta_SMA.R
+++ b/R/ta_SMA.R
@@ -82,7 +82,7 @@ SMA.default <- function(
colnames(x) <- paste0("sma_", colnames(x))
- x
+ as.data.frame(x)
}
#' @rdname SMA
@@ -145,8 +145,8 @@ SMA.plotly <- function(
n = 10,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for SMA
x <- as.data.frame(
series(
x = x,
@@ -156,9 +156,21 @@ SMA.plotly <- function(
)
)
- ## indicator
- .indicator <- as.data.frame(NextMethod())
- .indicator$idx <- 1:nrow(.indicator)
+ ## calculator indicator
+ ## and return as data.frame
+ .indicator <- SMA.default(
+ x = x,
+ cols = rebuild_formula(
+ x = names(x)
+ ),
+ n = n
+ )
+
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
for (i in 1:ncol(x)) {
local({
@@ -167,7 +179,7 @@ SMA.plotly <- function(
.plotting_environment$main,
data = .indicator,
x = ~idx,
- y = ~ .indicator[, j],
+ y = ~ .indicator[[j]],
type = "scatter",
mode = "lines",
name = sprintf("SMA(%d)", n),
diff --git a/R/ta_STOCH.R b/R/ta_STOCH.R
index fbf4fdcc8..5ee4bdc46 100644
--- a/R/ta_STOCH.R
+++ b/R/ta_STOCH.R
@@ -135,15 +135,14 @@ stochastic.plotly <- function(
fastk = 5,
slowk = SMA(n = 10),
slowd = SMA(n = 8),
+ lower = 20,
+ upper = 80,
+ color = "lightgray",
+ alpha = 0.7,
...
) {
- # slowk <- map_maType_call(substitute(slowk))
- # slowd <- map_maType_call(substitute(slowd))
- # slowk <- substitute(slowk)
- # slowd <- substitute(slowd)
- # slowk <- map_maType_call(slowk)
- # slowd <- map_maType_call(slowd)
## construct HLC series
+ ## for stochastic
HLC <- as.data.frame(
series(
x = x,
@@ -153,52 +152,62 @@ stochastic.plotly <- function(
)
)
- .indicator <- as.data.frame(
- .Call(
- "impl_ta_STOCH",
- HLC[[1]],
- HLC[[2]],
- HLC[[3]],
- as.integer(fastk),
- as.integer(slowk$n),
- as.integer(slowk$maType),
- as.integer(slowd$n),
- as.integer(slowd$maType)
- )
+ ## calculate stochastic
+ ## and return as data.frame
+ .indicator <- stochastic.default(
+ x = HLC,
+ cols = rebuild_formula(
+ x = names(HLC)
+ ),
+ fastk = fastk,
+ slowk = slowk,
+ slowd = slowd
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ HLC
+ )
- ## Create
- output <- plotly::plot_ly(
+ ## generate plotly object
+ ## of the indicator
+ plotly_object <- subchart(
data = .indicator,
- x = ~idx,
y = ~slowk,
type = "scatter",
mode = "lines",
- # line = list(color = ad_col),
- name = "Stochastic %K",
- legendgroup = "stochastic",
+ name = "Stocastic %K",
+ legendgroup = "STOCH",
showlegend = TRUE
)
- output <- plotly::add_lines(
- output,
+ plotly_object <- add_ribbons(
+ plotly_object = plotly_object,
+ data = .indicator,
x = ~idx,
y = ~slowd,
- name = "Stochastic %D",
- legendgroup = "stochastic",
- showlegend = TRUE
+ ymin = rep(lower, nrow(.indicator)),
+ ymax = rep(upper, nrow(.indicator)),
+ color = color,
+ alpha = alpha,
+ showlegend = TRUE,
+ dash = c("solid", "dot", "dot"),
+ name = c("Stochastic %D", "Lower", "Upper"),
+ legendgroup = "STOCH"
)
- output <- add_title(
- x = output,
- text = "Stochastic"
- )
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = "Stochastic"
+ )
+ }
+
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(output)
+ list(plotly_object)
)
- output
+ plotly_object
}
diff --git a/R/ta_STOCHF.R b/R/ta_STOCHF.R
index 9d01bb270..96a8c44ca 100644
--- a/R/ta_STOCHF.R
+++ b/R/ta_STOCHF.R
@@ -128,11 +128,18 @@ fast_stochastic.plotly <- function(
cols,
fast_k = 5,
fast_d_MAtype = SMA(n = 10),
+ lower = 20,
+ upper = 80,
+ color = "lightgray",
+ alpha = 0.7,
...
) {
+ ## input arguments
slowk_ma <- fast_d_MAtype
- ## construct HLC series
+ ## prepare HLC
+ ## series for stochastic
+ ## relative strength index
HLC <- as.data.frame(series(
x = x,
formula = cols,
@@ -140,49 +147,61 @@ fast_stochastic.plotly <- function(
...
))
- .indicator <- as.data.frame(
- .Call(
- "impl_ta_STOCHF",
- HLC[[1]],
- HLC[[2]],
- HLC[[3]],
- as.integer(fast_k),
- as.integer(slowk_ma$n),
- as.integer(slowk_ma$maType)
- )
+ ## calculate indicator
+ ## and return as data.frame
+ .indicator <- fast_stochastic.default(
+ x = HLC,
+ cols = rebuild_formula(
+ names(HLC)
+ ),
+ fast_k = fast_k,
+ fast_d_MAtype = fast_d_MAtype
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ HLC
+ )
- ## Create
- output <- plotly::plot_ly(
+ ## generate plotly object
+ ## of the indicator
+ plotly_object <- subchart(
data = .indicator,
- x = ~idx,
y = ~fastk,
type = "scatter",
mode = "lines",
- # line = list(color = ad_col),
name = "Stochastic %K (Fast)",
legendgroup = "stochastic_fast",
showlegend = FALSE
)
- output <- plotly::add_lines(
- output,
+ plotly_object <- add_ribbons(
+ plotly_object = plotly_object,
+ data = .indicator,
x = ~idx,
y = ~fastd,
+ ymin = rep(lower, nrow(.indicator)),
+ ymax = rep(upper, nrow(.indicator)),
+ color = color,
+ alpha = alpha,
+ dash = c("solid", "dot", "dot"),
legendgroup = "stochastic_fast",
- name = "Stochastic %D (Fast)"
+ name = c("Stochastic %D (Fast)", "Lower", "Upper"),
+ showlegend = TRUE
)
- output <- add_title(
- x = output,
- text = "Fast Stochastic"
- )
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = "Fast Stochastic"
+ )
+ }
+
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(output)
+ list(plotly_object)
)
- output
+ plotly_object
}
diff --git a/R/ta_STOCHRSI.R b/R/ta_STOCHRSI.R
index be8eed63b..8d65e336b 100644
--- a/R/ta_STOCHRSI.R
+++ b/R/ta_STOCHRSI.R
@@ -157,13 +157,18 @@ stochastic_relative_strength_index.plotly <- function(
n_rsi = 10,
fast_k = 5,
fast_d_MAtype = SMA(n = 10),
+ lower = 20,
+ upper = 80,
+ color = "lightgray",
+ alpha = 0.7,
...
) {
## input arguments
fast_d_MAtype <- fast_d_MAtype
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for stochastic
+ ## relative strength index
x <- as.data.frame(
series(
x = x,
@@ -173,22 +178,29 @@ stochastic_relative_strength_index.plotly <- function(
)
)
- ## indicator
+ ## calculate indicator
+ ## and return as data.frame
.indicator <- stochastic_relative_strength_index.default(
x = x,
- cols = cols,
+ cols = rebuild_formula(
+ names(x)
+ ),
n = n,
n_rsi = n_rsi,
fast_k = fast_k,
fast_d_MAtype = fast_d_MAtype
)
- .indicator$idx <- 1:nrow(.indicator)
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
- # plot
- output <- plotly::plot_ly(
+ ## generate plotly object
+ ## of the indicator
+ plotly_object <- subchart(
data = .indicator,
- x = ~idx,
y = ~fastk,
type = "scatter",
mode = "lines",
@@ -197,24 +209,32 @@ stochastic_relative_strength_index.plotly <- function(
showlegend = TRUE
)
- output <- plotly::add_lines(
- output,
+ plotly_object <- add_ribbons(
+ plotly_object = plotly_object,
+ data = .indicator,
x = ~idx,
y = ~fastd,
- name = "StochRSI %D",
- legendgroup = "stochrsi",
- showlegend = TRUE
+ ymin = rep(lower, nrow(.indicator)),
+ ymax = rep(upper, nrow(.indicator)),
+ color = color,
+ alpha = alpha,
+ showlegend = TRUE,
+ dash = c("solid", "dot", "dot"),
+ name = c("StochRSI %D", "Lower", "Upper"),
+ legendgroup = "stochrsi"
)
- output <- add_title(
- x = output,
- text = "StochRSI"
- )
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = "StochRSI"
+ )
+ }
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(output)
+ list(plotly_object)
)
- output
+ plotly_object
}
diff --git a/R/ta_T3.R b/R/ta_T3.R
index 43714a729..a478466e3 100644
--- a/R/ta_T3.R
+++ b/R/ta_T3.R
@@ -89,7 +89,7 @@ T3.default <- function(
colnames(x) <- paste0("T3_", colnames(x))
- x
+ as.data.frame(x)
}
#' @rdname T3
@@ -153,8 +153,8 @@ T3.plotly <- function(
n = 10,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for T3
x <- as.data.frame(
series(
x = x,
@@ -164,9 +164,21 @@ T3.plotly <- function(
)
)
- ## indicator
- .indicator <- as.data.frame(NextMethod())
- .indicator$idx <- 1:nrow(.indicator)
+ ## calculator indicator
+ ## and return as data.frame
+ .indicator <- T3.default(
+ x = x,
+ cols = rebuild_formula(
+ x = names(x)
+ ),
+ n = n
+ )
+
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
for (i in 1:ncol(x)) {
local({
@@ -175,7 +187,7 @@ T3.plotly <- function(
.plotting_environment$main,
data = .indicator,
x = ~idx,
- y = ~ .indicator[, j],
+ y = ~ .indicator[[j]],
type = "scatter",
mode = "lines",
name = sprintf("T3(%d)", n),
diff --git a/R/ta_TEMA.R b/R/ta_TEMA.R
index 88d4e1352..b63542f87 100644
--- a/R/ta_TEMA.R
+++ b/R/ta_TEMA.R
@@ -89,7 +89,7 @@ TEMA.default <- function(
colnames(x) <- paste0("tema_", colnames(x))
- x
+ as.data.frame(x)
}
#' @rdname TEMA
@@ -153,8 +153,8 @@ TEMA.plotly <- function(
n = 10,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for TEMA
x <- as.data.frame(
series(
x = x,
@@ -164,9 +164,21 @@ TEMA.plotly <- function(
)
)
- ## indicator
- .indicator <- as.data.frame(NextMethod())
- .indicator$idx <- 1:nrow(.indicator)
+ ## calculator indicator
+ ## and return as data.frame
+ .indicator <- TEMA.default(
+ x = x,
+ cols = rebuild_formula(
+ x = names(x)
+ ),
+ n = n
+ )
+
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
for (i in 1:ncol(x)) {
local({
@@ -175,7 +187,7 @@ TEMA.plotly <- function(
.plotting_environment$main,
data = .indicator,
x = ~idx,
- y = ~ .indicator[, j],
+ y = ~ .indicator[[j]],
type = "scatter",
mode = "lines",
name = sprintf("TEMA(%d)", n),
diff --git a/R/ta_TRIMA.R b/R/ta_TRIMA.R
index 1c5dd371a..7b8d03b18 100644
--- a/R/ta_TRIMA.R
+++ b/R/ta_TRIMA.R
@@ -89,7 +89,7 @@ TRIMA.default <- function(
colnames(x) <- paste0("trima_", colnames(x))
- x
+ as.data.frame(x)
}
#' @rdname TRIMA
@@ -153,8 +153,8 @@ TRIMA.plotly <- function(
n = 10,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for TRIMA
x <- as.data.frame(
series(
x = x,
@@ -164,9 +164,21 @@ TRIMA.plotly <- function(
)
)
- ## indicator
- .indicator <- as.data.frame(NextMethod())
- .indicator$idx <- 1:nrow(.indicator)
+ ## calculator indicator
+ ## and return as data.frame
+ .indicator <- TRIMA.default(
+ x = x,
+ cols = rebuild_formula(
+ x = names(x)
+ ),
+ n = n
+ )
+
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
for (i in 1:ncol(x)) {
local({
@@ -175,7 +187,7 @@ TRIMA.plotly <- function(
.plotting_environment$main,
data = .indicator,
x = ~idx,
- y = ~ .indicator[, j],
+ y = ~ .indicator[[j]],
type = "scatter",
mode = "lines",
name = sprintf("TRIMA(%d)", n),
diff --git a/R/ta_ULTOSC.R b/R/ta_ULTOSC.R
index eeeb93d29..bec46d420 100644
--- a/R/ta_ULTOSC.R
+++ b/R/ta_ULTOSC.R
@@ -109,11 +109,16 @@ ultimate_oscillator.plotly <- function(
x,
cols,
n = c(7, 14, 28),
+ lower = 30,
+ upper = 70,
+ color = "lightgray",
+ alpha = 0.7,
...
) {
- ## prepare series
- ## from
- x <- as.data.frame(
+ ## prepare HLC
+ ## series for ultimate
+ ## oscillator
+ HLC <- as.data.frame(
series(
x = x,
formula = cols,
@@ -122,14 +127,25 @@ ultimate_oscillator.plotly <- function(
)
)
- ## indicator
- .indicator <- as.data.frame(NextMethod())
- .indicator$idx <- 1:nrow(.indicator)
+ ## calculate indicator
+ ## and return as data.frame
+ .indicator <- ultimate_oscillator.default(
+ x = HLC,
+ cols = rebuild_formula(
+ names(HLC)
+ ),
+ n = n
+ )
+
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ HLC
+ )
# plot
- output <- plotly::plot_ly(
+ plotly_object <- subchart(
data = .indicator,
- x = ~idx,
y = ~utimate_oscillator,
type = "scatter",
mode = "lines",
@@ -138,15 +154,31 @@ ultimate_oscillator.plotly <- function(
showlegend = TRUE
)
- output <- add_title(
- x = output,
- text = "Ultimate Oscillator"
+ plotly_object <- add_ribbons(
+ plotly_object = plotly_object,
+ data = .indicator,
+ x = ~idx,
+ ymin = rep(lower, nrow(.indicator)),
+ ymax = rep(upper, nrow(.indicator)),
+ color = color,
+ alpha = alpha,
+ showlegend = TRUE,
+ dash = c("dot", "dot"),
+ name = c("Lower", "Upper"),
+ legendgroup = "stochrsi"
)
+ if (main_chart_exists()) {
+ plotly_object <- add_title(
+ x = plotly_object,
+ text = "Ultimate Oscillator"
+ )
+ }
+
.plotting_environment$sub <- c(
.plotting_environment$sub,
- list(output)
+ list(plotly_object)
)
- output
+ plotly_object
}
diff --git a/R/ta_VOLUME.R b/R/ta_VOLUME.R
new file mode 100644
index 000000000..9c272eb89
--- /dev/null
+++ b/R/ta_VOLUME.R
@@ -0,0 +1,202 @@
+#' @export
+#' @family Volume Indicator
+#'
+#' @title Trading Volume
+#'
+#' @templateVar .title Trading Volume
+#' @templateVar .author Serkan Korkmaz
+#' @templateVar .fun trading_volume
+#'
+#' @param ma An optional list of moving average specifications.
+#'
+#' @template description
+trading_volume <- function(
+ x,
+ cols,
+ ma,
+ ...
+) {
+ UseMethod(
+ "trading_volume"
+ )
+}
+
+#' @export
+#'
+#' @usage NULL
+#'
+#' @rdname trading_volume
+#' @aliases trading_volume
+volume <- trading_volume
+
+#' @rdname trading_volume
+#' @usage NULL
+#' @export
+trading_volume.default <- function(
+ x,
+ cols,
+ ma,
+ ...
+) {
+ ## default behaviour is to
+ ## check if its a numeric vector
+ ##
+ ## No coercing here as it might
+ ## lead to overflow
+ x <- series(
+ x = cols,
+ default = ~volume,
+ data = x,
+ ...
+ )
+
+ ## 0) validate input
+ ## and stop the script
+ ## if conditions are not
+ ## met
+ if (!missing(ma)) {
+ xx <- vapply(
+ ma,
+ FUN = function(ma_) {
+ .Call(
+ "impl_ta_MA",
+ x[[1]],
+ ma_$n,
+ ma_$maType
+ )
+ },
+ FUN.VALUE = double(nrow(x)),
+ USE.NAMES = TRUE
+ )
+
+ x <- as.data.frame(
+ cbind(x, xx)
+ )
+ }
+
+ x
+}
+
+#' @rdname trading_volume
+#' @usage NULL
+#' @export
+trading_volume.numeric <- function(
+ x,
+ cols,
+ ma,
+ ...
+) {
+ if (!missing(cols)) {
+ warning(
+ "'cols' have been passed but is unused in for vectors"
+ )
+ }
+
+ NextMethod()
+}
+
+
+#' @rdname trading_volume
+#' @usage NULL
+#' @export
+trading_volume.data.frame <- function(
+ x,
+ cols,
+ ma,
+ ...
+) {
+ as.data.frame(
+ NextMethod()
+ )
+}
+
+#' @rdname trading_volume
+#' @usage NULL
+#' @export
+trading_volume.matrix <- function(
+ x,
+ cols,
+ ma,
+ ...
+) {
+ as.matrix(
+ NextMethod()
+ )
+}
+
+#' @rdname trading_volume
+#' @usage NULL
+#' @export
+trading_volume.plotly <- function(
+ x,
+ cols,
+ ma,
+ ...
+) {
+ ## prepare univariate
+ ## series for trading_volume
+ x <- as.data.frame(
+ series(
+ x = x,
+ formula = cols,
+ default = ~ open + close + volume,
+ ...
+ )
+ )
+
+ ## calculator indicator
+ ## and return as data.frame
+ .indicator <- trading_volume.default(
+ x = x,
+ cols = rebuild_formula(
+ x = names(x)[names(x) %in% "volume"]
+ ),
+ ma = ma
+ )
+
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
+
+ .indicator$direction <- x$open >= x$close
+
+ ## construct chart
+ chart_theme <- .chart_theme()
+
+ plotly_object <- subchart(
+ data = .indicator,
+ y = ~volume,
+ color = ~direction,
+ colors = c(
+ chart_theme$bull_color,
+ chart_theme$bear_color
+ ),
+ type = 'bar',
+ showlegend = FALSE
+ )
+
+ ## only chart the smoothing lines
+ ## if passed
+ if (!missing(ma)) {
+ for (i in 2:(ncol(.indicator) - 2)) {
+ plotly_object <- plotly::add_trace(
+ plotly_object,
+ data = .indicator,
+ x = ~idx,
+ y = .indicator[[i]],
+ type = "scatter",
+ mode = "lines",
+ inherit = FALSE
+ )
+ }
+ }
+
+ .plotting_environment$sub <- c(
+ .plotting_environment$sub,
+ list(plotly_object)
+ )
+
+ plotly_object
+}
diff --git a/R/ta_WMA.R b/R/ta_WMA.R
index 08875c93c..b440a5664 100644
--- a/R/ta_WMA.R
+++ b/R/ta_WMA.R
@@ -89,7 +89,7 @@ WMA.default <- function(
colnames(x) <- paste0("wma_", colnames(x))
- x
+ as.data.frame(x)
}
#' @rdname WMA
@@ -153,8 +153,8 @@ WMA.plotly <- function(
n = 10,
...
) {
- ## prepare series
- ## from
+ ## prepare univariate
+ ## series for WMA
x <- as.data.frame(
series(
x = x,
@@ -164,9 +164,21 @@ WMA.plotly <- function(
)
)
- ## indicator
- .indicator <- as.data.frame(NextMethod())
- .indicator$idx <- 1:nrow(.indicator)
+ ## calculator indicator
+ ## and return as data.frame
+ .indicator <- WMA.default(
+ x = x,
+ cols = rebuild_formula(
+ x = names(x)
+ ),
+ n = n
+ )
+
+ ## add x-axis conditional on whether
+ ## the data have been subsetted or not
+ .indicator$idx <- add_idx(
+ x
+ )
for (i in 1:ncol(x)) {
local({
@@ -175,7 +187,7 @@ WMA.plotly <- function(
.plotting_environment$main,
data = .indicator,
x = ~idx,
- y = ~ .indicator[, j],
+ y = ~ .indicator[[j]],
type = "scatter",
mode = "lines",
name = sprintf("WMA(%d)", n),
diff --git a/R/utils.R b/R/utils.R
index 9bf1da01b..bc5bbf310 100644
--- a/R/utils.R
+++ b/R/utils.R
@@ -181,3 +181,88 @@ reclass <- function(x, ...) {
is.formula <- function(x) {
inherits(x, "formula")
}
+
+## extract input name
+input_name <- function(x) {
+ if (is.call(x) && as.character(x[[1L]]) %in% c("::", ":::")) {
+ x <- x[[3L]]
+ }
+ deparse(x)
+}
+
+rebuild_formula <- function(
+ x,
+ exclude = "idx"
+) {
+ if (!is.character(x)) {
+ x <- names(x)
+ }
+ ## this function removes
+ ## idx and rebuilds the passed
+ ## series as formulas
+ idx <- grepl(
+ pattern = exclude,
+ x = x,
+ ignore.case = TRUE
+ )
+
+ stats::reformulate(
+ x[!idx]
+ )
+}
+
+add_idx <- function(x) {
+ ## store idx
+ idx <- .plotting_environment$idx$label
+
+ if (!is.null(idx)) {
+ idx[
+ if (is.null(attributes(x)$subset)) {
+ 1:nrow(x)
+ } else {
+ attributes(x)$subset
+ }
+ ]
+ } else {
+ 1:nrow(x)
+ }
+}
+
+to_title <- function(
+ x
+) {
+ ## remove underscores
+ ## if preset
+ x <- gsub(pattern = "_", replacement = " ", x = x)
+ gsub("\\b(.)", "\\U\\1", tolower(x), perl = TRUE)
+}
+
+
+has_arg <- function(name) {
+ ## shamelessly stolen from
+ ## {methods}
+ aname <- as.character(substitute(name))
+ fnames <- names(
+ formals(
+ sys.function(sys.parent())
+ )
+ )
+
+ if (is.na(match(aname, fnames))) {
+ if (is.na(match("...", fnames))) {
+ FALSE
+ } else {
+ dotsCall <- eval(quote(substitute(list(...))), sys.parent())
+ !is.na(match(aname, names(dotsCall)))
+ }
+ } else {
+ eval(substitute(!missing(name)), sys.frame(sys.parent()))
+ }
+}
+
+
+## main chart called
+## function
+main_chart_exists <- function() {
+ !is.null(.plotting_environment$main)
+}
diff --git a/README.Rmd b/README.Rmd
index 290bbabe9..c1a03a76e 100644
--- a/README.Rmd
+++ b/README.Rmd
@@ -6,19 +6,20 @@ output: github_document
```{r setup, include = FALSE}
# set options
-Sys.setenv(OPENSSL_CONF="/dev/null")
+Sys.setenv(OPENSSL_CONF = "/dev/null")
knitr::opts_chunk$set(
- collapse = FALSE,
- comment = "#>",
- fig.path = "man/figures/README-",
- message = FALSE,
- warning = FALSE,
- echo = FALSE
+ collapse = TRUE,
+ comment = "#>",
+ fig.path = "man/figures/README-",
+ fig.dpi = 120,
+ message = FALSE,
+ warning = FALSE,
+ echo = FALSE
)
```
-# {talib}: R bindings for [TA-Lib](https://github.com/TA-Lib/ta-lib)
+# {talib}: A Technical Analysis and Candlestick Pattern Library in R
[](https://github.com/serkor1/ta-lib-R/actions/workflows/R-CMD-check.yaml)
@@ -27,85 +28,100 @@ knitr::opts_chunk$set(
[](https://r-pkg.org/pkg/talib)
-[{talib}]() provides high-performance R bindings to the [TA-Lib](https://github.com/TA-Lib/ta-lib) C-library for Technical Analysis indicators, Candlestick patterns and interactive charting via [{plotly}]().
+[{talib}](https://serkor1.github.io/ta-lib-R/) is an `R`-package for Technical Analysis and algorithmic Candlestick pattern recognition built on the `C` library [TA-Lib](https://github.com/TA-Lib/ta-lib). [{talib}](https://serkor1.github.io/ta-lib-R/) extends [{TTR}](https://github.com/joshuaulrich/TTR) by adding Candlestick pattern recognition to the pool of available indicators, and interactive charts via [{plotly}](https://github.com/plotly/plotly.R).
-## Installation
+[TA-Lib](https://github.com/TA-Lib/ta-lib) supports 200+ indicators for Technical Analysis and Candlestick Patterns, all of which are available in [{talib}](https://serkor1.github.io/ta-lib-R/).
-### Stable version
-```{r devel_install, echo = TRUE, eval = FALSE}
-pak::pak("talib")
-```
+## Types of Indicators and Interface
-### Development version
+In the core C library functions are named as `TA_INDICATOR()` and `TA_CDLPATTERN()` for indicators and patterns respectively. In the `Python`-wrapper the functions are named `INDICATOR()` and `CDLPATTERN()`---but this `R` package follows the [tidyverse styleguide](https://style.tidyverse.org/) and therefore the naming is inconsistent with the core library and the Python wrapper. See below for an example of the mapping:
-The development version can be installed by recursive cloning the repository and using the available build tools as follows:
+
+# {talib}: A Technical Analysis and Candlestick Pattern Library in R
@@ -14,103 +14,138 @@ status](https://www.r-pkg.org/badges/version/talib)](https://CRAN.R-project.org/
downloads](https://cranlogs.r-pkg.org/badges/last-month/talib?color=blue)](https://r-pkg.org/pkg/talib)
-[{talib}]() provides high-performance R bindings to the
-[TA-Lib](https://github.com/TA-Lib/ta-lib) C-library for Technical
-Analysis indicators, Candlestick patterns and interactive charting via
-[{plotly}]().
-
-## Installation
-
-### Stable version
+[{talib}](https://serkor1.github.io/ta-lib-R/) is an `R`-package for
+Technical Analysis and algorithmic Candlestick pattern recognition built
+on the `C` library [TA-Lib](https://github.com/TA-Lib/ta-lib).
+[{talib}](https://serkor1.github.io/ta-lib-R/) extends
+[{TTR}](https://github.com/joshuaulrich/TTR) by adding Candlestick
+pattern recognition to the pool of available indicators, and interactive
+charts via [{plotly}](https://github.com/plotly/plotly.R).
+
+[TA-Lib](https://github.com/TA-Lib/ta-lib) supports 200+ indicators for
+Technical Analysis and Candlestick Patterns, all of which are available
+in [{talib}](https://serkor1.github.io/ta-lib-R/).
+
+## Types of Indicators and Interface
+
+In the core C library functions are named as `TA_INDICATOR()` and
+`TA_CDLPATTERN()` for indicators and patterns respectively. In the
+`Python`-wrapper the functions are named `INDICATOR()` and
+`CDLPATTERN()`—but this `R` package follows the [tidyverse
+styleguide](https://style.tidyverse.org/) and therefore the naming is
+inconsistent with the core library and the Python wrapper. See below for
+an example of the mapping:
+
+
+## Installation
+
+[TA-Lib](https://github.com/TA-Lib/ta-lib) is vendored in
+[{talib}](https://serkor1.github.io/ta-lib-R/) via `CMake`, so it is not
+necessary to have [TA-Lib](https://github.com/TA-Lib/ta-lib)
+pre-installed.[^1]
+
+### Stable version
+
+``` r
+pak::pak("talib")
+```
+
+### Development version
+
+The development version can be installed by recursive cloning the
+repository and using the available build tools as follows:
+
+``` shell
+git clone --recursive https://github.com/serkor1/ta-lib-R.git
+cd ta-lib-R
+make build
+```
+
+Use `make` to see package-level build-tools.
+
## Code of Conduct
-Please note that [{talib}]() is released with a [Contributor Code of
+Please note that [{talib}](https://serkor1.github.io/ta-lib-R/) is
+released with a [Contributor Code of
Conduct](https://contributor-covenant.org/version/2/1/CODE_OF_CONDUCT.html).
By contributing to this project, you agree to abide by its terms.
+
+[^1]: Some systems (Windows in particular) may require you to explicitly
+ install and link `CMake` for
+ [{talib}](https://serkor1.github.io/ta-lib-R/) to build properly.
diff --git a/man/chaikin_AD_line.Rd b/man/chaikin_AD_line.Rd
index 26e94e7b5..dceacc987 100644
--- a/man/chaikin_AD_line.Rd
+++ b/man/chaikin_AD_line.Rd
@@ -62,7 +62,8 @@ utils::tail(output)
\seealso{
Other Volume Indicator:
\code{\link{chaikin_AD_oscillator}()},
-\code{\link{on_balance_volume}()}
+\code{\link{on_balance_volume}()},
+\code{\link{trading_volume}()}
}
\author{
Serkan Korkmaz
diff --git a/man/chaikin_AD_oscillator.Rd b/man/chaikin_AD_oscillator.Rd
index 816cc45bc..9fa7e6129 100644
--- a/man/chaikin_AD_oscillator.Rd
+++ b/man/chaikin_AD_oscillator.Rd
@@ -66,7 +66,8 @@ utils::tail(output)
\seealso{
Other Volume Indicator:
\code{\link{chaikin_AD_line}()},
-\code{\link{on_balance_volume}()}
+\code{\link{on_balance_volume}()},
+\code{\link{trading_volume}()}
}
\author{
Serkan Korkmaz
diff --git a/man/chart.Rd b/man/chart.Rd
index 461c5672e..181c7ab9b 100644
--- a/man/chart.Rd
+++ b/man/chart.Rd
@@ -4,13 +4,17 @@
\alias{chart}
\title{Chart}
\usage{
-chart(x, type = "candlestick", ...)
+chart(x, type = "candlestick", idx = NULL, title, ...)
}
\arguments{
\item{x}{An OHLC object to be charted.}
\item{type}{A \link{character} of \link{length} 1. Either \code{candlestick} or \code{ohlc}.}
+\item{idx}{A \link{vector} with the same \link{length} of \code{x}. If passed it will replace the x-axis labels. See \code{vignette("charting")} for more details.}
+
+\item{title}{An optional \link{character} vector of \link{length} 1.}
+
\item{...}{Parameters passed into \link[plotly:plot_ly]{plotly::plot_ly}}
}
\description{
diff --git a/man/figures/README-charting-1.png b/man/figures/README-charting-1.png
index 92dee688f..a8b21d835 100644
Binary files a/man/figures/README-charting-1.png and b/man/figures/README-charting-1.png differ
diff --git a/man/figures/README-unnamed-chunk-3-1.png b/man/figures/README-unnamed-chunk-3-1.png
new file mode 100644
index 000000000..bcf777dd0
Binary files /dev/null and b/man/figures/README-unnamed-chunk-3-1.png differ
diff --git a/man/on_balance_volume.Rd b/man/on_balance_volume.Rd
index 3c6b7e140..db9fcac69 100644
--- a/man/on_balance_volume.Rd
+++ b/man/on_balance_volume.Rd
@@ -57,7 +57,8 @@ utils::tail(output)
\seealso{
Other Volume Indicator:
\code{\link{chaikin_AD_line}()},
-\code{\link{chaikin_AD_oscillator}()}
+\code{\link{chaikin_AD_oscillator}()},
+\code{\link{trading_volume}()}
}
\author{
Serkan Korkmaz
diff --git a/man/subchart.Rd b/man/subchart.Rd
new file mode 100644
index 000000000..51db8b0fa
--- /dev/null
+++ b/man/subchart.Rd
@@ -0,0 +1,21 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/chart_elements.R
+\name{subchart}
+\alias{subchart}
+\title{subchart}
+\usage{
+subchart(data, ...)
+}
+\arguments{
+\item{data}{\link{data.frame}}
+
+\item{...}{arguments passed onto \link[plotly:plot_ly]{plotly::plot_ly}}
+}
+\description{
+subchart
+}
+\details{
+A helper function for creating subcharts with prespecified
+xaxis and x values
+}
+\keyword{internal}
diff --git a/man/trading_volume.Rd b/man/trading_volume.Rd
new file mode 100644
index 000000000..e42e39b1e
--- /dev/null
+++ b/man/trading_volume.Rd
@@ -0,0 +1,75 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/ta_VOLUME.R
+\name{trading_volume}
+\alias{trading_volume}
+\alias{volume}
+\alias{trading_volume.default}
+\alias{trading_volume.numeric}
+\alias{trading_volume.data.frame}
+\alias{trading_volume.matrix}
+\alias{trading_volume.plotly}
+\title{Trading Volume}
+\usage{
+trading_volume(x, cols, ma, ...)
+}
+\arguments{
+\item{x}{An OHLC-V series that is coercible to \link{data.frame}. The function assumes that all columns are named in lowercase and order invariant.}
+
+\item{cols}{An optional \link{formula} passed into \link{model.frame}. If passed into indicators based on univariate series, the function calculates indicators for each element in 'cols'. For indicators based on multivariate series, it will alter the calculation itself. See \code{vignette("talib")} for more details.}
+
+\item{ma}{An optional list of moving average specifications.}
+
+\item{...}{Additional parameters passed into \link{model.frame}}
+}
+\description{
+The \code{trading_volume()} is a generic S3 function that builds upon 'type-safe'-esque workflows limited to classes in in base \code{R}, and the package-wide
+dependencies. Ie. \link{class} in, \link{class} out. Each method is a soft wrapper of \link{model.frame} and therefore the OHLC-V series must be coercible to a \link{data.frame}.
+This rule does not transfer to indicators that uses univariate series, unless passed as a 1-column \link{data.frame} or \link{matrix}. In such cases, if univariate series
+is passed as a \link{vector} the function calculates the indicator 'as is', and returns a \link{data.frame} if the indicator itself is also a univariate series.
+
+The indicator, by default, follows its mathematical definition. However, the \code{cols} argument allows for simple rearrangement of the definition by passing relevant
+columns in a custom order. Refer to the details-section for more on the calculation of the indicators.
+}
+\examples{
+## load Bitcoin (BTC)
+## series
+data(BTC, package = "talib")
+
+## calculate the indicator
+## for Bitcoin (BTC)
+output <- talib::trading_volume(BTC)
+
+## display the results
+utils::tail(output)
+
+## visualize the indicator
+## with candlesticks
+##
+## see ?talib::chart or ?talib::indicator
+## for more details
+{
+ ## chart OHLC-V
+ ## series with candlesticks
+ talib::chart(BTC)
+
+ ## chart indicator
+ ## with default values
+ talib::indicator(
+ talib::trading_volume
+ )
+}
+}
+\seealso{
+Other Volume Indicator:
+\code{\link{chaikin_AD_line}()},
+\code{\link{chaikin_AD_oscillator}()},
+\code{\link{on_balance_volume}()}
+}
+\author{
+Serkan Korkmaz
+}
+\concept{Volume Indicator}
+\concept{algorithmic trading}
+\concept{finance}
+\concept{technical analysis}
+\concept{trading}
diff --git a/vignettes/charting.Rmd b/vignettes/charting.Rmd
new file mode 100644
index 000000000..c9ca7363e
--- /dev/null
+++ b/vignettes/charting.Rmd
@@ -0,0 +1,147 @@
+---
+title: "Interactive Financial Charts"
+output: rmarkdown::html_vignette
+vignette: >
+ %\VignetteIndexEntry{Interactive Financial Charts}
+ %\VignetteEngine{knitr::rmarkdown}
+ %\VignetteEncoding{UTF-8}
+author: Serkan Korkmaz
+---
+
+```{r, include = FALSE}
+knitr::opts_chunk$set(
+ collapse = TRUE,
+ comment = "#>",
+ out.width = "100%",
+ out.height = "680",
+ fig.align = "center"
+)
+```
+
+## Price Charts
+
+### Candlestick Chart
+
+```{r}
+talib::chart(
+ x = talib::NVDA,
+ type = "candlestick"
+)
+```
+
+### OHLC Chart
+```{r}
+talib::chart(
+ x = talib::BTC,
+ type = "ohlc"
+)
+```
+
+By default the `chart`-function inherits name of the argument `x` as the title. This can be modified via the `title`-argument.
+
+```{r}
+talib::chart(
+ x = talib::BTC,
+ type = "ohlc",
+ title = "SPDR S&P 500 ETF Trust"
+)
+```
+
+## Charting indicators
+
+The various indicators can be added to the price chart---or charted seperately---with the `indicator`-function. The `indicator`-function will attach itself to the last chart.
+
+```{r}
+talib::indicator(
+ FUN = talib::MACD
+)
+```
+
+If you have already called the `chart`-function, and want to plot the indicator seperately you will have to clear the existing chart---this is done by calling `talib::chart()` without any arguments. The indicator can now be re-charted using the `indicator`-function.
+
+```{r}
+{
+ ## clear the chart
+ ## by calling talib::chart()
+ ## without any arguments
+ talib::chart()
+
+ ## rechart the indicator
+ ## directly
+ talib::indicator(
+ FUN = talib::MACD,
+ data = talib::BTC
+ )
+}
+```
+
+Notice here that you have to pass a `data` argument via `...` which gets passed downstream to `MACD`.
+
+## Modifying charts
+
+The charts can be globally modified via `options` use `?talib::chart` to see the full range of modifications available for the charting. Below is an example on how to modify the color scheme of the charts.
+
+```{r}
+## modify options
+## to create charts in
+## light and color-deficiency mode
+options(
+ talib.chart.dark = FALSE,
+ talib.chart.deficieny = TRUE
+)
+
+{
+ ## price chart
+ ## with defaults
+ talib::chart(
+ talib::SPY
+ )
+
+ ## add RSI indicator
+ talib::indicator(
+ FUN = talib::RSI
+ )
+
+ ## add Bollinger Bands
+ talib::indicator(
+ FUN = talib::BBANDS
+ )
+
+}
+```
+
+### Modifying x-axis labels
+
+Internally `chart()` and `indicator()` are working on the range of the the data---ie. `1:nrow(data)`---to easy the process of subsetting and for the efficiency. The x-axis can be labelled with dates from the data via the `idx`-argument.
+
+```{r}
+{
+ talib::chart(
+ x = talib::BTC,
+ idx = rownames(talib::BTC)
+ )
+}
+```
+
+### Charting Subsets
+
+The downstream indicator functions uses `model.frame` as the main function. This is useful in cases where the interest lies in indicators across a specific range without wanting to subset the data itself, or if you want to change indicators over time.
+
+```{r}
+{
+ talib::chart(
+ x = talib::BTC,
+ idx = rownames(talib::BTC)
+ )
+
+ talib::indicator(
+ talib::BBANDS,
+ subset = 1:nrow(talib::BTC) %in% c(50:100)
+ )
+
+ talib::indicator(
+ talib::ACCBANDS,
+ subset = 1:nrow(talib::BTC) %in% c(101:151)
+ )
+}
+```