From ccab79be5d5ae14626002829ab96d05f87d5b3a0 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Fri, 31 Jul 2026 22:13:03 +0200 Subject: [PATCH 01/22] :books: Alphabet -data * The data is extracted using {quantmod} and is stored as an -object that is to be used for examples, vignettes and tests. --- R/GOOGL.R | 36 ++++++++++++++++++++++++++++++++++++ data-raw/GOOGL.R | 18 ++++++++++++++++++ data/GOOGL.rda | Bin 0 -> 18336 bytes 3 files changed, 54 insertions(+) create mode 100644 R/GOOGL.R create mode 100644 data-raw/GOOGL.R create mode 100644 data/GOOGL.rda diff --git a/R/GOOGL.R b/R/GOOGL.R new file mode 100644 index 000000000..4d3ffef02 --- /dev/null +++ b/R/GOOGL.R @@ -0,0 +1,36 @@ +#' @name GOOGL +#' @title Alphabet Inc. (GOOGL) +#' +#' @description +#' Daily OHLCV price data for Alphabet Inc. (GOOGL), denominated in +#' USD, covering 2019-01-01 to 2021-12-31. Stored as an `xts` object +#' with a `Date` index and quantmod-style prefixed column names - the +#' exact shape returned by `quantmod::getSymbols()` - and used by the +#' unit tests for the `xts` methods. +#' +#' @format An `xts` object with 756 rows and 6 columns. +#' +#' \describe{ +#' \item{GOOGL.Open}{Opening price for the trading day.} +#' \item{GOOGL.High}{Highest price reached during the trading day.} +#' \item{GOOGL.Low}{Lowest price reached during the trading day.} +#' \item{GOOGL.Close}{Closing price for the trading day.} +#' \item{GOOGL.Volume}{Total trading volume for the day.} +#' \item{GOOGL.Adjusted}{Adjusted closing price for the trading day.} +#' } +#' +#' @source Loaded using [quantmod](https://cran.r-project.org/web/packages/quantmod/index.html). +#' +#' @concept Financial Data +#' @concept OHLCV +#' +#' @docType data +#' @keywords datasets +#' +#' @examples +#' ## Load the dataset +#' data(GOOGL, package = "talib") +#' +#' ## Scan for Doji patterns on GOOGL +#' talib::doji(GOOGL) +"GOOGL" diff --git a/data-raw/GOOGL.R b/data-raw/GOOGL.R new file mode 100644 index 000000000..ab36a311e --- /dev/null +++ b/data-raw/GOOGL.R @@ -0,0 +1,18 @@ +## script: GOOGL +## objective: Generate GOOGL +## data for the R package +## using {quantmod} +## +## 1) load data +GOOGL <- quantmod::getSymbols( + Symbols = "GOOGL", + auto.assign = FALSE, + from = as.Date("2019-01-01"), + to = as.Date("2021-12-31") +) + +## 2) store data +usethis::use_data( + GOOGL, + overwrite = TRUE +) diff --git a/data/GOOGL.rda b/data/GOOGL.rda new file mode 100644 index 0000000000000000000000000000000000000000..71f9c34312b4e0ce95aab4059543daa6bb065e03 GIT binary patch literal 18336 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

8N?v%VP`n^*txNqBx^bNFF*T|um2qxTr> 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 O{}*yaI8cy@ycru*r~Oa> literal 0 HcmV?d00001 From 157a55ee95ad2005b20f82d64e59788a3374ee3f Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Fri, 31 Jul 2026 22:14:39 +0200 Subject: [PATCH 02/22] :hammer: Suggest and --- DESCRIPTION | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index b165ba4a1..80ed27e1a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -41,7 +41,9 @@ Suggests: knitr, plotly, rmarkdown, - testthat (>= 3.0.0) + testthat (>= 3.0.0), + xts, + zoo Config/testthat/edition: 3 Depends: R (>= 3.5) From a4985748fbb0c4364c85e89e6558aea4788ba00b Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Sun, 2 Aug 2026 18:49:07 +0200 Subject: [PATCH 03/22] :hammer: Added -class to TA-Lib output * The added class will ease the downstream coding process when adding -methods to the indicators. --- src/wrapper.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/wrapper.h b/src/wrapper.h index 8a32a55a2..12b033fa7 100644 --- a/src/wrapper.h +++ b/src/wrapper.h @@ -8,6 +8,7 @@ #define WRAPPER_H #include "NA-handling.h" +#include "Rinternals.h" #include "attributes.h" #include "names.h" #include "normalize.h" @@ -234,6 +235,14 @@ &protection_counter \ ); \ \ + /* Attach classes to output so its easier to work with downstream */ \ + SEXP TA_CLASS = PROTECT(Rf_allocVector(STRSXP, 3)); \ + protection_counter++; \ + SET_STRING_ELT(TA_CLASS, 0, Rf_mkChar("ta_object")); \ + SET_STRING_ELT(TA_CLASS, 1, Rf_mkChar("matrix")); \ + SET_STRING_ELT(TA_CLASS, 2, Rf_mkChar("array")); \ + Rf_setAttrib(out, R_ClassSymbol, TA_CLASS); \ + \ UNPROTECT(protection_counter); \ return out; \ } \ From 7a2b3f54c501170da320bad396d2f5820ea3c7b2 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Mon, 3 Aug 2026 07:41:09 +0200 Subject: [PATCH 04/22] :hammer: Introduce index() and set_index() * The index refers to the time-index of the object passed into the indicator functions. By default, for and , it (was) is assumed that these are given in the rownames() of the passed OHLC-V object. For an -object the time-index is given as the index attribute - that is just how works which necessitates this change. * With this introduction , and objects can be handled in the default method which reduces the number of lines changed for the introduction of the -methods. Any changes and bugs can potentially be handled in the dispatching functions like, for example, series.xts() to avoid a mass change in files for a simple bug. --- NAMESPACE | 4 ++++ R/utils.R | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++-- src/init.c | 5 +++-- src/names.c | 23 ++++++++++++++++++--- src/names.h | 5 +++-- 5 files changed, 85 insertions(+), 9 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index b03a1bff8..0d03aaad3 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -269,6 +269,8 @@ S3method(in_neck,default) S3method(in_neck,ggplot) S3method(in_neck,matrix) S3method(in_neck,plotly) +S3method(index,default) +S3method(index,xts) S3method(indicator,"function") S3method(intraday_movement_index,data.frame) S3method(intraday_movement_index,default) @@ -497,6 +499,8 @@ S3method(separating_lines,plotly) S3method(series,formula) S3method(series,ggplot) S3method(series,plotly) +S3method(set_index,character) +S3method(set_index,numeric) S3method(set_rownames,data.frame) S3method(set_rownames,matrix) S3method(shooting_star,data.frame) diff --git a/R/utils.R b/R/utils.R index 74b1febe3..79dd7a1b4 100644 --- a/R/utils.R +++ b/R/utils.R @@ -298,6 +298,59 @@ candlestick_setting <- function() { invisible(NULL) } +index <- function(x) { + UseMethod("index") +} + +#' @export +index.default <- function(x) { + rownames(x) +} + +#' @export +index.xts <- function(x) { + attr( + x = x, + which = "index" + ) +} + +## Index +set_index <- function(x, value) { + UseMethod("set_index", object = value) +} + +#' @export +set_index.character <- function(x, value) { + if (is.matrix(x)) { + .Call( + C_index_matrix, + x, + value, + colnames(x) + ) + } else { + ## set the rownames + .Call( + C_index_data_frame, + x, + value + ) + } + + return(invisible(NULL)) +} + +#' @export +set_index.numeric <- function(x, value) { + .Call( + C_index_xts, + x, + value + ) + + return(invisible(NULL)) +} ## rownaming set_rownames <- function(x, x_names) { @@ -308,7 +361,7 @@ set_rownames <- function(x, x_names) { set_rownames.data.frame <- function(x, x_names) { ## set the rownames .Call( - C_rownames_data_frame, + C_index_data_frame, x, x_names ) @@ -320,7 +373,7 @@ set_rownames.data.frame <- function(x, x_names) { set_rownames.matrix <- function(x, x_names) { ## set the rownames .Call( - C_rownames_matrix, + C_index_matrix, x, x_names, colnames(x) diff --git a/src/init.c b/src/init.c index 1d5ad3068..f5fccc864 100644 --- a/src/init.c +++ b/src/init.c @@ -85,8 +85,9 @@ static const R_CallMethodDef CallEntries[] = { {"ta_set_compatibility", (DL_FUNC)&ta_set_compatibility, 1}, {"set_candle_setting", (DL_FUNC)&set_candle_setting, 4}, {"reset_candle_setting", (DL_FUNC)&reset_candle_setting, 1}, - {"rownames_data_frame", (DL_FUNC)&rownames_data_frame, 2}, - {"rownames_matrix", (DL_FUNC)&rownames_matrix, 3}, + {"index_data_frame", (DL_FUNC)&index_data_frame, 2}, + {"index_matrix", (DL_FUNC)&index_matrix, 3}, + {"index_xts", (DL_FUNC)&index_xts, 2}, {"map_dfr_double", (DL_FUNC)&map_dfr_double, 1}, {"map_dfr_integer", (DL_FUNC)&map_dfr_integer, 1}, {"initialize_ta_lib", (DL_FUNC)&initialize_ta_lib, 0}, diff --git a/src/names.c b/src/names.c index afea23cdb..abb71fec4 100644 --- a/src/names.c +++ b/src/names.c @@ -62,8 +62,8 @@ void set_colnames( // it will crash. // clang-format off -void rownames_data_frame( - SEXP x, +void index_data_frame( + SEXP x, SEXP rownames ) // clang-format on @@ -74,7 +74,7 @@ void rownames_data_frame( } // clang-format off -void rownames_matrix( +void index_matrix( SEXP x, SEXP rownames, SEXP colnames @@ -94,5 +94,22 @@ void rownames_matrix( UNPROTECT(1); + return; +} + +// Index of the -object +// +// Installs the 'index'-attribute on x. The value is the +// index of the input -object, i.e. zoo::index(x), +// and is attached as-is. +// clang-format off +void index_xts( + SEXP x, + SEXP index +) +// clang-format on +{ + Rf_setAttrib(x, Rf_install("index"), index); + return; } \ No newline at end of file diff --git a/src/names.h b/src/names.h index 3c9d04916..da95b8440 100644 --- a/src/names.h +++ b/src/names.h @@ -4,7 +4,8 @@ #include void set_colnames(SEXP x, const char *const *names, int k); -void rownames_data_frame(SEXP x, SEXP rownames); -void rownames_matrix(SEXP x, SEXP rownames, SEXP colnames); +void index_data_frame(SEXP x, SEXP rownames); +void index_matrix(SEXP x, SEXP rownames, SEXP colnames); +void index_xts(SEXP x, SEXP index); #endif /* NAMES_H */ From 9c039dbd9d91ded8caf25124764b4492170180a3 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 09:46:17 +0200 Subject: [PATCH 05/22] :hammer: Reworked series() * The signature of the series function is now more "straightforward," in the sense that there are no dispatch switching conditional on how the arguments are passed. This was a change that was long due, as it was a rather confusing construction. The series() is now a more proper S3 function that has a method for each of the relevant data classes. * A new (classed) method has been introduced to accomodate the methods in the indicator functions. The method adds an explicit class to the method such that the methods can implemented without further changes to the default methods on the indicator side. There have been introduced a wide variety of functions in utils.R to accomodate this change. * Unit-tests have been rewritten so it fits the new series() structure, which has the same underlying logic but a changed input arguments. --- R/helper.R | 15 +++ R/series.R | 190 ++++++++++++++++++++++++----------- R/utils.R | 48 +++++++++ tests/testthat/test-series.R | 107 ++++++++++++++------ 4 files changed, 268 insertions(+), 92 deletions(-) diff --git a/R/helper.R b/R/helper.R index a039e678e..3bd0b83a6 100644 --- a/R/helper.R +++ b/R/helper.R @@ -196,3 +196,18 @@ is.empty.list <- function(x) { is.empty.character <- function(x) { identical(x, character(0)) | grepl("^[[:space:]]*$", x) } + + +as.title_case <- function(x) { + gsub( + pattern = "(^|_)([[:alpha:]])", + replacement = "\\1\\U\\2", + x = x, + perl = TRUE + ) +} + +#' @export +`[[.ta_series` <- function(x, i, ...) { + x[, i] +} diff --git a/R/series.R b/R/series.R index ae62534eb..1a0658811 100644 --- a/R/series.R +++ b/R/series.R @@ -15,9 +15,9 @@ #' Effectively a thin wrapper around [stats::model.frame()]. #' #' @param x Dispatch target: a `formula`, `ggplot`, or `plotly` object. -#' May be omitted by the caller, in which case `default_formula` is +#' May be omitted by the caller, in which case `formula.default` is #' substituted in so dispatch always has a real target. -#' @param default_formula The indicator's default formula +#' @param formula.default The indicator's default formula #' (e.g. `~close`, `~high + low + close`). Used as the fallback for #' `x` and as the minimum-length check in [series.formula()]. #' @param ... Forwarded to the dispatched method - typically `data` @@ -28,43 +28,37 @@ #' @noRd series <- function( x, - default_formula, + formula, ## passed formula + formula.default, ## default formula ... ) { - ## Callers may omit `x` when they want the default formula used - ## wholesale (e.g. indicator(RSI, data = df) with no cols). Populate - ## `x` early so dispatch always has a real target. - if (missing(x)) { - x <- default_formula - } - UseMethod("series", x) } #' Chart-pipeline entry for ggplot backends. Resolves `formula` against -#' `default_formula` and delegates to [.series_chart_dispatch()]. +#' `formula.default` and delegates to [.series_chart_dispatch()]. #' #' @param x The active `ggplot` chart object dispatched on. -#' @param default_formula The indicator's default formula (e.g. +#' @param formula.default The indicator's default formula (e.g. #' `~close`). #' @param formula Optional explicit column formula; falls back to -#' `default_formula` when missing. +#' `formula.default` when missing. #' @param ... Quoted by the dispatcher and forwarded to #' [stats::model.frame()] - typically `data` and optional `subset`. #' @noRd #' @export series.ggplot <- function( x, - default_formula, formula, + formula.default, ... ) { if (missing(formula)) { - formula <- default_formula + formula <- formula.default } .series_chart_dispatch( x = x, - default_formula = default_formula, + formula.default = formula.default, formula = formula, ... ) @@ -74,26 +68,26 @@ series.ggplot <- function( #' [series.ggplot()]. #' #' @param x The active `plotly` chart object dispatched on. -#' @param default_formula The indicator's default formula (e.g. +#' @param formula.default The indicator's default formula (e.g. #' `~close`). #' @param formula Optional explicit column formula; falls back to -#' `default_formula` when missing. +#' `formula.default` when missing. #' @param ... Quoted by the dispatcher and forwarded to #' [stats::model.frame()] - typically `data` and optional `subset`. #' @noRd #' @export series.plotly <- function( x, - default_formula, formula, + formula.default, ... ) { if (missing(formula)) { - formula <- default_formula + formula <- formula.default } .series_chart_dispatch( x = x, - default_formula = default_formula, + formula.default = formula.default, formula = formula, ... ) @@ -110,7 +104,7 @@ series.plotly <- function( #' on ETH while computing RSI on BTC). #' #' @param x The chart object dispatched on (`ggplot` / `plotly`). -#' @param default_formula The indicator's default formula. +#' @param formula.default The indicator's default formula. #' @param formula Resolved column formula (already defaulted by the #' caller). #' @param ... Caller dots; quoted here so [stats::model.frame()] can @@ -118,8 +112,8 @@ series.plotly <- function( #' @noRd .series_chart_dispatch <- function( x, - default_formula, formula, + formula.default, ... ) { dots_quoted <- as.list( @@ -156,11 +150,18 @@ series.plotly <- function( dots_quoted$data <- state$x } + data_arg <- dots_quoted$data + dots_quoted$data <- NULL + output <- as.data.frame( do.call( - series.formula, + series, c( - list(x = formula, default_formula = default_formula), + list( + x = data_arg, + formula = formula, + formula.default = formula.default + ), dots_quoted ), quote = FALSE @@ -174,7 +175,7 @@ series.plotly <- function( #' Formula method - the main column-resolution path. #' #' Validates that an explicit `x` covers at least the variables -#' expected by `default_formula`, fast-coerces plain numeric matrices +#' expected by `formula.default`, fast-coerces plain numeric matrices #' via the C helper in `src/dataframe.c`, defers classed inputs (xts, #' zoo, tibble, ...) to [as.data.frame()] for proper method dispatch, #' then builds the model frame. Skips [stats::model.frame()] entirely @@ -182,34 +183,34 @@ series.plotly <- function( #' bare-data path. #' #' @param x A `formula` selecting OHLCV columns (e.g. `~close`, -#' `~high + low + close`). Falls back to `default_formula` when +#' `~high + low + close`). Falls back to `formula.default` when #' missing - the generic populates `x`, but `UseMethod()` re-invokes #' with the original args, so the missing check has to repeat here. -#' @param default_formula The indicator's default formula. Sets the +#' @param formula.default The indicator's default formula. Sets the #' minimum acceptable length for an explicit `x`. #' @param data A data frame, plain numeric matrix, or any object with #' an [as.data.frame()] method. #' @param ... Forwarded to [stats::model.frame()] - typically `subset`. #' @noRd #' @export -series.formula <- function( +series.data.frame <- function( x, - default_formula, - data, + formula, + formula.default, ... ) { - ## UseMethod re-invokes the method with the *original* arguments, - ## so a missing `x` in the generic stays missing here even though - ## the generic assigned it. Re-resolve before touching `x`. - if (missing(x)) { - x <- default_formula + # ## UseMethod re-invokes the method with the *original* arguments, + # ## so a missing `x` in the generic stays missing here even though + # ## the generic assigned it. Re-resolve before touching `x`. + if (missing(formula)) { + formula <- formula.default } ## An explicit formula must cover at least the variables expected by ## the indicator's default. A longer formula is allowed - downstream ## code only consumes what it needs. - formula_length <- length(all.vars(x)) - default_length <- length(all.vars(default_formula)) + formula_length <- length(all.vars(formula)) + default_length <- length(all.vars(formula.default)) assert( x = formula_length >= default_length, @@ -218,42 +219,24 @@ series.formula <- function( paste0("Got length ", formula_length, "."), paste0( "Uses ", - paste0("'", all.vars(default_formula), "'", collapse = ", "), + paste0("'", all.vars(formula.default), "'", collapse = ", "), " by default." ) ) - ## Fast matrix -> data.frame coercion via the C helper in - ## src/dataframe.c. Restricted to *plain* numeric matrices: an - ## explicit class (xts, zoo, tibble, ...) is left to as.data.frame - ## so the dispatch system picks the correct coercion method. - if ( - is.matrix(data) && - is.null(oldClass(data)) && - typeof(data) %in% c("double", "integer") - ) { - data <- map_dfr(data) - } else if (!is.data.frame(data)) { - ## map_dfr only registers methods for plain double / integer - ## matrices, so anything carrying an explicit class (xts, zoo, - ## tibble, ...) or a non-numeric type has to go through - ## as.data.frame so its method-dispatched coercion runs. - data <- as.data.frame(data) - } - assert_column_names( - formula = x, - available_variables = colnames(data) + formula = formula, + available_variables = colnames(x) ) dots_quoted <- as.list(substitute(list(...)))[-1L] if (length(dots_quoted) == 0L) { - output <- data[, all.vars(x), drop = FALSE] + output <- x[, all.vars(formula), drop = FALSE] } else { output <- do.call( stats::model.frame, - c(list(formula = x, data = data), dots_quoted), + c(list(formula = formula, data = x), dots_quoted), quote = FALSE ) } @@ -262,3 +245,88 @@ series.formula <- function( output } + +#' @export +series.matrix <- function( + x, + formula, + formula.default, + ... +) { + ## convert to + ## and pass into series + x <- map_dfr(x) + + series( + x = x, + formula = formula, + formula.default = formula.default + ) +} + +#' @export +series.xts <- function( + x, + formula, + formula.default, + ... +) { + ## reclass 'x' so downstream can + ## can handle the output + class(x) <- c( + class(x), + "ta_series" + ) + + ## fast-track to returning values + ## if the 'x' is correctly just one column + if (NCOL(x) == 1L && length(all.vars(formula.default)) == 1L) { + return(x) + } + + ## assert correctness of the passed + ## formulas + if (missing(formula)) { + ## the core assumption is that the default + ## formula never matches the actual names of + ## the passed because it returns as + ## TICKER.Open, TICKER.High, ..., TICKER.Adjusted + ## + ## So the first step is to convert the default formula + ## to to title case + formula.default <- stats::reformulate( + as.title_case( + grep( + pattern = paste(all.vars(formula.default), collapse = "|"), + x = names(x), + value = TRUE, + ignore.case = TRUE + ) + ) + ) + ## if the formula is not passed + ## it should be replaced by the default + formula <- formula.default + } + + ## assert that columns exists + ## and emit message if not + assert_column_names( + formula = formula, + available_variables = names(x) + ) + + ## extract all matching column + ## names + ## + ## NOTE: This step is not necessary if the + ## cols are not passed as its already been + ## identified an asserted + identified_columns <- grep( + pattern = paste(all.vars(formula), collapse = "|"), + x = names(x), + value = TRUE + ) + + return(x[[match(identified_columns, names(x))]]) +} diff --git a/R/utils.R b/R/utils.R index 79dd7a1b4..83594d9df 100644 --- a/R/utils.R +++ b/R/utils.R @@ -382,11 +382,49 @@ set_rownames.matrix <- function(x, x_names) { return(invisible(NULL)) } +#' @export +as.data.frame.ta_object <- function(x, row.names, optional, ...) { + ## extract 'lookback' attribute + lookback_attribute <- attr(x, "lookback", TRUE) + + if (is.matrix(x)) { + if (is.double(x)) { + x <- .Call( + C_map_dfr_double, + x + ) + } + if (is.integer(x)) { + x <- .Call( + C_map_dfr_integer, + x + ) + } + } + + attr(x, "lookback") <- lookback_attribute + + return(x) +} + +#' @export +as.matrix.ta_object <- function(x, ...) { + class(x) <- c("matrix", "array") + + return(x) +} + + ## map to map_dfr <- function(x) { UseMethod("map_dfr") } +#' @export +map_dfr.ta_object <- function(x) { + as.data.frame(x) +} + #' @export map_dfr.double <- function(x) { if (!is.matrix(x)) { @@ -456,3 +494,13 @@ as.maType.double <- function(x, ...) { #' @export as.maType.integer <- as.maType.double + +as.xts <- function(x) { + UseMethod("as.xts") +} + +#' @export +as.xts.ta_object <- function(x) { + class(x) <- c("xts", "zoo") + x +} diff --git a/tests/testthat/test-series.R b/tests/testthat/test-series.R index 37cb1c695..20a401f2b 100644 --- a/tests/testthat/test-series.R +++ b/tests/testthat/test-series.R @@ -1,52 +1,97 @@ +library(talib) ## tests for the formula-based column selector ## series() is internal; we exercise it via the indicator pipeline +testthat::test_that(desc = "Output is ", code = { + ## check + x <- talib:::series( + x = SPY, + formula = ~open, + formula.default = ~open + ) -series <- talib:::series - -testthat::test_that("series() requires data", { - testthat::expect_error( - series(x = ~close, default_formula = ~close), - "data" + testthat::expect_s3_class( + x, + "data.frame" ) -}) -testthat::test_that("series() falls back to default formula when x is missing", { - df <- data.frame(close = 1:5) - out <- series(default_formula = ~close, data = df) + ## check + x <- talib:::series( + x = ATOM, + formula = ~open, + formula.default = ~open + ) - testthat::expect_s3_class(out, "data.frame") - testthat::expect_equal(out$close, 1:5) + testthat::expect_s3_class( + x, + "data.frame" + ) }) -testthat::test_that("series() honours explicit formula over default", { - df <- data.frame(close = 1:5, open = 6:10) - out <- series(x = ~open, default_formula = ~close, data = df) +testthat::test_that(desc = "formula has precedence over formula.default", code = { + ## check ATOM by passing + ## formula explicitly different + ## from the default + x <- talib:::series( + x = ATOM, + formula = ~open, + formula.default = ~close + ) - testthat::expect_equal(names(out)[1L], "open") + ## check that the colnames + ## are are open + testthat::expect_equal( + colnames(x), + "open" + ) + + ## check that there are no + ## implicit renaming + testthat::expect_equal( + x$open, + ATOM$open + ) }) -testthat::test_that("series() rejects shorter formula than default", { - df <- data.frame(close = 1:5, high = 6:10, low = 11:15) +testthat::test_that(desc = "Missing formula does not error", code = { + ## + testthat::expect_no_condition( + talib:::series( + x = ATOM, + formula.default = ~close + ) + ) - ## default expects 3 vars - we pass 1 - testthat::expect_error( - series(x = ~close, default_formula = ~ high + low + close, data = df) + ## + testthat::expect_no_condition( + talib:::series( + x = SPY, + formula.default = ~close + ) ) }) -testthat::test_that("series() errors on unknown column", { - df <- data.frame(close = 1:5) +testthat::test_that(desc = "Attributes are respected", code = { + ## + x <- talib:::series( + x = ATOM, + formula.default = ~ open + high + low + close + volume + ) - testthat::expect_error( - series(x = ~missing_col, default_formula = ~close, data = df) + testthat::expect_equal( + x, + ATOM ) -}) -testthat::test_that("series() coerces non-data.frame to data.frame", { - mat <- matrix(1:10, ncol = 2, dimnames = list(NULL, c("close", "open"))) + ## + x <- talib:::series( + x = SPY, + formula.default = ~ open + high + low + close + volume + ) - testthat::expect_no_error( - out <- series(default_formula = ~close, data = mat) + ## NOTE: x is a + ## but SPY are a matrix + testthat::expect_equal( + as.matrix(x), + SPY ) - testthat::expect_s3_class(out, "data.frame") }) From 6179cba38c87d912c29f777bb8187f337c37dd15 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 09:46:44 +0200 Subject: [PATCH 06/22] :hammer: methods added to templates * methods have been added to all non-rolling indicators (these are considered utility functions) which follows the same underlying logic as the and methods; ie. it dispatches to the default method. - The logic are handled by series() and utils.R via S3 classes * The most "important" change here is that the indicators moves from using rownames to index in the argument naming. This is to introduce some sort of consistency across the methods ( does not have any rownmes). Under the hood and methods still sets the rowname attribute while sets the index attribute of the resulting indicator. --- codegen/templates/candlestick_template.R | 46 ++++++++++++++----- .../templates/chart_candlestick_template.R | 2 +- codegen/templates/chart_main_template.R | 2 +- .../templates/chart_moving_average_template.R | 2 +- codegen/templates/chart_subchart_template.R | 2 +- codegen/templates/indicator_template.R | 41 +++++++++++++---- codegen/templates/moving_average_template.R | 42 +++++++++++++---- 7 files changed, 106 insertions(+), 31 deletions(-) diff --git a/codegen/templates/candlestick_template.R b/codegen/templates/candlestick_template.R index e0733a682..fe8e4832f 100644 --- a/codegen/templates/candlestick_template.R +++ b/codegen/templates/candlestick_template.R @@ -78,32 +78,30 @@ ${FUN}.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ${FORMULA}, - data = x, + x = x, + formula.default = ${FORMULA}, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( + x <- .Call( C_impl_ta_${ALIAS}, ${C_SIGNATURE}, normalize, as.logical(na.bridge) ) - ) ## add column name colnames(x) <- "${ALIAS}" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -120,7 +118,7 @@ ${FUN}.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( ${FUN}.default( x = x, cols = cols, @@ -142,16 +140,42 @@ ${FUN}.matrix <- function( ${ARGS} na.bridge = FALSE, ...) { - - ${FUN}.default( + as.matrix( +${FUN}.default( x = x, cols = cols , ${PARGS} na.bridge = na.bridge, ... ) + ) + } +#' @usage NULL +#' @aliases ${FUN} +#' +#' @export +${FUN}.xts <- function( + x, + cols, + ${ARGS} + na.bridge = FALSE, + ...) { + + as.xts( + ${FUN}.default( + x = x, + cols = cols, + ${PARGS} + na.bridge = na.bridge, + ... + ) + ) + +} + + #' @usage NULL ${ALIAS}_lookback <- ${CAMEL_LOOKBACK}${FUN}_lookback <- function( x, diff --git a/codegen/templates/chart_candlestick_template.R b/codegen/templates/chart_candlestick_template.R index 7d05e32dc..a1160044b 100644 --- a/codegen/templates/chart_candlestick_template.R +++ b/codegen/templates/chart_candlestick_template.R @@ -26,7 +26,7 @@ ${FUN}.${METHOD} <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ${FORMULA}, + formula.default = ${FORMULA}, ... ) diff --git a/codegen/templates/chart_main_template.R b/codegen/templates/chart_main_template.R index 3d1eda9b1..34752042a 100644 --- a/codegen/templates/chart_main_template.R +++ b/codegen/templates/chart_main_template.R @@ -28,7 +28,7 @@ ${FUN}.${METHOD} <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ${FORMULA}, + formula.default = ${FORMULA}, ... ) diff --git a/codegen/templates/chart_moving_average_template.R b/codegen/templates/chart_moving_average_template.R index 977f9de4d..b01315a24 100644 --- a/codegen/templates/chart_moving_average_template.R +++ b/codegen/templates/chart_moving_average_template.R @@ -26,7 +26,7 @@ ${FUN}.${METHOD} <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ${FORMULA}, + formula.default = ${FORMULA}, ... ) diff --git a/codegen/templates/chart_subchart_template.R b/codegen/templates/chart_subchart_template.R index 1a43471e4..624f6587c 100644 --- a/codegen/templates/chart_subchart_template.R +++ b/codegen/templates/chart_subchart_template.R @@ -32,7 +32,7 @@ ${FUN}.${METHOD} <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ${FORMULA}, + formula.default = ${FORMULA}, ... ) diff --git a/codegen/templates/indicator_template.R b/codegen/templates/indicator_template.R index f0b947dc9..016244674 100644 --- a/codegen/templates/indicator_template.R +++ b/codegen/templates/indicator_template.R @@ -57,15 +57,15 @@ ${FUN}.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ${FORMULA}, - data = x, + x = x, + formula = cols, + formula.default = ${FORMULA}, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -76,7 +76,7 @@ ${FUN}.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -93,7 +93,7 @@ ${FUN}.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( ${FUN}.default( x = x, cols = cols, @@ -115,14 +115,39 @@ ${FUN}.matrix <- function( ${ARGS} na.bridge = FALSE, ...) { - - ${FUN}.default( + as.matrix( +${FUN}.default( x = x, cols = cols , ${PARGS} na.bridge = na.bridge, ... ) + ) + +} + +#' @usage NULL +#' @aliases ${FUN} +#' +#' @export +${FUN}.xts <- function( + x, + cols, + ${ARGS} + na.bridge = FALSE, + ...) { + + as.xts( + ${FUN}.default( + x = x, + cols = cols, + ${PARGS} + na.bridge = na.bridge, + ... + ) + ) + } #' @usage NULL diff --git a/codegen/templates/moving_average_template.R b/codegen/templates/moving_average_template.R index 19b9561f8..bce1d569d 100644 --- a/codegen/templates/moving_average_template.R +++ b/codegen/templates/moving_average_template.R @@ -80,15 +80,15 @@ ${FUN}.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ${FORMULA}, - data = x, + x = x, + formula.default = ${FORMULA}, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -99,7 +99,7 @@ ${FUN}.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -116,7 +116,7 @@ ${FUN}.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( ${FUN}.default( x = x, cols = cols, @@ -138,16 +138,42 @@ ${FUN}.matrix <- function( ${ARGS} na.bridge = FALSE, ...) { - - ${FUN}.default( +as.matrix( +${FUN}.default( x = x, cols = cols , ${PARGS} na.bridge = na.bridge, ... ) +) + } +#' @usage NULL +#' @aliases ${FUN} +#' +#' @export +${FUN}.xts <- function( + x, + cols, + ${ARGS} + na.bridge = FALSE, + ...) { + + as.xts( + ${FUN}.default( + x = x, + cols = cols, + ${PARGS} + na.bridge = na.bridge, + ... + ) + ) + +} + + #' @usage NULL #' @aliases ${FUN} #' From d8ee71dda24b2a31753b26b16f92a8684b17c7b4 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 09:52:30 +0200 Subject: [PATCH 07/22] :hammer: Regenerated code --- R/ta_ACCBANDS.R | 52 ++++++++++++++++++------- R/ta_AD.R | 48 ++++++++++++++++------- R/ta_ADOSC.R | 56 +++++++++++++++++++------- R/ta_ADX.R | 52 ++++++++++++++++++------- R/ta_ADXR.R | 52 ++++++++++++++++++------- R/ta_APO.R | 60 ++++++++++++++++++++-------- R/ta_AROON.R | 52 ++++++++++++++++++------- R/ta_AROONOSC.R | 52 ++++++++++++++++++------- R/ta_ATR.R | 52 ++++++++++++++++++------- R/ta_AVGDEV.R | 48 +++++++++++++++++------ R/ta_AVGPRICE.R | 44 +++++++++++++++------ R/ta_BBANDS.R | 64 ++++++++++++++++++++++-------- R/ta_BOP.R | 48 ++++++++++++++++------- R/ta_CCI.R | 52 ++++++++++++++++++------- R/ta_CDL2CROWS.R | 67 ++++++++++++++++++++----------- R/ta_CDL3BLACKCROWS.R | 67 ++++++++++++++++++++----------- R/ta_CDL3INSIDE.R | 67 ++++++++++++++++++++----------- R/ta_CDL3LINESTRIKE.R | 67 ++++++++++++++++++++----------- R/ta_CDL3OUTSIDE.R | 67 ++++++++++++++++++++----------- R/ta_CDL3STARSINSOUTH.R | 67 ++++++++++++++++++++----------- R/ta_CDL3WHITESOLDIERS.R | 67 ++++++++++++++++++++----------- R/ta_CDLABANDONEDBABY.R | 73 ++++++++++++++++++++++------------ R/ta_CDLADVANCEBLOCK.R | 67 ++++++++++++++++++++----------- R/ta_CDLBELTHOLD.R | 67 ++++++++++++++++++++----------- R/ta_CDLBREAKAWAY.R | 67 ++++++++++++++++++++----------- R/ta_CDLCLOSINGMARUBOZU.R | 67 ++++++++++++++++++++----------- R/ta_CDLCONCEALBABYSWALL.R | 67 ++++++++++++++++++++----------- R/ta_CDLCOUNTERATTACK.R | 67 ++++++++++++++++++++----------- R/ta_CDLDARKCLOUDCOVER.R | 73 ++++++++++++++++++++++------------ R/ta_CDLDOJI.R | 67 ++++++++++++++++++++----------- R/ta_CDLDOJISTAR.R | 67 ++++++++++++++++++++----------- R/ta_CDLDRAGONFLYDOJI.R | 67 ++++++++++++++++++++----------- R/ta_CDLENGULFING.R | 67 ++++++++++++++++++++----------- R/ta_CDLEVENINGDOJISTAR.R | 73 ++++++++++++++++++++++------------ R/ta_CDLEVENINGSTAR.R | 73 ++++++++++++++++++++++------------ R/ta_CDLGAPSIDESIDEWHITE.R | 67 ++++++++++++++++++++----------- R/ta_CDLGRAVESTONEDOJI.R | 67 ++++++++++++++++++++----------- R/ta_CDLHAMMER.R | 67 ++++++++++++++++++++----------- R/ta_CDLHANGINGMAN.R | 67 ++++++++++++++++++++----------- R/ta_CDLHARAMI.R | 67 ++++++++++++++++++++----------- R/ta_CDLHARAMICROSS.R | 67 ++++++++++++++++++++----------- R/ta_CDLHIGHWAVE.R | 67 ++++++++++++++++++++----------- R/ta_CDLHIKKAKE.R | 67 ++++++++++++++++++++----------- R/ta_CDLHIKKAKEMOD.R | 67 ++++++++++++++++++++----------- R/ta_CDLHOMINGPIGEON.R | 67 ++++++++++++++++++++----------- R/ta_CDLIDENTICAL3CROWS.R | 67 ++++++++++++++++++++----------- R/ta_CDLINNECK.R | 67 ++++++++++++++++++++----------- R/ta_CDLINVERTEDHAMMER.R | 67 ++++++++++++++++++++----------- R/ta_CDLKICKING.R | 67 ++++++++++++++++++++----------- R/ta_CDLKICKINGBYLENGTH.R | 67 ++++++++++++++++++++----------- R/ta_CDLLADDERBOTTOM.R | 67 ++++++++++++++++++++----------- R/ta_CDLLONGLEGGEDDOJI.R | 67 ++++++++++++++++++++----------- R/ta_CDLLONGLINE.R | 67 ++++++++++++++++++++----------- R/ta_CDLMARUBOZU.R | 67 ++++++++++++++++++++----------- R/ta_CDLMATCHINGLOW.R | 67 ++++++++++++++++++++----------- R/ta_CDLMATHOLD.R | 73 ++++++++++++++++++++++------------ R/ta_CDLMORNINGDOJISTAR.R | 73 ++++++++++++++++++++++------------ R/ta_CDLMORNINGSTAR.R | 73 ++++++++++++++++++++++------------ R/ta_CDLONNECK.R | 67 ++++++++++++++++++++----------- R/ta_CDLPIERCING.R | 67 ++++++++++++++++++++----------- R/ta_CDLRICKSHAWMAN.R | 67 ++++++++++++++++++++----------- R/ta_CDLRISEFALL3METHODS.R | 67 ++++++++++++++++++++----------- R/ta_CDLSEPARATINGLINES.R | 67 ++++++++++++++++++++----------- R/ta_CDLSHOOTINGSTAR.R | 67 ++++++++++++++++++++----------- R/ta_CDLSHORTLINE.R | 67 ++++++++++++++++++++----------- R/ta_CDLSPINNINGTOP.R | 67 ++++++++++++++++++++----------- R/ta_CDLSTALLEDPATTERN.R | 67 ++++++++++++++++++++----------- R/ta_CDLSTICKSANDWICH.R | 67 ++++++++++++++++++++----------- R/ta_CDLTAKURI.R | 67 ++++++++++++++++++++----------- R/ta_CDLTASUKIGAP.R | 67 ++++++++++++++++++++----------- R/ta_CDLTHRUSTING.R | 67 ++++++++++++++++++++----------- R/ta_CDLTRISTAR.R | 67 ++++++++++++++++++++----------- R/ta_CDLUNIQUE3RIVER.R | 67 ++++++++++++++++++++----------- R/ta_CDLUPSIDEGAP2CROWS.R | 67 ++++++++++++++++++++----------- R/ta_CDLXSIDEGAP3METHODS.R | 67 ++++++++++++++++++++----------- R/ta_CMO.R | 52 ++++++++++++++++++------- R/ta_DEMA.R | 53 ++++++++++++++++++------- R/ta_DX.R | 52 ++++++++++++++++++------- R/ta_EMA.R | 53 ++++++++++++++++++------- R/ta_HT_DCPERIOD.R | 48 ++++++++++++++++------- R/ta_HT_DCPHASE.R | 48 ++++++++++++++++------- R/ta_HT_PHASOR.R | 48 ++++++++++++++++------- R/ta_HT_SINE.R | 48 ++++++++++++++++------- R/ta_HT_TRENDLINE.R | 48 ++++++++++++++++------- R/ta_HT_TRENDMODE.R | 48 ++++++++++++++++------- R/ta_IMI.R | 52 ++++++++++++++++++------- R/ta_KAMA.R | 53 ++++++++++++++++++------- R/ta_MACD.R | 60 ++++++++++++++++++++-------- R/ta_MACDEXT.R | 72 +++++++++++++++++++++++++--------- R/ta_MACDFIX.R | 52 ++++++++++++++++++------- R/ta_MAMA.R | 61 +++++++++++++++++++++-------- R/ta_MAVP.R | 64 ++++++++++++++++++++++-------- R/ta_MEDPRICE.R | 44 +++++++++++++++------ R/ta_MFI.R | 52 ++++++++++++++++++------- R/ta_MIDPOINT.R | 52 ++++++++++++++++++------- R/ta_MIDPRICE.R | 52 ++++++++++++++++++------- R/ta_MINUS_DI.R | 52 ++++++++++++++++++------- R/ta_MINUS_DM.R | 52 ++++++++++++++++++------- R/ta_MOM.R | 52 ++++++++++++++++++------- R/ta_NATR.R | 52 ++++++++++++++++++------- R/ta_OBV.R | 48 ++++++++++++++++------- R/ta_PLUS_DI.R | 52 ++++++++++++++++++------- R/ta_PLUS_DM.R | 52 ++++++++++++++++++------- R/ta_PPO.R | 60 ++++++++++++++++++++-------- R/ta_ROCR.R | 52 ++++++++++++++++++------- R/ta_RSI.R | 52 ++++++++++++++++++------- R/ta_SAR.R | 56 +++++++++++++++++++------- R/ta_SAREXT.R | 80 ++++++++++++++++++++++++++++---------- R/ta_SMA.R | 53 ++++++++++++++++++------- R/ta_STOCH.R | 68 +++++++++++++++++++++++--------- R/ta_STOCHF.R | 60 ++++++++++++++++++++-------- R/ta_STOCHRSI.R | 64 ++++++++++++++++++++++-------- R/ta_T3.R | 57 ++++++++++++++++++++------- R/ta_TEMA.R | 53 ++++++++++++++++++------- R/ta_TRANGE.R | 48 ++++++++++++++++------- R/ta_TRIMA.R | 53 ++++++++++++++++++------- R/ta_TRIX.R | 52 ++++++++++++++++++------- R/ta_TYPPRICE.R | 44 +++++++++++++++------ R/ta_ULTOSC.R | 60 ++++++++++++++++++++-------- R/ta_VOLUME.R | 10 ++--- R/ta_WCLPRICE.R | 44 +++++++++++++++------ R/ta_WILLR.R | 52 ++++++++++++++++++------- R/ta_WMA.R | 53 ++++++++++++++++++------- 123 files changed, 5112 insertions(+), 2292 deletions(-) diff --git a/R/ta_ACCBANDS.R b/R/ta_ACCBANDS.R index 8ed41cb75..df45a2430 100644 --- a/R/ta_ACCBANDS.R +++ b/R/ta_ACCBANDS.R @@ -58,15 +58,15 @@ acceleration_bands.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -80,7 +80,7 @@ acceleration_bands.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -97,7 +97,7 @@ acceleration_bands.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( acceleration_bands.default( x = x, cols = cols, @@ -119,12 +119,36 @@ acceleration_bands.matrix <- function( na.bridge = FALSE, ... ) { - acceleration_bands.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + acceleration_bands.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases acceleration_bands +#' +#' @export +acceleration_bands.xts <- function( + x, + cols, + timePeriod = 20, + na.bridge = FALSE, + ... +) { + as.xts( + acceleration_bands.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -172,7 +196,7 @@ acceleration_bands.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) @@ -274,7 +298,7 @@ acceleration_bands.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) diff --git a/R/ta_AD.R b/R/ta_AD.R index df8a4f373..4f5336024 100644 --- a/R/ta_AD.R +++ b/R/ta_AD.R @@ -56,15 +56,15 @@ chaikin_accumulation_distribution_line.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close + volume, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close + volume, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -78,7 +78,7 @@ chaikin_accumulation_distribution_line.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -94,7 +94,7 @@ chaikin_accumulation_distribution_line.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( chaikin_accumulation_distribution_line.default( x = x, cols = cols, @@ -114,11 +114,33 @@ chaikin_accumulation_distribution_line.matrix <- function( na.bridge = FALSE, ... ) { - chaikin_accumulation_distribution_line.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + chaikin_accumulation_distribution_line.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases chaikin_accumulation_distribution_line +#' +#' @export +chaikin_accumulation_distribution_line.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + chaikin_accumulation_distribution_line.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } @@ -162,7 +184,7 @@ chaikin_accumulation_distribution_line.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close + volume, + formula.default = ~ high + low + close + volume, ... ) @@ -253,7 +275,7 @@ chaikin_accumulation_distribution_line.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close + volume, + formula.default = ~ high + low + close + volume, ... ) diff --git a/R/ta_ADOSC.R b/R/ta_ADOSC.R index ab96fde67..571f75880 100644 --- a/R/ta_ADOSC.R +++ b/R/ta_ADOSC.R @@ -61,15 +61,15 @@ chaikin_accumulation_distribution_oscillator.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close + volume, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close + volume, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -85,7 +85,7 @@ chaikin_accumulation_distribution_oscillator.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -103,7 +103,7 @@ chaikin_accumulation_distribution_oscillator.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( chaikin_accumulation_distribution_oscillator.default( x = x, cols = cols, @@ -127,13 +127,39 @@ chaikin_accumulation_distribution_oscillator.matrix <- function( na.bridge = FALSE, ... ) { - chaikin_accumulation_distribution_oscillator.default( - x = x, - cols = cols, - fastPeriod = fastPeriod, - slowPeriod = slowPeriod, - na.bridge = na.bridge, - ... + as.matrix( + chaikin_accumulation_distribution_oscillator.default( + x = x, + cols = cols, + fastPeriod = fastPeriod, + slowPeriod = slowPeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases chaikin_accumulation_distribution_oscillator +#' +#' @export +chaikin_accumulation_distribution_oscillator.xts <- function( + x, + cols, + fastPeriod = 3, + slowPeriod = 10, + na.bridge = FALSE, + ... +) { + as.xts( + chaikin_accumulation_distribution_oscillator.default( + x = x, + cols = cols, + fastPeriod = fastPeriod, + slowPeriod = slowPeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -183,7 +209,7 @@ chaikin_accumulation_distribution_oscillator.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close + volume, + formula.default = ~ high + low + close + volume, ... ) @@ -278,7 +304,7 @@ chaikin_accumulation_distribution_oscillator.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close + volume, + formula.default = ~ high + low + close + volume, ... ) diff --git a/R/ta_ADX.R b/R/ta_ADX.R index 83af497dc..a1218a659 100644 --- a/R/ta_ADX.R +++ b/R/ta_ADX.R @@ -58,15 +58,15 @@ average_directional_movement_index.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -80,7 +80,7 @@ average_directional_movement_index.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -97,7 +97,7 @@ average_directional_movement_index.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( average_directional_movement_index.default( x = x, cols = cols, @@ -119,12 +119,36 @@ average_directional_movement_index.matrix <- function( na.bridge = FALSE, ... ) { - average_directional_movement_index.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + average_directional_movement_index.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases average_directional_movement_index +#' +#' @export +average_directional_movement_index.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + average_directional_movement_index.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -174,7 +198,7 @@ average_directional_movement_index.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) @@ -277,7 +301,7 @@ average_directional_movement_index.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) diff --git a/R/ta_ADXR.R b/R/ta_ADXR.R index df7790c60..76f39d637 100644 --- a/R/ta_ADXR.R +++ b/R/ta_ADXR.R @@ -58,15 +58,15 @@ average_directional_movement_index_rating.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -80,7 +80,7 @@ average_directional_movement_index_rating.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -97,7 +97,7 @@ average_directional_movement_index_rating.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( average_directional_movement_index_rating.default( x = x, cols = cols, @@ -119,12 +119,36 @@ average_directional_movement_index_rating.matrix <- function( na.bridge = FALSE, ... ) { - average_directional_movement_index_rating.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + average_directional_movement_index_rating.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases average_directional_movement_index_rating +#' +#' @export +average_directional_movement_index_rating.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + average_directional_movement_index_rating.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -174,7 +198,7 @@ average_directional_movement_index_rating.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) @@ -277,7 +301,7 @@ average_directional_movement_index_rating.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) diff --git a/R/ta_APO.R b/R/ta_APO.R index bbb865b61..1ab78d545 100644 --- a/R/ta_APO.R +++ b/R/ta_APO.R @@ -64,15 +64,15 @@ absolute_price_oscillator.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -86,7 +86,7 @@ absolute_price_oscillator.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -105,7 +105,7 @@ absolute_price_oscillator.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( absolute_price_oscillator.default( x = x, cols = cols, @@ -131,14 +131,42 @@ absolute_price_oscillator.matrix <- function( na.bridge = FALSE, ... ) { - absolute_price_oscillator.default( - x = x, - cols = cols, - fastPeriod = fastPeriod, - slowPeriod = slowPeriod, - maType = maType, - na.bridge = na.bridge, - ... + as.matrix( + absolute_price_oscillator.default( + x = x, + cols = cols, + fastPeriod = fastPeriod, + slowPeriod = slowPeriod, + maType = maType, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases absolute_price_oscillator +#' +#' @export +absolute_price_oscillator.xts <- function( + x, + cols, + fastPeriod = 12, + slowPeriod = 26, + maType = 1, + na.bridge = FALSE, + ... +) { + as.xts( + absolute_price_oscillator.default( + x = x, + cols = cols, + fastPeriod = fastPeriod, + slowPeriod = slowPeriod, + maType = maType, + na.bridge = na.bridge, + ... + ) ) } @@ -230,7 +258,7 @@ absolute_price_oscillator.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -334,7 +362,7 @@ absolute_price_oscillator.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_AROON.R b/R/ta_AROON.R index e9cbb8da1..52da7c9d2 100644 --- a/R/ta_AROON.R +++ b/R/ta_AROON.R @@ -51,15 +51,15 @@ aroon.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -72,7 +72,7 @@ aroon.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -89,7 +89,7 @@ aroon.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( aroon.default( x = x, cols = cols, @@ -111,12 +111,36 @@ aroon.matrix <- function( na.bridge = FALSE, ... ) { - aroon.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + aroon.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases aroon +#' +#' @export +aroon.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + aroon.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -163,7 +187,7 @@ aroon.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low, + formula.default = ~ high + low, ... ) @@ -275,7 +299,7 @@ aroon.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low, + formula.default = ~ high + low, ... ) diff --git a/R/ta_AROONOSC.R b/R/ta_AROONOSC.R index e1c68b01a..f949315fb 100644 --- a/R/ta_AROONOSC.R +++ b/R/ta_AROONOSC.R @@ -58,15 +58,15 @@ aroon_oscillator.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -79,7 +79,7 @@ aroon_oscillator.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -96,7 +96,7 @@ aroon_oscillator.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( aroon_oscillator.default( x = x, cols = cols, @@ -118,12 +118,36 @@ aroon_oscillator.matrix <- function( na.bridge = FALSE, ... ) { - aroon_oscillator.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + aroon_oscillator.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases aroon_oscillator +#' +#' @export +aroon_oscillator.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + aroon_oscillator.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -170,7 +194,7 @@ aroon_oscillator.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low, + formula.default = ~ high + low, ... ) @@ -268,7 +292,7 @@ aroon_oscillator.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low, + formula.default = ~ high + low, ... ) diff --git a/R/ta_ATR.R b/R/ta_ATR.R index f0566f42e..de8dfe295 100644 --- a/R/ta_ATR.R +++ b/R/ta_ATR.R @@ -58,15 +58,15 @@ average_true_range.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -80,7 +80,7 @@ average_true_range.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -97,7 +97,7 @@ average_true_range.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( average_true_range.default( x = x, cols = cols, @@ -119,12 +119,36 @@ average_true_range.matrix <- function( na.bridge = FALSE, ... ) { - average_true_range.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + average_true_range.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases average_true_range +#' +#' @export +average_true_range.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + average_true_range.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -171,7 +195,7 @@ average_true_range.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) @@ -264,7 +288,7 @@ average_true_range.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) diff --git a/R/ta_AVGDEV.R b/R/ta_AVGDEV.R index eefd4249a..0da081c91 100644 --- a/R/ta_AVGDEV.R +++ b/R/ta_AVGDEV.R @@ -58,15 +58,15 @@ average_deviation.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -78,7 +78,7 @@ average_deviation.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -95,7 +95,7 @@ average_deviation.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( average_deviation.default( x = x, cols = cols, @@ -117,12 +117,36 @@ average_deviation.matrix <- function( na.bridge = FALSE, ... ) { - average_deviation.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + average_deviation.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases average_deviation +#' +#' @export +average_deviation.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + average_deviation.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } diff --git a/R/ta_AVGPRICE.R b/R/ta_AVGPRICE.R index 17162dc7a..990f8c7f7 100644 --- a/R/ta_AVGPRICE.R +++ b/R/ta_AVGPRICE.R @@ -56,15 +56,15 @@ average_price.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ open + high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -78,7 +78,7 @@ average_price.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -94,7 +94,7 @@ average_price.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( average_price.default( x = x, cols = cols, @@ -114,11 +114,33 @@ average_price.matrix <- function( na.bridge = FALSE, ... ) { - average_price.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + average_price.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases average_price +#' +#' @export +average_price.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + average_price.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } diff --git a/R/ta_BBANDS.R b/R/ta_BBANDS.R index f74fc476f..a65c36b5f 100644 --- a/R/ta_BBANDS.R +++ b/R/ta_BBANDS.R @@ -66,15 +66,15 @@ bollinger_bands.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -89,7 +89,7 @@ bollinger_bands.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -109,7 +109,7 @@ bollinger_bands.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( bollinger_bands.default( x = x, cols = cols, @@ -137,15 +137,45 @@ bollinger_bands.matrix <- function( na.bridge = FALSE, ... ) { - bollinger_bands.default( - x = x, - cols = cols, - timePeriod = timePeriod, - deviationsUp = deviationsUp, - deviationsDown = deviationsDown, - maType = maType, - na.bridge = na.bridge, - ... + as.matrix( + bollinger_bands.default( + x = x, + cols = cols, + timePeriod = timePeriod, + deviationsUp = deviationsUp, + deviationsDown = deviationsDown, + maType = maType, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases bollinger_bands +#' +#' @export +bollinger_bands.xts <- function( + x, + cols, + timePeriod = 20, + deviationsUp = 2, + deviationsDown = 2, + maType = 0, + na.bridge = FALSE, + ... +) { + as.xts( + bollinger_bands.default( + x = x, + cols = cols, + timePeriod = timePeriod, + deviationsUp = deviationsUp, + deviationsDown = deviationsDown, + maType = maType, + na.bridge = na.bridge, + ... + ) ) } @@ -243,7 +273,7 @@ bollinger_bands.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -375,7 +405,7 @@ bollinger_bands.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_BOP.R b/R/ta_BOP.R index 01a6ff1fc..003ea17fc 100644 --- a/R/ta_BOP.R +++ b/R/ta_BOP.R @@ -56,15 +56,15 @@ balance_of_power.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ open + high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -78,7 +78,7 @@ balance_of_power.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -94,7 +94,7 @@ balance_of_power.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( balance_of_power.default( x = x, cols = cols, @@ -114,11 +114,33 @@ balance_of_power.matrix <- function( na.bridge = FALSE, ... ) { - balance_of_power.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + balance_of_power.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases balance_of_power +#' +#' @export +balance_of_power.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + balance_of_power.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } @@ -162,7 +184,7 @@ balance_of_power.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -264,7 +286,7 @@ balance_of_power.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CCI.R b/R/ta_CCI.R index 1119c1a35..f7a0cd886 100644 --- a/R/ta_CCI.R +++ b/R/ta_CCI.R @@ -58,15 +58,15 @@ commodity_channel_index.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -80,7 +80,7 @@ commodity_channel_index.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -97,7 +97,7 @@ commodity_channel_index.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( commodity_channel_index.default( x = x, cols = cols, @@ -119,12 +119,36 @@ commodity_channel_index.matrix <- function( na.bridge = FALSE, ... ) { - commodity_channel_index.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + commodity_channel_index.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases commodity_channel_index +#' +#' @export +commodity_channel_index.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + commodity_channel_index.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -173,7 +197,7 @@ commodity_channel_index.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) @@ -270,7 +294,7 @@ commodity_channel_index.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) diff --git a/R/ta_CDL2CROWS.R b/R/ta_CDL2CROWS.R index 3615e4201..b93871907 100644 --- a/R/ta_CDL2CROWS.R +++ b/R/ta_CDL2CROWS.R @@ -77,35 +77,33 @@ two_crows.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDL2CROWS, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDL2CROWS, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDL2CROWS" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ two_crows.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( two_crows.default( x = x, cols = cols, @@ -141,14 +139,37 @@ two_crows.matrix <- function( na.bridge = FALSE, ... ) { - two_crows.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + two_crows.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases two_crows +#' +#' @export +two_crows.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + two_crows.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDL2CROWS_lookback <- twoCrows_lookback <- two_crows_lookback <- function( x, @@ -186,7 +207,7 @@ two_crows.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ two_crows.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDL3BLACKCROWS.R b/R/ta_CDL3BLACKCROWS.R index d0c73ace4..c7a8ab32b 100644 --- a/R/ta_CDL3BLACKCROWS.R +++ b/R/ta_CDL3BLACKCROWS.R @@ -77,35 +77,33 @@ three_black_crows.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDL3BLACKCROWS, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDL3BLACKCROWS, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDL3BLACKCROWS" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ three_black_crows.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( three_black_crows.default( x = x, cols = cols, @@ -141,14 +139,37 @@ three_black_crows.matrix <- function( na.bridge = FALSE, ... ) { - three_black_crows.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + three_black_crows.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases three_black_crows +#' +#' @export +three_black_crows.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + three_black_crows.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDL3BLACKCROWS_lookback <- threeBlackCrows_lookback <- three_black_crows_lookback <- function( x, @@ -186,7 +207,7 @@ three_black_crows.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ three_black_crows.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDL3INSIDE.R b/R/ta_CDL3INSIDE.R index da82524b7..8a45348d4 100644 --- a/R/ta_CDL3INSIDE.R +++ b/R/ta_CDL3INSIDE.R @@ -77,35 +77,33 @@ three_inside.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDL3INSIDE, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDL3INSIDE, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDL3INSIDE" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ three_inside.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( three_inside.default( x = x, cols = cols, @@ -141,14 +139,37 @@ three_inside.matrix <- function( na.bridge = FALSE, ... ) { - three_inside.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + three_inside.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases three_inside +#' +#' @export +three_inside.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + three_inside.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDL3INSIDE_lookback <- threeInside_lookback <- three_inside_lookback <- function( x, @@ -186,7 +207,7 @@ three_inside.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ three_inside.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDL3LINESTRIKE.R b/R/ta_CDL3LINESTRIKE.R index e590b4dfd..7c829bc7b 100644 --- a/R/ta_CDL3LINESTRIKE.R +++ b/R/ta_CDL3LINESTRIKE.R @@ -77,35 +77,33 @@ three_line_strike.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDL3LINESTRIKE, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDL3LINESTRIKE, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDL3LINESTRIKE" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ three_line_strike.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( three_line_strike.default( x = x, cols = cols, @@ -141,14 +139,37 @@ three_line_strike.matrix <- function( na.bridge = FALSE, ... ) { - three_line_strike.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + three_line_strike.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases three_line_strike +#' +#' @export +three_line_strike.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + three_line_strike.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDL3LINESTRIKE_lookback <- threeLineStrike_lookback <- three_line_strike_lookback <- function( x, @@ -186,7 +207,7 @@ three_line_strike.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ three_line_strike.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDL3OUTSIDE.R b/R/ta_CDL3OUTSIDE.R index fc629a2a9..fe631607b 100644 --- a/R/ta_CDL3OUTSIDE.R +++ b/R/ta_CDL3OUTSIDE.R @@ -77,35 +77,33 @@ three_outside.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDL3OUTSIDE, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDL3OUTSIDE, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDL3OUTSIDE" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ three_outside.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( three_outside.default( x = x, cols = cols, @@ -141,14 +139,37 @@ three_outside.matrix <- function( na.bridge = FALSE, ... ) { - three_outside.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + three_outside.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases three_outside +#' +#' @export +three_outside.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + three_outside.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDL3OUTSIDE_lookback <- threeOutside_lookback <- three_outside_lookback <- function( x, @@ -186,7 +207,7 @@ three_outside.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ three_outside.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDL3STARSINSOUTH.R b/R/ta_CDL3STARSINSOUTH.R index 723b918e5..5f112cb3d 100644 --- a/R/ta_CDL3STARSINSOUTH.R +++ b/R/ta_CDL3STARSINSOUTH.R @@ -77,35 +77,33 @@ three_stars_in_the_south.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDL3STARSINSOUTH, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDL3STARSINSOUTH, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDL3STARSINSOUTH" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ three_stars_in_the_south.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( three_stars_in_the_south.default( x = x, cols = cols, @@ -141,14 +139,37 @@ three_stars_in_the_south.matrix <- function( na.bridge = FALSE, ... ) { - three_stars_in_the_south.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + three_stars_in_the_south.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases three_stars_in_the_south +#' +#' @export +three_stars_in_the_south.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + three_stars_in_the_south.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDL3STARSINSOUTH_lookback <- threeStarsInTheSouth_lookback <- three_stars_in_the_south_lookback <- function( x, @@ -186,7 +207,7 @@ three_stars_in_the_south.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ three_stars_in_the_south.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDL3WHITESOLDIERS.R b/R/ta_CDL3WHITESOLDIERS.R index 9e30ca422..afb361db8 100644 --- a/R/ta_CDL3WHITESOLDIERS.R +++ b/R/ta_CDL3WHITESOLDIERS.R @@ -77,35 +77,33 @@ three_white_soldiers.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDL3WHITESOLDIERS, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDL3WHITESOLDIERS, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDL3WHITESOLDIERS" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ three_white_soldiers.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( three_white_soldiers.default( x = x, cols = cols, @@ -141,14 +139,37 @@ three_white_soldiers.matrix <- function( na.bridge = FALSE, ... ) { - three_white_soldiers.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + three_white_soldiers.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases three_white_soldiers +#' +#' @export +three_white_soldiers.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + three_white_soldiers.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDL3WHITESOLDIERS_lookback <- threeWhiteSoldiers_lookback <- three_white_soldiers_lookback <- function( x, @@ -186,7 +207,7 @@ three_white_soldiers.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ three_white_soldiers.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLABANDONEDBABY.R b/R/ta_CDLABANDONEDBABY.R index 387eae1c4..3ee8b4fab 100644 --- a/R/ta_CDLABANDONEDBABY.R +++ b/R/ta_CDLABANDONEDBABY.R @@ -79,36 +79,34 @@ abandoned_baby.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLABANDONEDBABY, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - as.double(penetration), - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLABANDONEDBABY, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + as.double(penetration), + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLABANDONEDBABY" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -125,7 +123,7 @@ abandoned_baby.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( abandoned_baby.default( x = x, cols = cols, @@ -147,15 +145,40 @@ abandoned_baby.matrix <- function( na.bridge = FALSE, ... ) { - abandoned_baby.default( - x = x, - cols = cols, - penetration = penetration, - na.bridge = na.bridge, - ... + as.matrix( + abandoned_baby.default( + x = x, + cols = cols, + penetration = penetration, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases abandoned_baby +#' +#' @export +abandoned_baby.xts <- function( + x, + cols, + penetration = 0.3, + na.bridge = FALSE, + ... +) { + as.xts( + abandoned_baby.default( + x = x, + cols = cols, + penetration = penetration, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLABANDONEDBABY_lookback <- abandonedBaby_lookback <- abandoned_baby_lookback <- function( x, @@ -196,7 +219,7 @@ abandoned_baby.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -256,7 +279,7 @@ abandoned_baby.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLADVANCEBLOCK.R b/R/ta_CDLADVANCEBLOCK.R index 7930fd926..c30ac27a3 100644 --- a/R/ta_CDLADVANCEBLOCK.R +++ b/R/ta_CDLADVANCEBLOCK.R @@ -77,35 +77,33 @@ advance_block.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLADVANCEBLOCK, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLADVANCEBLOCK, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLADVANCEBLOCK" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ advance_block.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( advance_block.default( x = x, cols = cols, @@ -141,14 +139,37 @@ advance_block.matrix <- function( na.bridge = FALSE, ... ) { - advance_block.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + advance_block.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases advance_block +#' +#' @export +advance_block.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + advance_block.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLADVANCEBLOCK_lookback <- advanceBlock_lookback <- advance_block_lookback <- function( x, @@ -186,7 +207,7 @@ advance_block.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ advance_block.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLBELTHOLD.R b/R/ta_CDLBELTHOLD.R index 774588470..ecfa9bd92 100644 --- a/R/ta_CDLBELTHOLD.R +++ b/R/ta_CDLBELTHOLD.R @@ -77,35 +77,33 @@ belt_hold.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLBELTHOLD, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLBELTHOLD, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLBELTHOLD" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ belt_hold.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( belt_hold.default( x = x, cols = cols, @@ -141,14 +139,37 @@ belt_hold.matrix <- function( na.bridge = FALSE, ... ) { - belt_hold.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + belt_hold.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases belt_hold +#' +#' @export +belt_hold.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + belt_hold.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLBELTHOLD_lookback <- beltHold_lookback <- belt_hold_lookback <- function( x, @@ -186,7 +207,7 @@ belt_hold.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ belt_hold.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLBREAKAWAY.R b/R/ta_CDLBREAKAWAY.R index 3c2bc9b19..f4fe5c822 100644 --- a/R/ta_CDLBREAKAWAY.R +++ b/R/ta_CDLBREAKAWAY.R @@ -77,35 +77,33 @@ break_away.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLBREAKAWAY, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLBREAKAWAY, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLBREAKAWAY" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ break_away.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( break_away.default( x = x, cols = cols, @@ -141,14 +139,37 @@ break_away.matrix <- function( na.bridge = FALSE, ... ) { - break_away.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + break_away.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases break_away +#' +#' @export +break_away.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + break_away.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLBREAKAWAY_lookback <- breakAway_lookback <- break_away_lookback <- function( x, @@ -186,7 +207,7 @@ break_away.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ break_away.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLCLOSINGMARUBOZU.R b/R/ta_CDLCLOSINGMARUBOZU.R index af68e5998..e7e6b0662 100644 --- a/R/ta_CDLCLOSINGMARUBOZU.R +++ b/R/ta_CDLCLOSINGMARUBOZU.R @@ -77,35 +77,33 @@ closing_marubozu.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLCLOSINGMARUBOZU, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLCLOSINGMARUBOZU, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLCLOSINGMARUBOZU" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ closing_marubozu.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( closing_marubozu.default( x = x, cols = cols, @@ -141,14 +139,37 @@ closing_marubozu.matrix <- function( na.bridge = FALSE, ... ) { - closing_marubozu.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + closing_marubozu.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases closing_marubozu +#' +#' @export +closing_marubozu.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + closing_marubozu.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLCLOSINGMARUBOZU_lookback <- closingMarubozu_lookback <- closing_marubozu_lookback <- function( x, @@ -186,7 +207,7 @@ closing_marubozu.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ closing_marubozu.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLCONCEALBABYSWALL.R b/R/ta_CDLCONCEALBABYSWALL.R index 52100f9bf..dd97bea69 100644 --- a/R/ta_CDLCONCEALBABYSWALL.R +++ b/R/ta_CDLCONCEALBABYSWALL.R @@ -77,35 +77,33 @@ concealing_baby_swallow.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLCONCEALBABYSWALL, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLCONCEALBABYSWALL, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLCONCEALBABYSWALL" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ concealing_baby_swallow.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( concealing_baby_swallow.default( x = x, cols = cols, @@ -141,14 +139,37 @@ concealing_baby_swallow.matrix <- function( na.bridge = FALSE, ... ) { - concealing_baby_swallow.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + concealing_baby_swallow.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases concealing_baby_swallow +#' +#' @export +concealing_baby_swallow.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + concealing_baby_swallow.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLCONCEALBABYSWALL_lookback <- concealingBabySwallow_lookback <- concealing_baby_swallow_lookback <- function( x, @@ -186,7 +207,7 @@ concealing_baby_swallow.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ concealing_baby_swallow.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLCOUNTERATTACK.R b/R/ta_CDLCOUNTERATTACK.R index 3f14a1af8..279529d8c 100644 --- a/R/ta_CDLCOUNTERATTACK.R +++ b/R/ta_CDLCOUNTERATTACK.R @@ -77,35 +77,33 @@ counter_attack.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLCOUNTERATTACK, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLCOUNTERATTACK, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLCOUNTERATTACK" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ counter_attack.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( counter_attack.default( x = x, cols = cols, @@ -141,14 +139,37 @@ counter_attack.matrix <- function( na.bridge = FALSE, ... ) { - counter_attack.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + counter_attack.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases counter_attack +#' +#' @export +counter_attack.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + counter_attack.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLCOUNTERATTACK_lookback <- counterAttack_lookback <- counter_attack_lookback <- function( x, @@ -186,7 +207,7 @@ counter_attack.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ counter_attack.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLDARKCLOUDCOVER.R b/R/ta_CDLDARKCLOUDCOVER.R index da42c6f96..b53d9dd96 100644 --- a/R/ta_CDLDARKCLOUDCOVER.R +++ b/R/ta_CDLDARKCLOUDCOVER.R @@ -79,36 +79,34 @@ dark_cloud_cover.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLDARKCLOUDCOVER, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - as.double(penetration), - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLDARKCLOUDCOVER, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + as.double(penetration), + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLDARKCLOUDCOVER" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -125,7 +123,7 @@ dark_cloud_cover.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( dark_cloud_cover.default( x = x, cols = cols, @@ -147,15 +145,40 @@ dark_cloud_cover.matrix <- function( na.bridge = FALSE, ... ) { - dark_cloud_cover.default( - x = x, - cols = cols, - penetration = penetration, - na.bridge = na.bridge, - ... + as.matrix( + dark_cloud_cover.default( + x = x, + cols = cols, + penetration = penetration, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases dark_cloud_cover +#' +#' @export +dark_cloud_cover.xts <- function( + x, + cols, + penetration = 0.5, + na.bridge = FALSE, + ... +) { + as.xts( + dark_cloud_cover.default( + x = x, + cols = cols, + penetration = penetration, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLDARKCLOUDCOVER_lookback <- darkCloudCover_lookback <- dark_cloud_cover_lookback <- function( x, @@ -196,7 +219,7 @@ dark_cloud_cover.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -256,7 +279,7 @@ dark_cloud_cover.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLDOJI.R b/R/ta_CDLDOJI.R index bec111837..80741735e 100644 --- a/R/ta_CDLDOJI.R +++ b/R/ta_CDLDOJI.R @@ -70,35 +70,33 @@ doji.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLDOJI, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLDOJI, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLDOJI" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -114,7 +112,7 @@ doji.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( doji.default( x = x, cols = cols, @@ -134,14 +132,37 @@ doji.matrix <- function( na.bridge = FALSE, ... ) { - doji.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + doji.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases doji +#' +#' @export +doji.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + doji.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLDOJI_lookback <- doji_lookback <- function( x, @@ -179,7 +200,7 @@ doji.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -237,7 +258,7 @@ doji.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLDOJISTAR.R b/R/ta_CDLDOJISTAR.R index d9216409b..d86604f52 100644 --- a/R/ta_CDLDOJISTAR.R +++ b/R/ta_CDLDOJISTAR.R @@ -77,35 +77,33 @@ doji_star.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLDOJISTAR, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLDOJISTAR, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLDOJISTAR" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ doji_star.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( doji_star.default( x = x, cols = cols, @@ -141,14 +139,37 @@ doji_star.matrix <- function( na.bridge = FALSE, ... ) { - doji_star.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + doji_star.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases doji_star +#' +#' @export +doji_star.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + doji_star.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLDOJISTAR_lookback <- dojiStar_lookback <- doji_star_lookback <- function( x, @@ -186,7 +207,7 @@ doji_star.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ doji_star.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLDRAGONFLYDOJI.R b/R/ta_CDLDRAGONFLYDOJI.R index 9e7bbb2f2..842335c68 100644 --- a/R/ta_CDLDRAGONFLYDOJI.R +++ b/R/ta_CDLDRAGONFLYDOJI.R @@ -77,35 +77,33 @@ dragonfly_doji.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLDRAGONFLYDOJI, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLDRAGONFLYDOJI, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLDRAGONFLYDOJI" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ dragonfly_doji.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( dragonfly_doji.default( x = x, cols = cols, @@ -141,14 +139,37 @@ dragonfly_doji.matrix <- function( na.bridge = FALSE, ... ) { - dragonfly_doji.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + dragonfly_doji.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases dragonfly_doji +#' +#' @export +dragonfly_doji.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + dragonfly_doji.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLDRAGONFLYDOJI_lookback <- dragonflyDoji_lookback <- dragonfly_doji_lookback <- function( x, @@ -186,7 +207,7 @@ dragonfly_doji.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ dragonfly_doji.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLENGULFING.R b/R/ta_CDLENGULFING.R index ec0a2d952..8b4dae593 100644 --- a/R/ta_CDLENGULFING.R +++ b/R/ta_CDLENGULFING.R @@ -70,35 +70,33 @@ engulfing.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLENGULFING, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLENGULFING, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLENGULFING" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -114,7 +112,7 @@ engulfing.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( engulfing.default( x = x, cols = cols, @@ -134,14 +132,37 @@ engulfing.matrix <- function( na.bridge = FALSE, ... ) { - engulfing.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + engulfing.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases engulfing +#' +#' @export +engulfing.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + engulfing.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLENGULFING_lookback <- engulfing_lookback <- function( x, @@ -179,7 +200,7 @@ engulfing.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -237,7 +258,7 @@ engulfing.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLEVENINGDOJISTAR.R b/R/ta_CDLEVENINGDOJISTAR.R index ac78692f3..252d1569d 100644 --- a/R/ta_CDLEVENINGDOJISTAR.R +++ b/R/ta_CDLEVENINGDOJISTAR.R @@ -79,36 +79,34 @@ evening_doji_star.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLEVENINGDOJISTAR, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - as.double(penetration), - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLEVENINGDOJISTAR, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + as.double(penetration), + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLEVENINGDOJISTAR" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -125,7 +123,7 @@ evening_doji_star.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( evening_doji_star.default( x = x, cols = cols, @@ -147,15 +145,40 @@ evening_doji_star.matrix <- function( na.bridge = FALSE, ... ) { - evening_doji_star.default( - x = x, - cols = cols, - penetration = penetration, - na.bridge = na.bridge, - ... + as.matrix( + evening_doji_star.default( + x = x, + cols = cols, + penetration = penetration, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases evening_doji_star +#' +#' @export +evening_doji_star.xts <- function( + x, + cols, + penetration = 0.3, + na.bridge = FALSE, + ... +) { + as.xts( + evening_doji_star.default( + x = x, + cols = cols, + penetration = penetration, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLEVENINGDOJISTAR_lookback <- eveningDojiStar_lookback <- evening_doji_star_lookback <- function( x, @@ -196,7 +219,7 @@ evening_doji_star.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -256,7 +279,7 @@ evening_doji_star.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLEVENINGSTAR.R b/R/ta_CDLEVENINGSTAR.R index 125d85543..796722682 100644 --- a/R/ta_CDLEVENINGSTAR.R +++ b/R/ta_CDLEVENINGSTAR.R @@ -79,36 +79,34 @@ evening_star.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLEVENINGSTAR, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - as.double(penetration), - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLEVENINGSTAR, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + as.double(penetration), + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLEVENINGSTAR" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -125,7 +123,7 @@ evening_star.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( evening_star.default( x = x, cols = cols, @@ -147,15 +145,40 @@ evening_star.matrix <- function( na.bridge = FALSE, ... ) { - evening_star.default( - x = x, - cols = cols, - penetration = penetration, - na.bridge = na.bridge, - ... + as.matrix( + evening_star.default( + x = x, + cols = cols, + penetration = penetration, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases evening_star +#' +#' @export +evening_star.xts <- function( + x, + cols, + penetration = 0.3, + na.bridge = FALSE, + ... +) { + as.xts( + evening_star.default( + x = x, + cols = cols, + penetration = penetration, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLEVENINGSTAR_lookback <- eveningStar_lookback <- evening_star_lookback <- function( x, @@ -196,7 +219,7 @@ evening_star.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -256,7 +279,7 @@ evening_star.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLGAPSIDESIDEWHITE.R b/R/ta_CDLGAPSIDESIDEWHITE.R index de5e8f8c2..2eec8e064 100644 --- a/R/ta_CDLGAPSIDESIDEWHITE.R +++ b/R/ta_CDLGAPSIDESIDEWHITE.R @@ -77,35 +77,33 @@ gaps_side_white.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLGAPSIDESIDEWHITE, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLGAPSIDESIDEWHITE, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLGAPSIDESIDEWHITE" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ gaps_side_white.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( gaps_side_white.default( x = x, cols = cols, @@ -141,14 +139,37 @@ gaps_side_white.matrix <- function( na.bridge = FALSE, ... ) { - gaps_side_white.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + gaps_side_white.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases gaps_side_white +#' +#' @export +gaps_side_white.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + gaps_side_white.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLGAPSIDESIDEWHITE_lookback <- gapsSideWhite_lookback <- gaps_side_white_lookback <- function( x, @@ -186,7 +207,7 @@ gaps_side_white.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ gaps_side_white.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLGRAVESTONEDOJI.R b/R/ta_CDLGRAVESTONEDOJI.R index a1a8e6b70..bf6d3d8ef 100644 --- a/R/ta_CDLGRAVESTONEDOJI.R +++ b/R/ta_CDLGRAVESTONEDOJI.R @@ -77,35 +77,33 @@ gravestone_doji.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLGRAVESTONEDOJI, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLGRAVESTONEDOJI, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLGRAVESTONEDOJI" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ gravestone_doji.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( gravestone_doji.default( x = x, cols = cols, @@ -141,14 +139,37 @@ gravestone_doji.matrix <- function( na.bridge = FALSE, ... ) { - gravestone_doji.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + gravestone_doji.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases gravestone_doji +#' +#' @export +gravestone_doji.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + gravestone_doji.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLGRAVESTONEDOJI_lookback <- gravestoneDoji_lookback <- gravestone_doji_lookback <- function( x, @@ -186,7 +207,7 @@ gravestone_doji.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ gravestone_doji.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLHAMMER.R b/R/ta_CDLHAMMER.R index b27203f87..5b90f50c1 100644 --- a/R/ta_CDLHAMMER.R +++ b/R/ta_CDLHAMMER.R @@ -70,35 +70,33 @@ hammer.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLHAMMER, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLHAMMER, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLHAMMER" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -114,7 +112,7 @@ hammer.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( hammer.default( x = x, cols = cols, @@ -134,14 +132,37 @@ hammer.matrix <- function( na.bridge = FALSE, ... ) { - hammer.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + hammer.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases hammer +#' +#' @export +hammer.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + hammer.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLHAMMER_lookback <- hammer_lookback <- function( x, @@ -179,7 +200,7 @@ hammer.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -237,7 +258,7 @@ hammer.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLHANGINGMAN.R b/R/ta_CDLHANGINGMAN.R index fcfeb18a9..fc447681c 100644 --- a/R/ta_CDLHANGINGMAN.R +++ b/R/ta_CDLHANGINGMAN.R @@ -77,35 +77,33 @@ hanging_man.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLHANGINGMAN, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLHANGINGMAN, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLHANGINGMAN" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ hanging_man.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( hanging_man.default( x = x, cols = cols, @@ -141,14 +139,37 @@ hanging_man.matrix <- function( na.bridge = FALSE, ... ) { - hanging_man.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + hanging_man.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases hanging_man +#' +#' @export +hanging_man.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + hanging_man.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLHANGINGMAN_lookback <- hangingMan_lookback <- hanging_man_lookback <- function( x, @@ -186,7 +207,7 @@ hanging_man.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ hanging_man.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLHARAMI.R b/R/ta_CDLHARAMI.R index 47ea7b55c..b62de4412 100644 --- a/R/ta_CDLHARAMI.R +++ b/R/ta_CDLHARAMI.R @@ -70,35 +70,33 @@ harami.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLHARAMI, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLHARAMI, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLHARAMI" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -114,7 +112,7 @@ harami.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( harami.default( x = x, cols = cols, @@ -134,14 +132,37 @@ harami.matrix <- function( na.bridge = FALSE, ... ) { - harami.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + harami.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases harami +#' +#' @export +harami.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + harami.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLHARAMI_lookback <- harami_lookback <- function( x, @@ -179,7 +200,7 @@ harami.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -237,7 +258,7 @@ harami.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLHARAMICROSS.R b/R/ta_CDLHARAMICROSS.R index 2881eee1c..32dbb0e98 100644 --- a/R/ta_CDLHARAMICROSS.R +++ b/R/ta_CDLHARAMICROSS.R @@ -77,35 +77,33 @@ harami_cross.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLHARAMICROSS, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLHARAMICROSS, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLHARAMICROSS" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ harami_cross.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( harami_cross.default( x = x, cols = cols, @@ -141,14 +139,37 @@ harami_cross.matrix <- function( na.bridge = FALSE, ... ) { - harami_cross.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + harami_cross.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases harami_cross +#' +#' @export +harami_cross.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + harami_cross.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLHARAMICROSS_lookback <- haramiCross_lookback <- harami_cross_lookback <- function( x, @@ -186,7 +207,7 @@ harami_cross.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ harami_cross.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLHIGHWAVE.R b/R/ta_CDLHIGHWAVE.R index ad60c5929..3e7a4a9e6 100644 --- a/R/ta_CDLHIGHWAVE.R +++ b/R/ta_CDLHIGHWAVE.R @@ -77,35 +77,33 @@ high_wave.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLHIGHWAVE, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLHIGHWAVE, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLHIGHWAVE" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ high_wave.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( high_wave.default( x = x, cols = cols, @@ -141,14 +139,37 @@ high_wave.matrix <- function( na.bridge = FALSE, ... ) { - high_wave.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + high_wave.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases high_wave +#' +#' @export +high_wave.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + high_wave.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLHIGHWAVE_lookback <- highWave_lookback <- high_wave_lookback <- function( x, @@ -186,7 +207,7 @@ high_wave.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ high_wave.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLHIKKAKE.R b/R/ta_CDLHIKKAKE.R index 8084cb4a3..23a0298c5 100644 --- a/R/ta_CDLHIKKAKE.R +++ b/R/ta_CDLHIKKAKE.R @@ -70,35 +70,33 @@ hikakke.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLHIKKAKE, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLHIKKAKE, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLHIKKAKE" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -114,7 +112,7 @@ hikakke.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( hikakke.default( x = x, cols = cols, @@ -134,14 +132,37 @@ hikakke.matrix <- function( na.bridge = FALSE, ... ) { - hikakke.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + hikakke.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases hikakke +#' +#' @export +hikakke.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + hikakke.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLHIKKAKE_lookback <- hikakke_lookback <- function( x, @@ -179,7 +200,7 @@ hikakke.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -237,7 +258,7 @@ hikakke.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLHIKKAKEMOD.R b/R/ta_CDLHIKKAKEMOD.R index 11b6bab91..a39e23127 100644 --- a/R/ta_CDLHIKKAKEMOD.R +++ b/R/ta_CDLHIKKAKEMOD.R @@ -77,35 +77,33 @@ hikakke_mod.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLHIKKAKEMOD, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLHIKKAKEMOD, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLHIKKAKEMOD" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ hikakke_mod.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( hikakke_mod.default( x = x, cols = cols, @@ -141,14 +139,37 @@ hikakke_mod.matrix <- function( na.bridge = FALSE, ... ) { - hikakke_mod.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + hikakke_mod.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases hikakke_mod +#' +#' @export +hikakke_mod.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + hikakke_mod.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLHIKKAKEMOD_lookback <- hikakkeMod_lookback <- hikakke_mod_lookback <- function( x, @@ -186,7 +207,7 @@ hikakke_mod.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ hikakke_mod.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLHOMINGPIGEON.R b/R/ta_CDLHOMINGPIGEON.R index fba92b1ea..71e3ed75e 100644 --- a/R/ta_CDLHOMINGPIGEON.R +++ b/R/ta_CDLHOMINGPIGEON.R @@ -77,35 +77,33 @@ homing_pigeon.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLHOMINGPIGEON, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLHOMINGPIGEON, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLHOMINGPIGEON" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ homing_pigeon.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( homing_pigeon.default( x = x, cols = cols, @@ -141,14 +139,37 @@ homing_pigeon.matrix <- function( na.bridge = FALSE, ... ) { - homing_pigeon.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + homing_pigeon.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases homing_pigeon +#' +#' @export +homing_pigeon.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + homing_pigeon.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLHOMINGPIGEON_lookback <- homingPigeon_lookback <- homing_pigeon_lookback <- function( x, @@ -186,7 +207,7 @@ homing_pigeon.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ homing_pigeon.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLIDENTICAL3CROWS.R b/R/ta_CDLIDENTICAL3CROWS.R index 256dc1eb9..112f413d0 100644 --- a/R/ta_CDLIDENTICAL3CROWS.R +++ b/R/ta_CDLIDENTICAL3CROWS.R @@ -77,35 +77,33 @@ three_identical_crows.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLIDENTICAL3CROWS, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLIDENTICAL3CROWS, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLIDENTICAL3CROWS" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ three_identical_crows.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( three_identical_crows.default( x = x, cols = cols, @@ -141,14 +139,37 @@ three_identical_crows.matrix <- function( na.bridge = FALSE, ... ) { - three_identical_crows.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + three_identical_crows.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases three_identical_crows +#' +#' @export +three_identical_crows.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + three_identical_crows.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLIDENTICAL3CROWS_lookback <- threeIdenticalCrows_lookback <- three_identical_crows_lookback <- function( x, @@ -186,7 +207,7 @@ three_identical_crows.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ three_identical_crows.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLINNECK.R b/R/ta_CDLINNECK.R index aa9398bd4..b88b97deb 100644 --- a/R/ta_CDLINNECK.R +++ b/R/ta_CDLINNECK.R @@ -77,35 +77,33 @@ in_neck.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLINNECK, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLINNECK, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLINNECK" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ in_neck.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( in_neck.default( x = x, cols = cols, @@ -141,14 +139,37 @@ in_neck.matrix <- function( na.bridge = FALSE, ... ) { - in_neck.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + in_neck.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases in_neck +#' +#' @export +in_neck.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + in_neck.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLINNECK_lookback <- inNeck_lookback <- in_neck_lookback <- function( x, @@ -186,7 +207,7 @@ in_neck.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ in_neck.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLINVERTEDHAMMER.R b/R/ta_CDLINVERTEDHAMMER.R index a55211985..8182ab320 100644 --- a/R/ta_CDLINVERTEDHAMMER.R +++ b/R/ta_CDLINVERTEDHAMMER.R @@ -77,35 +77,33 @@ inverted_hammer.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLINVERTEDHAMMER, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLINVERTEDHAMMER, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLINVERTEDHAMMER" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ inverted_hammer.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( inverted_hammer.default( x = x, cols = cols, @@ -141,14 +139,37 @@ inverted_hammer.matrix <- function( na.bridge = FALSE, ... ) { - inverted_hammer.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + inverted_hammer.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases inverted_hammer +#' +#' @export +inverted_hammer.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + inverted_hammer.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLINVERTEDHAMMER_lookback <- invertedHammer_lookback <- inverted_hammer_lookback <- function( x, @@ -186,7 +207,7 @@ inverted_hammer.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ inverted_hammer.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLKICKING.R b/R/ta_CDLKICKING.R index 320620fe1..d42724c5d 100644 --- a/R/ta_CDLKICKING.R +++ b/R/ta_CDLKICKING.R @@ -70,35 +70,33 @@ kicking.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLKICKING, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLKICKING, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLKICKING" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -114,7 +112,7 @@ kicking.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( kicking.default( x = x, cols = cols, @@ -134,14 +132,37 @@ kicking.matrix <- function( na.bridge = FALSE, ... ) { - kicking.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + kicking.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases kicking +#' +#' @export +kicking.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + kicking.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLKICKING_lookback <- kicking_lookback <- function( x, @@ -179,7 +200,7 @@ kicking.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -237,7 +258,7 @@ kicking.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLKICKINGBYLENGTH.R b/R/ta_CDLKICKINGBYLENGTH.R index 4fa625ff7..6f34cbd8d 100644 --- a/R/ta_CDLKICKINGBYLENGTH.R +++ b/R/ta_CDLKICKINGBYLENGTH.R @@ -77,35 +77,33 @@ kicking_baby_length.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLKICKINGBYLENGTH, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLKICKINGBYLENGTH, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLKICKINGBYLENGTH" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ kicking_baby_length.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( kicking_baby_length.default( x = x, cols = cols, @@ -141,14 +139,37 @@ kicking_baby_length.matrix <- function( na.bridge = FALSE, ... ) { - kicking_baby_length.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + kicking_baby_length.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases kicking_baby_length +#' +#' @export +kicking_baby_length.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + kicking_baby_length.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLKICKINGBYLENGTH_lookback <- kickingBabyLength_lookback <- kicking_baby_length_lookback <- function( x, @@ -186,7 +207,7 @@ kicking_baby_length.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ kicking_baby_length.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLLADDERBOTTOM.R b/R/ta_CDLLADDERBOTTOM.R index 51fc9e3e9..d30d7379f 100644 --- a/R/ta_CDLLADDERBOTTOM.R +++ b/R/ta_CDLLADDERBOTTOM.R @@ -77,35 +77,33 @@ ladder_bottom.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLLADDERBOTTOM, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLLADDERBOTTOM, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLLADDERBOTTOM" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ ladder_bottom.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( ladder_bottom.default( x = x, cols = cols, @@ -141,14 +139,37 @@ ladder_bottom.matrix <- function( na.bridge = FALSE, ... ) { - ladder_bottom.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + ladder_bottom.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases ladder_bottom +#' +#' @export +ladder_bottom.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + ladder_bottom.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLLADDERBOTTOM_lookback <- ladderBottom_lookback <- ladder_bottom_lookback <- function( x, @@ -186,7 +207,7 @@ ladder_bottom.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ ladder_bottom.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLLONGLEGGEDDOJI.R b/R/ta_CDLLONGLEGGEDDOJI.R index 4084282b2..048802691 100644 --- a/R/ta_CDLLONGLEGGEDDOJI.R +++ b/R/ta_CDLLONGLEGGEDDOJI.R @@ -77,35 +77,33 @@ long_legged_doji.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLLONGLEGGEDDOJI, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLLONGLEGGEDDOJI, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLLONGLEGGEDDOJI" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ long_legged_doji.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( long_legged_doji.default( x = x, cols = cols, @@ -141,14 +139,37 @@ long_legged_doji.matrix <- function( na.bridge = FALSE, ... ) { - long_legged_doji.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + long_legged_doji.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases long_legged_doji +#' +#' @export +long_legged_doji.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + long_legged_doji.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLLONGLEGGEDDOJI_lookback <- longLeggedDoji_lookback <- long_legged_doji_lookback <- function( x, @@ -186,7 +207,7 @@ long_legged_doji.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ long_legged_doji.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLLONGLINE.R b/R/ta_CDLLONGLINE.R index 59d24e9b2..643959243 100644 --- a/R/ta_CDLLONGLINE.R +++ b/R/ta_CDLLONGLINE.R @@ -77,35 +77,33 @@ long_line.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLLONGLINE, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLLONGLINE, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLLONGLINE" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ long_line.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( long_line.default( x = x, cols = cols, @@ -141,14 +139,37 @@ long_line.matrix <- function( na.bridge = FALSE, ... ) { - long_line.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + long_line.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases long_line +#' +#' @export +long_line.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + long_line.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLLONGLINE_lookback <- longLine_lookback <- long_line_lookback <- function( x, @@ -186,7 +207,7 @@ long_line.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ long_line.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLMARUBOZU.R b/R/ta_CDLMARUBOZU.R index ed540a839..9912e3c41 100644 --- a/R/ta_CDLMARUBOZU.R +++ b/R/ta_CDLMARUBOZU.R @@ -70,35 +70,33 @@ marubozu.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLMARUBOZU, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLMARUBOZU, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLMARUBOZU" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -114,7 +112,7 @@ marubozu.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( marubozu.default( x = x, cols = cols, @@ -134,14 +132,37 @@ marubozu.matrix <- function( na.bridge = FALSE, ... ) { - marubozu.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + marubozu.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases marubozu +#' +#' @export +marubozu.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + marubozu.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLMARUBOZU_lookback <- marubozu_lookback <- function( x, @@ -179,7 +200,7 @@ marubozu.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -237,7 +258,7 @@ marubozu.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLMATCHINGLOW.R b/R/ta_CDLMATCHINGLOW.R index b55e7cb94..2a7c42c3c 100644 --- a/R/ta_CDLMATCHINGLOW.R +++ b/R/ta_CDLMATCHINGLOW.R @@ -77,35 +77,33 @@ matching_low.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLMATCHINGLOW, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLMATCHINGLOW, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLMATCHINGLOW" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ matching_low.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( matching_low.default( x = x, cols = cols, @@ -141,14 +139,37 @@ matching_low.matrix <- function( na.bridge = FALSE, ... ) { - matching_low.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + matching_low.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases matching_low +#' +#' @export +matching_low.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + matching_low.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLMATCHINGLOW_lookback <- matchingLow_lookback <- matching_low_lookback <- function( x, @@ -186,7 +207,7 @@ matching_low.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ matching_low.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLMATHOLD.R b/R/ta_CDLMATHOLD.R index 180fd8a4c..b3e8a1409 100644 --- a/R/ta_CDLMATHOLD.R +++ b/R/ta_CDLMATHOLD.R @@ -79,36 +79,34 @@ mat_hold.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLMATHOLD, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - as.double(penetration), - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLMATHOLD, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + as.double(penetration), + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLMATHOLD" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -125,7 +123,7 @@ mat_hold.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( mat_hold.default( x = x, cols = cols, @@ -147,15 +145,40 @@ mat_hold.matrix <- function( na.bridge = FALSE, ... ) { - mat_hold.default( - x = x, - cols = cols, - penetration = penetration, - na.bridge = na.bridge, - ... + as.matrix( + mat_hold.default( + x = x, + cols = cols, + penetration = penetration, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases mat_hold +#' +#' @export +mat_hold.xts <- function( + x, + cols, + penetration = 0.5, + na.bridge = FALSE, + ... +) { + as.xts( + mat_hold.default( + x = x, + cols = cols, + penetration = penetration, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLMATHOLD_lookback <- matHold_lookback <- mat_hold_lookback <- function( x, @@ -196,7 +219,7 @@ mat_hold.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -256,7 +279,7 @@ mat_hold.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLMORNINGDOJISTAR.R b/R/ta_CDLMORNINGDOJISTAR.R index ef9075fb7..5382877a4 100644 --- a/R/ta_CDLMORNINGDOJISTAR.R +++ b/R/ta_CDLMORNINGDOJISTAR.R @@ -79,36 +79,34 @@ morning_doji_star.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLMORNINGDOJISTAR, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - as.double(penetration), - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLMORNINGDOJISTAR, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + as.double(penetration), + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLMORNINGDOJISTAR" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -125,7 +123,7 @@ morning_doji_star.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( morning_doji_star.default( x = x, cols = cols, @@ -147,15 +145,40 @@ morning_doji_star.matrix <- function( na.bridge = FALSE, ... ) { - morning_doji_star.default( - x = x, - cols = cols, - penetration = penetration, - na.bridge = na.bridge, - ... + as.matrix( + morning_doji_star.default( + x = x, + cols = cols, + penetration = penetration, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases morning_doji_star +#' +#' @export +morning_doji_star.xts <- function( + x, + cols, + penetration = 0.3, + na.bridge = FALSE, + ... +) { + as.xts( + morning_doji_star.default( + x = x, + cols = cols, + penetration = penetration, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLMORNINGDOJISTAR_lookback <- morningDojiStar_lookback <- morning_doji_star_lookback <- function( x, @@ -196,7 +219,7 @@ morning_doji_star.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -256,7 +279,7 @@ morning_doji_star.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLMORNINGSTAR.R b/R/ta_CDLMORNINGSTAR.R index 94dbf01f7..98e2b4f41 100644 --- a/R/ta_CDLMORNINGSTAR.R +++ b/R/ta_CDLMORNINGSTAR.R @@ -79,36 +79,34 @@ morning_star.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLMORNINGSTAR, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - as.double(penetration), - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLMORNINGSTAR, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + as.double(penetration), + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLMORNINGSTAR" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -125,7 +123,7 @@ morning_star.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( morning_star.default( x = x, cols = cols, @@ -147,15 +145,40 @@ morning_star.matrix <- function( na.bridge = FALSE, ... ) { - morning_star.default( - x = x, - cols = cols, - penetration = penetration, - na.bridge = na.bridge, - ... + as.matrix( + morning_star.default( + x = x, + cols = cols, + penetration = penetration, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases morning_star +#' +#' @export +morning_star.xts <- function( + x, + cols, + penetration = 0.3, + na.bridge = FALSE, + ... +) { + as.xts( + morning_star.default( + x = x, + cols = cols, + penetration = penetration, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLMORNINGSTAR_lookback <- morningStar_lookback <- morning_star_lookback <- function( x, @@ -196,7 +219,7 @@ morning_star.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -256,7 +279,7 @@ morning_star.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLONNECK.R b/R/ta_CDLONNECK.R index 1158f827d..962ee3ebf 100644 --- a/R/ta_CDLONNECK.R +++ b/R/ta_CDLONNECK.R @@ -77,35 +77,33 @@ on_neck.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLONNECK, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLONNECK, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLONNECK" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ on_neck.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( on_neck.default( x = x, cols = cols, @@ -141,14 +139,37 @@ on_neck.matrix <- function( na.bridge = FALSE, ... ) { - on_neck.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + on_neck.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases on_neck +#' +#' @export +on_neck.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + on_neck.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLONNECK_lookback <- onNeck_lookback <- on_neck_lookback <- function( x, @@ -186,7 +207,7 @@ on_neck.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ on_neck.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLPIERCING.R b/R/ta_CDLPIERCING.R index efa7e433f..bde204751 100644 --- a/R/ta_CDLPIERCING.R +++ b/R/ta_CDLPIERCING.R @@ -70,35 +70,33 @@ piercing.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLPIERCING, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLPIERCING, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLPIERCING" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -114,7 +112,7 @@ piercing.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( piercing.default( x = x, cols = cols, @@ -134,14 +132,37 @@ piercing.matrix <- function( na.bridge = FALSE, ... ) { - piercing.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + piercing.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases piercing +#' +#' @export +piercing.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + piercing.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLPIERCING_lookback <- piercing_lookback <- function( x, @@ -179,7 +200,7 @@ piercing.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -237,7 +258,7 @@ piercing.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLRICKSHAWMAN.R b/R/ta_CDLRICKSHAWMAN.R index 4d697ae40..65c8893d9 100644 --- a/R/ta_CDLRICKSHAWMAN.R +++ b/R/ta_CDLRICKSHAWMAN.R @@ -77,35 +77,33 @@ rickshaw_man.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLRICKSHAWMAN, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLRICKSHAWMAN, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLRICKSHAWMAN" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ rickshaw_man.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( rickshaw_man.default( x = x, cols = cols, @@ -141,14 +139,37 @@ rickshaw_man.matrix <- function( na.bridge = FALSE, ... ) { - rickshaw_man.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + rickshaw_man.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases rickshaw_man +#' +#' @export +rickshaw_man.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + rickshaw_man.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLRICKSHAWMAN_lookback <- rickshawMan_lookback <- rickshaw_man_lookback <- function( x, @@ -186,7 +207,7 @@ rickshaw_man.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ rickshaw_man.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLRISEFALL3METHODS.R b/R/ta_CDLRISEFALL3METHODS.R index 17ce29d27..fb9951282 100644 --- a/R/ta_CDLRISEFALL3METHODS.R +++ b/R/ta_CDLRISEFALL3METHODS.R @@ -77,35 +77,33 @@ rise_fall_3_methods.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLRISEFALL3METHODS, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLRISEFALL3METHODS, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLRISEFALL3METHODS" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ rise_fall_3_methods.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( rise_fall_3_methods.default( x = x, cols = cols, @@ -141,14 +139,37 @@ rise_fall_3_methods.matrix <- function( na.bridge = FALSE, ... ) { - rise_fall_3_methods.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + rise_fall_3_methods.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases rise_fall_3_methods +#' +#' @export +rise_fall_3_methods.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + rise_fall_3_methods.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLRISEFALL3METHODS_lookback <- riseFall3Methods_lookback <- rise_fall_3_methods_lookback <- function( x, @@ -186,7 +207,7 @@ rise_fall_3_methods.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ rise_fall_3_methods.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLSEPARATINGLINES.R b/R/ta_CDLSEPARATINGLINES.R index da857c8f0..e3c8eb9f0 100644 --- a/R/ta_CDLSEPARATINGLINES.R +++ b/R/ta_CDLSEPARATINGLINES.R @@ -77,35 +77,33 @@ separating_lines.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLSEPARATINGLINES, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLSEPARATINGLINES, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLSEPARATINGLINES" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ separating_lines.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( separating_lines.default( x = x, cols = cols, @@ -141,14 +139,37 @@ separating_lines.matrix <- function( na.bridge = FALSE, ... ) { - separating_lines.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + separating_lines.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases separating_lines +#' +#' @export +separating_lines.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + separating_lines.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLSEPARATINGLINES_lookback <- separatingLines_lookback <- separating_lines_lookback <- function( x, @@ -186,7 +207,7 @@ separating_lines.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ separating_lines.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLSHOOTINGSTAR.R b/R/ta_CDLSHOOTINGSTAR.R index 77b1f68c3..567abbec9 100644 --- a/R/ta_CDLSHOOTINGSTAR.R +++ b/R/ta_CDLSHOOTINGSTAR.R @@ -77,35 +77,33 @@ shooting_star.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLSHOOTINGSTAR, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLSHOOTINGSTAR, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLSHOOTINGSTAR" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ shooting_star.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( shooting_star.default( x = x, cols = cols, @@ -141,14 +139,37 @@ shooting_star.matrix <- function( na.bridge = FALSE, ... ) { - shooting_star.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + shooting_star.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases shooting_star +#' +#' @export +shooting_star.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + shooting_star.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLSHOOTINGSTAR_lookback <- shootingStar_lookback <- shooting_star_lookback <- function( x, @@ -186,7 +207,7 @@ shooting_star.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ shooting_star.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLSHORTLINE.R b/R/ta_CDLSHORTLINE.R index 4044bb321..ec3eb8510 100644 --- a/R/ta_CDLSHORTLINE.R +++ b/R/ta_CDLSHORTLINE.R @@ -77,35 +77,33 @@ short_line.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLSHORTLINE, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLSHORTLINE, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLSHORTLINE" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ short_line.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( short_line.default( x = x, cols = cols, @@ -141,14 +139,37 @@ short_line.matrix <- function( na.bridge = FALSE, ... ) { - short_line.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + short_line.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases short_line +#' +#' @export +short_line.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + short_line.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLSHORTLINE_lookback <- shortLine_lookback <- short_line_lookback <- function( x, @@ -186,7 +207,7 @@ short_line.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ short_line.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLSPINNINGTOP.R b/R/ta_CDLSPINNINGTOP.R index e03f61f18..4295f9465 100644 --- a/R/ta_CDLSPINNINGTOP.R +++ b/R/ta_CDLSPINNINGTOP.R @@ -77,35 +77,33 @@ spinning_top.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLSPINNINGTOP, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLSPINNINGTOP, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLSPINNINGTOP" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ spinning_top.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( spinning_top.default( x = x, cols = cols, @@ -141,14 +139,37 @@ spinning_top.matrix <- function( na.bridge = FALSE, ... ) { - spinning_top.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + spinning_top.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases spinning_top +#' +#' @export +spinning_top.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + spinning_top.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLSPINNINGTOP_lookback <- spinningTop_lookback <- spinning_top_lookback <- function( x, @@ -186,7 +207,7 @@ spinning_top.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ spinning_top.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLSTALLEDPATTERN.R b/R/ta_CDLSTALLEDPATTERN.R index 7812764a2..c98694daf 100644 --- a/R/ta_CDLSTALLEDPATTERN.R +++ b/R/ta_CDLSTALLEDPATTERN.R @@ -77,35 +77,33 @@ stalled_pattern.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLSTALLEDPATTERN, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLSTALLEDPATTERN, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLSTALLEDPATTERN" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ stalled_pattern.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( stalled_pattern.default( x = x, cols = cols, @@ -141,14 +139,37 @@ stalled_pattern.matrix <- function( na.bridge = FALSE, ... ) { - stalled_pattern.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + stalled_pattern.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases stalled_pattern +#' +#' @export +stalled_pattern.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + stalled_pattern.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLSTALLEDPATTERN_lookback <- stalledPattern_lookback <- stalled_pattern_lookback <- function( x, @@ -186,7 +207,7 @@ stalled_pattern.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ stalled_pattern.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLSTICKSANDWICH.R b/R/ta_CDLSTICKSANDWICH.R index 5c554bea9..e693238f7 100644 --- a/R/ta_CDLSTICKSANDWICH.R +++ b/R/ta_CDLSTICKSANDWICH.R @@ -77,35 +77,33 @@ stick_sandwich.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLSTICKSANDWICH, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLSTICKSANDWICH, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLSTICKSANDWICH" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ stick_sandwich.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( stick_sandwich.default( x = x, cols = cols, @@ -141,14 +139,37 @@ stick_sandwich.matrix <- function( na.bridge = FALSE, ... ) { - stick_sandwich.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + stick_sandwich.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases stick_sandwich +#' +#' @export +stick_sandwich.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + stick_sandwich.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLSTICKSANDWICH_lookback <- stickSandwich_lookback <- stick_sandwich_lookback <- function( x, @@ -186,7 +207,7 @@ stick_sandwich.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ stick_sandwich.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLTAKURI.R b/R/ta_CDLTAKURI.R index 6273baa29..8e6cb53ff 100644 --- a/R/ta_CDLTAKURI.R +++ b/R/ta_CDLTAKURI.R @@ -70,35 +70,33 @@ takuri.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLTAKURI, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLTAKURI, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLTAKURI" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -114,7 +112,7 @@ takuri.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( takuri.default( x = x, cols = cols, @@ -134,14 +132,37 @@ takuri.matrix <- function( na.bridge = FALSE, ... ) { - takuri.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + takuri.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases takuri +#' +#' @export +takuri.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + takuri.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLTAKURI_lookback <- takuri_lookback <- function( x, @@ -179,7 +200,7 @@ takuri.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -237,7 +258,7 @@ takuri.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLTASUKIGAP.R b/R/ta_CDLTASUKIGAP.R index eb77bc8a3..742a38c18 100644 --- a/R/ta_CDLTASUKIGAP.R +++ b/R/ta_CDLTASUKIGAP.R @@ -77,35 +77,33 @@ tasuki_gap.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLTASUKIGAP, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLTASUKIGAP, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLTASUKIGAP" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ tasuki_gap.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( tasuki_gap.default( x = x, cols = cols, @@ -141,14 +139,37 @@ tasuki_gap.matrix <- function( na.bridge = FALSE, ... ) { - tasuki_gap.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + tasuki_gap.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases tasuki_gap +#' +#' @export +tasuki_gap.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + tasuki_gap.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLTASUKIGAP_lookback <- tasukiGap_lookback <- tasuki_gap_lookback <- function( x, @@ -186,7 +207,7 @@ tasuki_gap.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ tasuki_gap.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLTHRUSTING.R b/R/ta_CDLTHRUSTING.R index e724fe13a..66401b334 100644 --- a/R/ta_CDLTHRUSTING.R +++ b/R/ta_CDLTHRUSTING.R @@ -70,35 +70,33 @@ thrusting.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLTHRUSTING, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLTHRUSTING, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLTHRUSTING" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -114,7 +112,7 @@ thrusting.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( thrusting.default( x = x, cols = cols, @@ -134,14 +132,37 @@ thrusting.matrix <- function( na.bridge = FALSE, ... ) { - thrusting.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + thrusting.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases thrusting +#' +#' @export +thrusting.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + thrusting.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLTHRUSTING_lookback <- thrusting_lookback <- function( x, @@ -179,7 +200,7 @@ thrusting.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -237,7 +258,7 @@ thrusting.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLTRISTAR.R b/R/ta_CDLTRISTAR.R index 46d99997a..61f313998 100644 --- a/R/ta_CDLTRISTAR.R +++ b/R/ta_CDLTRISTAR.R @@ -70,35 +70,33 @@ tristar.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLTRISTAR, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLTRISTAR, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLTRISTAR" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -114,7 +112,7 @@ tristar.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( tristar.default( x = x, cols = cols, @@ -134,14 +132,37 @@ tristar.matrix <- function( na.bridge = FALSE, ... ) { - tristar.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + tristar.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases tristar +#' +#' @export +tristar.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + tristar.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLTRISTAR_lookback <- tristar_lookback <- function( x, @@ -179,7 +200,7 @@ tristar.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -237,7 +258,7 @@ tristar.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLUNIQUE3RIVER.R b/R/ta_CDLUNIQUE3RIVER.R index 19c84bbe8..a1bae95d2 100644 --- a/R/ta_CDLUNIQUE3RIVER.R +++ b/R/ta_CDLUNIQUE3RIVER.R @@ -77,35 +77,33 @@ unique_3_river.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLUNIQUE3RIVER, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLUNIQUE3RIVER, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLUNIQUE3RIVER" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ unique_3_river.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( unique_3_river.default( x = x, cols = cols, @@ -141,14 +139,37 @@ unique_3_river.matrix <- function( na.bridge = FALSE, ... ) { - unique_3_river.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + unique_3_river.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases unique_3_river +#' +#' @export +unique_3_river.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + unique_3_river.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLUNIQUE3RIVER_lookback <- unique3River_lookback <- unique_3_river_lookback <- function( x, @@ -186,7 +207,7 @@ unique_3_river.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ unique_3_river.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLUPSIDEGAP2CROWS.R b/R/ta_CDLUPSIDEGAP2CROWS.R index 0f4530ec1..c06185d1c 100644 --- a/R/ta_CDLUPSIDEGAP2CROWS.R +++ b/R/ta_CDLUPSIDEGAP2CROWS.R @@ -77,35 +77,33 @@ upside_gap_2_crows.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLUPSIDEGAP2CROWS, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLUPSIDEGAP2CROWS, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLUPSIDEGAP2CROWS" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ upside_gap_2_crows.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( upside_gap_2_crows.default( x = x, cols = cols, @@ -141,14 +139,37 @@ upside_gap_2_crows.matrix <- function( na.bridge = FALSE, ... ) { - upside_gap_2_crows.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + upside_gap_2_crows.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases upside_gap_2_crows +#' +#' @export +upside_gap_2_crows.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + upside_gap_2_crows.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLUPSIDEGAP2CROWS_lookback <- upsideGap2Crows_lookback <- upside_gap_2_crows_lookback <- function( x, @@ -186,7 +207,7 @@ upside_gap_2_crows.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ upside_gap_2_crows.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CDLXSIDEGAP3METHODS.R b/R/ta_CDLXSIDEGAP3METHODS.R index 50b926a4a..f4dad065a 100644 --- a/R/ta_CDLXSIDEGAP3METHODS.R +++ b/R/ta_CDLXSIDEGAP3METHODS.R @@ -77,35 +77,33 @@ xside_gap_3_methods.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + high + low + close, - data = x, + x = x, + formula.default = ~ open + high + low + close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame - x <- as.matrix( - .Call( - C_impl_ta_CDLXSIDEGAP3METHODS, - constructed_series[[1]], - constructed_series[[2]], - constructed_series[[3]], - constructed_series[[4]], - normalize, - as.logical(na.bridge) - ) + x <- .Call( + C_impl_ta_CDLXSIDEGAP3METHODS, + constructed_series[[1]], + constructed_series[[2]], + constructed_series[[3]], + constructed_series[[4]], + normalize, + as.logical(na.bridge) ) ## add column name colnames(x) <- "CDLXSIDEGAP3METHODS" ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +119,7 @@ xside_gap_3_methods.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( xside_gap_3_methods.default( x = x, cols = cols, @@ -141,14 +139,37 @@ xside_gap_3_methods.matrix <- function( na.bridge = FALSE, ... ) { - xside_gap_3_methods.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + xside_gap_3_methods.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases xside_gap_3_methods +#' +#' @export +xside_gap_3_methods.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + xside_gap_3_methods.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } + #' @usage NULL CDLXSIDEGAP3METHODS_lookback <- xsideGap3Methods_lookback <- xside_gap_3_methods_lookback <- function( x, @@ -186,7 +207,7 @@ xside_gap_3_methods.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) @@ -244,7 +265,7 @@ xside_gap_3_methods.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + high + low + close, + formula.default = ~ open + high + low + close, ... ) diff --git a/R/ta_CMO.R b/R/ta_CMO.R index 87a726285..f60ef6e57 100644 --- a/R/ta_CMO.R +++ b/R/ta_CMO.R @@ -58,15 +58,15 @@ chande_momentum_oscillator.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -78,7 +78,7 @@ chande_momentum_oscillator.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -95,7 +95,7 @@ chande_momentum_oscillator.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( chande_momentum_oscillator.default( x = x, cols = cols, @@ -117,12 +117,36 @@ chande_momentum_oscillator.matrix <- function( na.bridge = FALSE, ... ) { - chande_momentum_oscillator.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + chande_momentum_oscillator.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases chande_momentum_oscillator +#' +#' @export +chande_momentum_oscillator.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + chande_momentum_oscillator.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -206,7 +230,7 @@ chande_momentum_oscillator.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -313,7 +337,7 @@ chande_momentum_oscillator.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_DEMA.R b/R/ta_DEMA.R index 80ae501f6..21625eb87 100644 --- a/R/ta_DEMA.R +++ b/R/ta_DEMA.R @@ -84,15 +84,15 @@ double_exponential_moving_average.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula.default = ~close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -104,7 +104,7 @@ double_exponential_moving_average.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +121,7 @@ double_exponential_moving_average.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( double_exponential_moving_average.default( x = x, cols = cols, @@ -143,15 +143,40 @@ double_exponential_moving_average.matrix <- function( na.bridge = FALSE, ... ) { - double_exponential_moving_average.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + double_exponential_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } +#' @usage NULL +#' @aliases double_exponential_moving_average +#' +#' @export +double_exponential_moving_average.xts <- function( + x, + cols, + timePeriod = 30, + na.bridge = FALSE, + ... +) { + as.xts( + double_exponential_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + + #' @usage NULL #' @aliases double_exponential_moving_average #' @@ -228,7 +253,7 @@ double_exponential_moving_average.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -297,7 +322,7 @@ double_exponential_moving_average.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_DX.R b/R/ta_DX.R index 4670c97f5..cc8f22a37 100644 --- a/R/ta_DX.R +++ b/R/ta_DX.R @@ -58,15 +58,15 @@ directional_movement_index.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -80,7 +80,7 @@ directional_movement_index.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -97,7 +97,7 @@ directional_movement_index.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( directional_movement_index.default( x = x, cols = cols, @@ -119,12 +119,36 @@ directional_movement_index.matrix <- function( na.bridge = FALSE, ... ) { - directional_movement_index.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + directional_movement_index.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases directional_movement_index +#' +#' @export +directional_movement_index.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + directional_movement_index.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -171,7 +195,7 @@ directional_movement_index.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) @@ -273,7 +297,7 @@ directional_movement_index.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) diff --git a/R/ta_EMA.R b/R/ta_EMA.R index 6ace188d0..321d02ed0 100644 --- a/R/ta_EMA.R +++ b/R/ta_EMA.R @@ -84,15 +84,15 @@ exponential_moving_average.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula.default = ~close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -104,7 +104,7 @@ exponential_moving_average.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +121,7 @@ exponential_moving_average.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( exponential_moving_average.default( x = x, cols = cols, @@ -143,15 +143,40 @@ exponential_moving_average.matrix <- function( na.bridge = FALSE, ... ) { - exponential_moving_average.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + exponential_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } +#' @usage NULL +#' @aliases exponential_moving_average +#' +#' @export +exponential_moving_average.xts <- function( + x, + cols, + timePeriod = 30, + na.bridge = FALSE, + ... +) { + as.xts( + exponential_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + + #' @usage NULL #' @aliases exponential_moving_average #' @@ -228,7 +253,7 @@ exponential_moving_average.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -297,7 +322,7 @@ exponential_moving_average.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_HT_DCPERIOD.R b/R/ta_HT_DCPERIOD.R index 6d408ee10..3d0476927 100644 --- a/R/ta_HT_DCPERIOD.R +++ b/R/ta_HT_DCPERIOD.R @@ -56,15 +56,15 @@ dominant_cycle_period.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -75,7 +75,7 @@ dominant_cycle_period.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -91,7 +91,7 @@ dominant_cycle_period.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( dominant_cycle_period.default( x = x, cols = cols, @@ -111,11 +111,33 @@ dominant_cycle_period.matrix <- function( na.bridge = FALSE, ... ) { - dominant_cycle_period.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + dominant_cycle_period.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases dominant_cycle_period +#' +#' @export +dominant_cycle_period.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + dominant_cycle_period.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } @@ -192,7 +214,7 @@ dominant_cycle_period.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -292,7 +314,7 @@ dominant_cycle_period.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_HT_DCPHASE.R b/R/ta_HT_DCPHASE.R index b4bb51e34..fc1ab908b 100644 --- a/R/ta_HT_DCPHASE.R +++ b/R/ta_HT_DCPHASE.R @@ -56,15 +56,15 @@ dominant_cycle_phase.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -75,7 +75,7 @@ dominant_cycle_phase.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -91,7 +91,7 @@ dominant_cycle_phase.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( dominant_cycle_phase.default( x = x, cols = cols, @@ -111,11 +111,33 @@ dominant_cycle_phase.matrix <- function( na.bridge = FALSE, ... ) { - dominant_cycle_phase.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + dominant_cycle_phase.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases dominant_cycle_phase +#' +#' @export +dominant_cycle_phase.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + dominant_cycle_phase.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } @@ -192,7 +214,7 @@ dominant_cycle_phase.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -292,7 +314,7 @@ dominant_cycle_phase.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_HT_PHASOR.R b/R/ta_HT_PHASOR.R index 3351345ca..d10285866 100644 --- a/R/ta_HT_PHASOR.R +++ b/R/ta_HT_PHASOR.R @@ -56,15 +56,15 @@ phasor_components.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -75,7 +75,7 @@ phasor_components.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -91,7 +91,7 @@ phasor_components.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( phasor_components.default( x = x, cols = cols, @@ -111,11 +111,33 @@ phasor_components.matrix <- function( na.bridge = FALSE, ... ) { - phasor_components.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + phasor_components.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases phasor_components +#' +#' @export +phasor_components.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + phasor_components.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } @@ -192,7 +214,7 @@ phasor_components.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -300,7 +322,7 @@ phasor_components.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_HT_SINE.R b/R/ta_HT_SINE.R index 75c12931a..5a4120cac 100644 --- a/R/ta_HT_SINE.R +++ b/R/ta_HT_SINE.R @@ -56,15 +56,15 @@ sine_wave.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -75,7 +75,7 @@ sine_wave.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -91,7 +91,7 @@ sine_wave.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( sine_wave.default( x = x, cols = cols, @@ -111,11 +111,33 @@ sine_wave.matrix <- function( na.bridge = FALSE, ... ) { - sine_wave.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + sine_wave.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases sine_wave +#' +#' @export +sine_wave.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + sine_wave.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } @@ -192,7 +214,7 @@ sine_wave.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -298,7 +320,7 @@ sine_wave.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_HT_TRENDLINE.R b/R/ta_HT_TRENDLINE.R index 4d3c6e1fa..e1b1df2f9 100644 --- a/R/ta_HT_TRENDLINE.R +++ b/R/ta_HT_TRENDLINE.R @@ -49,15 +49,15 @@ trendline.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -68,7 +68,7 @@ trendline.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -84,7 +84,7 @@ trendline.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( trendline.default( x = x, cols = cols, @@ -104,11 +104,33 @@ trendline.matrix <- function( na.bridge = FALSE, ... ) { - trendline.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + trendline.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases trendline +#' +#' @export +trendline.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + trendline.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } @@ -184,7 +206,7 @@ trendline.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -253,7 +275,7 @@ trendline.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_HT_TRENDMODE.R b/R/ta_HT_TRENDMODE.R index e9545a78c..d18a90b72 100644 --- a/R/ta_HT_TRENDMODE.R +++ b/R/ta_HT_TRENDMODE.R @@ -56,15 +56,15 @@ trend_cycle_mode.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -75,7 +75,7 @@ trend_cycle_mode.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -91,7 +91,7 @@ trend_cycle_mode.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( trend_cycle_mode.default( x = x, cols = cols, @@ -111,11 +111,33 @@ trend_cycle_mode.matrix <- function( na.bridge = FALSE, ... ) { - trend_cycle_mode.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + trend_cycle_mode.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases trend_cycle_mode +#' +#' @export +trend_cycle_mode.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + trend_cycle_mode.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } @@ -192,7 +214,7 @@ trend_cycle_mode.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -291,7 +313,7 @@ trend_cycle_mode.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_IMI.R b/R/ta_IMI.R index 255b3158a..2578261b4 100644 --- a/R/ta_IMI.R +++ b/R/ta_IMI.R @@ -58,15 +58,15 @@ intraday_movement_index.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ open + close, - data = x, + x = x, + formula = cols, + formula.default = ~ open + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -79,7 +79,7 @@ intraday_movement_index.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -96,7 +96,7 @@ intraday_movement_index.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( intraday_movement_index.default( x = x, cols = cols, @@ -118,12 +118,36 @@ intraday_movement_index.matrix <- function( na.bridge = FALSE, ... ) { - intraday_movement_index.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + intraday_movement_index.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases intraday_movement_index +#' +#' @export +intraday_movement_index.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + intraday_movement_index.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -170,7 +194,7 @@ intraday_movement_index.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + close, + formula.default = ~ open + close, ... ) @@ -268,7 +292,7 @@ intraday_movement_index.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ open + close, + formula.default = ~ open + close, ... ) diff --git a/R/ta_KAMA.R b/R/ta_KAMA.R index 8b11760b4..8aefd482d 100644 --- a/R/ta_KAMA.R +++ b/R/ta_KAMA.R @@ -84,15 +84,15 @@ kaufman_adaptive_moving_average.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula.default = ~close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -104,7 +104,7 @@ kaufman_adaptive_moving_average.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +121,7 @@ kaufman_adaptive_moving_average.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( kaufman_adaptive_moving_average.default( x = x, cols = cols, @@ -143,15 +143,40 @@ kaufman_adaptive_moving_average.matrix <- function( na.bridge = FALSE, ... ) { - kaufman_adaptive_moving_average.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + kaufman_adaptive_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } +#' @usage NULL +#' @aliases kaufman_adaptive_moving_average +#' +#' @export +kaufman_adaptive_moving_average.xts <- function( + x, + cols, + timePeriod = 30, + na.bridge = FALSE, + ... +) { + as.xts( + kaufman_adaptive_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + + #' @usage NULL #' @aliases kaufman_adaptive_moving_average #' @@ -228,7 +253,7 @@ kaufman_adaptive_moving_average.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -297,7 +322,7 @@ kaufman_adaptive_moving_average.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_MACD.R b/R/ta_MACD.R index de98ff7d3..78f00b070 100644 --- a/R/ta_MACD.R +++ b/R/ta_MACD.R @@ -64,15 +64,15 @@ moving_average_convergence_divergence.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -86,7 +86,7 @@ moving_average_convergence_divergence.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -105,7 +105,7 @@ moving_average_convergence_divergence.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( moving_average_convergence_divergence.default( x = x, cols = cols, @@ -131,14 +131,42 @@ moving_average_convergence_divergence.matrix <- function( na.bridge = FALSE, ... ) { - moving_average_convergence_divergence.default( - x = x, - cols = cols, - fastPeriod = fastPeriod, - slowPeriod = slowPeriod, - signalPeriod = signalPeriod, - na.bridge = na.bridge, - ... + as.matrix( + moving_average_convergence_divergence.default( + x = x, + cols = cols, + fastPeriod = fastPeriod, + slowPeriod = slowPeriod, + signalPeriod = signalPeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases moving_average_convergence_divergence +#' +#' @export +moving_average_convergence_divergence.xts <- function( + x, + cols, + fastPeriod = 12, + slowPeriod = 26, + signalPeriod = 9, + na.bridge = FALSE, + ... +) { + as.xts( + moving_average_convergence_divergence.default( + x = x, + cols = cols, + fastPeriod = fastPeriod, + slowPeriod = slowPeriod, + signalPeriod = signalPeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -230,7 +258,7 @@ moving_average_convergence_divergence.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -365,7 +393,7 @@ moving_average_convergence_divergence.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_MACDEXT.R b/R/ta_MACDEXT.R index 0ff8884b5..8a9e7e8e3 100644 --- a/R/ta_MACDEXT.R +++ b/R/ta_MACDEXT.R @@ -73,15 +73,15 @@ extended_moving_average_convergence_divergence.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -98,7 +98,7 @@ extended_moving_average_convergence_divergence.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -120,7 +120,7 @@ extended_moving_average_convergence_divergence.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( extended_moving_average_convergence_divergence.default( x = x, cols = cols, @@ -152,17 +152,51 @@ extended_moving_average_convergence_divergence.matrix <- function( na.bridge = FALSE, ... ) { - extended_moving_average_convergence_divergence.default( - x = x, - cols = cols, - fastPeriod = fastPeriod, - fastMa = fastMa, - slowPeriod = slowPeriod, - slowMa = slowMa, - signalPeriod = signalPeriod, - signalMa = signalMa, - na.bridge = na.bridge, - ... + as.matrix( + extended_moving_average_convergence_divergence.default( + x = x, + cols = cols, + fastPeriod = fastPeriod, + fastMa = fastMa, + slowPeriod = slowPeriod, + slowMa = slowMa, + signalPeriod = signalPeriod, + signalMa = signalMa, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases extended_moving_average_convergence_divergence +#' +#' @export +extended_moving_average_convergence_divergence.xts <- function( + x, + cols, + fastPeriod = 12, + fastMa = 0, + slowPeriod = 26, + slowMa = 0, + signalPeriod = 9, + signalMa = 0, + na.bridge = FALSE, + ... +) { + as.xts( + extended_moving_average_convergence_divergence.default( + x = x, + cols = cols, + fastPeriod = fastPeriod, + fastMa = fastMa, + slowPeriod = slowPeriod, + slowMa = slowMa, + signalPeriod = signalPeriod, + signalMa = signalMa, + na.bridge = na.bridge, + ... + ) ) } @@ -269,7 +303,7 @@ extended_moving_average_convergence_divergence.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -410,7 +444,7 @@ extended_moving_average_convergence_divergence.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_MACDFIX.R b/R/ta_MACDFIX.R index 17eb1cc3f..d0c1a4d76 100644 --- a/R/ta_MACDFIX.R +++ b/R/ta_MACDFIX.R @@ -58,15 +58,15 @@ fixed_moving_average_convergence_divergence.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -78,7 +78,7 @@ fixed_moving_average_convergence_divergence.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -95,7 +95,7 @@ fixed_moving_average_convergence_divergence.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( fixed_moving_average_convergence_divergence.default( x = x, cols = cols, @@ -117,12 +117,36 @@ fixed_moving_average_convergence_divergence.matrix <- function( na.bridge = FALSE, ... ) { - fixed_moving_average_convergence_divergence.default( - x = x, - cols = cols, - signalPeriod = signalPeriod, - na.bridge = na.bridge, - ... + as.matrix( + fixed_moving_average_convergence_divergence.default( + x = x, + cols = cols, + signalPeriod = signalPeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases fixed_moving_average_convergence_divergence +#' +#' @export +fixed_moving_average_convergence_divergence.xts <- function( + x, + cols, + signalPeriod = 9, + na.bridge = FALSE, + ... +) { + as.xts( + fixed_moving_average_convergence_divergence.default( + x = x, + cols = cols, + signalPeriod = signalPeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -204,7 +228,7 @@ fixed_moving_average_convergence_divergence.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -333,7 +357,7 @@ fixed_moving_average_convergence_divergence.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_MAMA.R b/R/ta_MAMA.R index a7105b918..69e260b47 100644 --- a/R/ta_MAMA.R +++ b/R/ta_MAMA.R @@ -99,15 +99,15 @@ mesa_adaptive_moving_average.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula.default = ~close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -120,7 +120,7 @@ mesa_adaptive_moving_average.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -139,7 +139,7 @@ mesa_adaptive_moving_average.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( mesa_adaptive_moving_average.default( x = x, cols = cols, @@ -165,17 +165,46 @@ mesa_adaptive_moving_average.matrix <- function( na.bridge = FALSE, ... ) { - mesa_adaptive_moving_average.default( - x = x, - cols = cols, - timePeriod = timePeriod, - fastLimit = fastLimit, - slowLimit = slowLimit, - na.bridge = na.bridge, - ... + as.matrix( + mesa_adaptive_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + fastLimit = fastLimit, + slowLimit = slowLimit, + na.bridge = na.bridge, + ... + ) ) } +#' @usage NULL +#' @aliases mesa_adaptive_moving_average +#' +#' @export +mesa_adaptive_moving_average.xts <- function( + x, + cols, + timePeriod = 30, + fastLimit = 0.5, + slowLimit = 0.05, + na.bridge = FALSE, + ... +) { + as.xts( + mesa_adaptive_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + fastLimit = fastLimit, + slowLimit = slowLimit, + na.bridge = na.bridge, + ... + ) + ) +} + + #' @usage NULL #' @aliases mesa_adaptive_moving_average #' @@ -260,7 +289,7 @@ mesa_adaptive_moving_average.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -333,7 +362,7 @@ mesa_adaptive_moving_average.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_MAVP.R b/R/ta_MAVP.R index cc6135e12..5df31be42 100644 --- a/R/ta_MAVP.R +++ b/R/ta_MAVP.R @@ -69,15 +69,15 @@ variable_moving_average_period.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -92,7 +92,7 @@ variable_moving_average_period.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -112,7 +112,7 @@ variable_moving_average_period.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( variable_moving_average_period.default( x = x, cols = cols, @@ -140,15 +140,45 @@ variable_moving_average_period.matrix <- function( na.bridge = FALSE, ... ) { - variable_moving_average_period.default( - x = x, - cols = cols, - periods = periods, - minimumPeriod = minimumPeriod, - maximumPeriod = maximumPeriod, - maType = maType, - na.bridge = na.bridge, - ... + as.matrix( + variable_moving_average_period.default( + x = x, + cols = cols, + periods = periods, + minimumPeriod = minimumPeriod, + maximumPeriod = maximumPeriod, + maType = maType, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases variable_moving_average_period +#' +#' @export +variable_moving_average_period.xts <- function( + x, + cols, + periods, + minimumPeriod = 2, + maximumPeriod = 30, + maType = 0, + na.bridge = FALSE, + ... +) { + as.xts( + variable_moving_average_period.default( + x = x, + cols = cols, + periods = periods, + minimumPeriod = minimumPeriod, + maximumPeriod = maximumPeriod, + maType = maType, + na.bridge = na.bridge, + ... + ) ) } @@ -243,7 +273,7 @@ variable_moving_average_period.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -333,7 +363,7 @@ variable_moving_average_period.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_MEDPRICE.R b/R/ta_MEDPRICE.R index a81bd341b..e8760cb69 100644 --- a/R/ta_MEDPRICE.R +++ b/R/ta_MEDPRICE.R @@ -56,15 +56,15 @@ median_price.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -76,7 +76,7 @@ median_price.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -92,7 +92,7 @@ median_price.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( median_price.default( x = x, cols = cols, @@ -112,11 +112,33 @@ median_price.matrix <- function( na.bridge = FALSE, ... ) { - median_price.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + median_price.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases median_price +#' +#' @export +median_price.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + median_price.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } diff --git a/R/ta_MFI.R b/R/ta_MFI.R index d3262386d..31c3d455d 100644 --- a/R/ta_MFI.R +++ b/R/ta_MFI.R @@ -58,15 +58,15 @@ money_flow_index.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close + volume, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close + volume, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -81,7 +81,7 @@ money_flow_index.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -98,7 +98,7 @@ money_flow_index.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( money_flow_index.default( x = x, cols = cols, @@ -120,12 +120,36 @@ money_flow_index.matrix <- function( na.bridge = FALSE, ... ) { - money_flow_index.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + money_flow_index.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases money_flow_index +#' +#' @export +money_flow_index.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + money_flow_index.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -174,7 +198,7 @@ money_flow_index.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close + volume, + formula.default = ~ high + low + close + volume, ... ) @@ -272,7 +296,7 @@ money_flow_index.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close + volume, + formula.default = ~ high + low + close + volume, ... ) diff --git a/R/ta_MIDPOINT.R b/R/ta_MIDPOINT.R index 12e43cce5..0f66b6efb 100644 --- a/R/ta_MIDPOINT.R +++ b/R/ta_MIDPOINT.R @@ -58,15 +58,15 @@ midpoint_period.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -78,7 +78,7 @@ midpoint_period.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -95,7 +95,7 @@ midpoint_period.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( midpoint_period.default( x = x, cols = cols, @@ -117,12 +117,36 @@ midpoint_period.matrix <- function( na.bridge = FALSE, ... ) { - midpoint_period.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + midpoint_period.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases midpoint_period +#' +#' @export +midpoint_period.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + midpoint_period.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -203,7 +227,7 @@ midpoint_period.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -282,7 +306,7 @@ midpoint_period.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_MIDPRICE.R b/R/ta_MIDPRICE.R index 9905c4812..7274b60cc 100644 --- a/R/ta_MIDPRICE.R +++ b/R/ta_MIDPRICE.R @@ -58,15 +58,15 @@ midpoint_price.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -79,7 +79,7 @@ midpoint_price.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -96,7 +96,7 @@ midpoint_price.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( midpoint_price.default( x = x, cols = cols, @@ -118,12 +118,36 @@ midpoint_price.matrix <- function( na.bridge = FALSE, ... ) { - midpoint_price.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + midpoint_price.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases midpoint_price +#' +#' @export +midpoint_price.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + midpoint_price.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -169,7 +193,7 @@ midpoint_price.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low, + formula.default = ~ high + low, ... ) @@ -248,7 +272,7 @@ midpoint_price.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low, + formula.default = ~ high + low, ... ) diff --git a/R/ta_MINUS_DI.R b/R/ta_MINUS_DI.R index 2499c2134..9025487f0 100644 --- a/R/ta_MINUS_DI.R +++ b/R/ta_MINUS_DI.R @@ -58,15 +58,15 @@ minus_directional_indicator.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -80,7 +80,7 @@ minus_directional_indicator.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -97,7 +97,7 @@ minus_directional_indicator.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( minus_directional_indicator.default( x = x, cols = cols, @@ -119,12 +119,36 @@ minus_directional_indicator.matrix <- function( na.bridge = FALSE, ... ) { - minus_directional_indicator.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + minus_directional_indicator.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases minus_directional_indicator +#' +#' @export +minus_directional_indicator.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + minus_directional_indicator.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -171,7 +195,7 @@ minus_directional_indicator.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) @@ -264,7 +288,7 @@ minus_directional_indicator.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) diff --git a/R/ta_MINUS_DM.R b/R/ta_MINUS_DM.R index b31275164..917c0ada6 100644 --- a/R/ta_MINUS_DM.R +++ b/R/ta_MINUS_DM.R @@ -58,15 +58,15 @@ minus_directional_movement.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -79,7 +79,7 @@ minus_directional_movement.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -96,7 +96,7 @@ minus_directional_movement.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( minus_directional_movement.default( x = x, cols = cols, @@ -118,12 +118,36 @@ minus_directional_movement.matrix <- function( na.bridge = FALSE, ... ) { - minus_directional_movement.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + minus_directional_movement.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases minus_directional_movement +#' +#' @export +minus_directional_movement.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + minus_directional_movement.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -170,7 +194,7 @@ minus_directional_movement.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low, + formula.default = ~ high + low, ... ) @@ -263,7 +287,7 @@ minus_directional_movement.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low, + formula.default = ~ high + low, ... ) diff --git a/R/ta_MOM.R b/R/ta_MOM.R index 0b55a4ec5..189b55f7b 100644 --- a/R/ta_MOM.R +++ b/R/ta_MOM.R @@ -51,15 +51,15 @@ momentum.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -71,7 +71,7 @@ momentum.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -88,7 +88,7 @@ momentum.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( momentum.default( x = x, cols = cols, @@ -110,12 +110,36 @@ momentum.matrix <- function( na.bridge = FALSE, ... ) { - momentum.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + momentum.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases momentum +#' +#' @export +momentum.xts <- function( + x, + cols, + timePeriod = 10, + na.bridge = FALSE, + ... +) { + as.xts( + momentum.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -197,7 +221,7 @@ momentum.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -293,7 +317,7 @@ momentum.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_NATR.R b/R/ta_NATR.R index 715281eb9..389096501 100644 --- a/R/ta_NATR.R +++ b/R/ta_NATR.R @@ -58,15 +58,15 @@ normalized_average_true_range.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -80,7 +80,7 @@ normalized_average_true_range.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -97,7 +97,7 @@ normalized_average_true_range.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( normalized_average_true_range.default( x = x, cols = cols, @@ -119,12 +119,36 @@ normalized_average_true_range.matrix <- function( na.bridge = FALSE, ... ) { - normalized_average_true_range.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + normalized_average_true_range.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases normalized_average_true_range +#' +#' @export +normalized_average_true_range.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + normalized_average_true_range.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -171,7 +195,7 @@ normalized_average_true_range.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) @@ -263,7 +287,7 @@ normalized_average_true_range.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) diff --git a/R/ta_OBV.R b/R/ta_OBV.R index a821dc4f2..faea3c87e 100644 --- a/R/ta_OBV.R +++ b/R/ta_OBV.R @@ -56,15 +56,15 @@ on_balance_volume.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ close + volume, - data = x, + x = x, + formula = cols, + formula.default = ~ close + volume, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -76,7 +76,7 @@ on_balance_volume.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -92,7 +92,7 @@ on_balance_volume.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( on_balance_volume.default( x = x, cols = cols, @@ -112,11 +112,33 @@ on_balance_volume.matrix <- function( na.bridge = FALSE, ... ) { - on_balance_volume.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + on_balance_volume.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases on_balance_volume +#' +#' @export +on_balance_volume.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + on_balance_volume.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } @@ -160,7 +182,7 @@ on_balance_volume.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ close + volume, + formula.default = ~ close + volume, ... ) @@ -248,7 +270,7 @@ on_balance_volume.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ close + volume, + formula.default = ~ close + volume, ... ) diff --git a/R/ta_PLUS_DI.R b/R/ta_PLUS_DI.R index f5ac7c5c4..64f1749e8 100644 --- a/R/ta_PLUS_DI.R +++ b/R/ta_PLUS_DI.R @@ -58,15 +58,15 @@ plus_directional_indicator.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -80,7 +80,7 @@ plus_directional_indicator.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -97,7 +97,7 @@ plus_directional_indicator.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( plus_directional_indicator.default( x = x, cols = cols, @@ -119,12 +119,36 @@ plus_directional_indicator.matrix <- function( na.bridge = FALSE, ... ) { - plus_directional_indicator.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + plus_directional_indicator.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases plus_directional_indicator +#' +#' @export +plus_directional_indicator.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + plus_directional_indicator.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -171,7 +195,7 @@ plus_directional_indicator.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) @@ -264,7 +288,7 @@ plus_directional_indicator.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) diff --git a/R/ta_PLUS_DM.R b/R/ta_PLUS_DM.R index c3bddf9a9..2eb9d6550 100644 --- a/R/ta_PLUS_DM.R +++ b/R/ta_PLUS_DM.R @@ -58,15 +58,15 @@ plus_directional_movement.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -79,7 +79,7 @@ plus_directional_movement.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -96,7 +96,7 @@ plus_directional_movement.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( plus_directional_movement.default( x = x, cols = cols, @@ -118,12 +118,36 @@ plus_directional_movement.matrix <- function( na.bridge = FALSE, ... ) { - plus_directional_movement.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + plus_directional_movement.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases plus_directional_movement +#' +#' @export +plus_directional_movement.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + plus_directional_movement.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -170,7 +194,7 @@ plus_directional_movement.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low, + formula.default = ~ high + low, ... ) @@ -263,7 +287,7 @@ plus_directional_movement.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low, + formula.default = ~ high + low, ... ) diff --git a/R/ta_PPO.R b/R/ta_PPO.R index 3d1114877..afdc5815d 100644 --- a/R/ta_PPO.R +++ b/R/ta_PPO.R @@ -64,15 +64,15 @@ percentage_price_oscillator.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -86,7 +86,7 @@ percentage_price_oscillator.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -105,7 +105,7 @@ percentage_price_oscillator.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( percentage_price_oscillator.default( x = x, cols = cols, @@ -131,14 +131,42 @@ percentage_price_oscillator.matrix <- function( na.bridge = FALSE, ... ) { - percentage_price_oscillator.default( - x = x, - cols = cols, - fastPeriod = fastPeriod, - slowPeriod = slowPeriod, - maType = maType, - na.bridge = na.bridge, - ... + as.matrix( + percentage_price_oscillator.default( + x = x, + cols = cols, + fastPeriod = fastPeriod, + slowPeriod = slowPeriod, + maType = maType, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases percentage_price_oscillator +#' +#' @export +percentage_price_oscillator.xts <- function( + x, + cols, + fastPeriod = 12, + slowPeriod = 26, + maType = 1, + na.bridge = FALSE, + ... +) { + as.xts( + percentage_price_oscillator.default( + x = x, + cols = cols, + fastPeriod = fastPeriod, + slowPeriod = slowPeriod, + maType = maType, + na.bridge = na.bridge, + ... + ) ) } @@ -230,7 +258,7 @@ percentage_price_oscillator.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -331,7 +359,7 @@ percentage_price_oscillator.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_ROCR.R b/R/ta_ROCR.R index 3fc951278..c2f5579f0 100644 --- a/R/ta_ROCR.R +++ b/R/ta_ROCR.R @@ -58,15 +58,15 @@ ratio_of_change.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -78,7 +78,7 @@ ratio_of_change.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -95,7 +95,7 @@ ratio_of_change.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( ratio_of_change.default( x = x, cols = cols, @@ -117,12 +117,36 @@ ratio_of_change.matrix <- function( na.bridge = FALSE, ... ) { - ratio_of_change.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + ratio_of_change.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases ratio_of_change +#' +#' @export +ratio_of_change.xts <- function( + x, + cols, + timePeriod = 10, + na.bridge = FALSE, + ... +) { + as.xts( + ratio_of_change.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -204,7 +228,7 @@ ratio_of_change.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -304,7 +328,7 @@ ratio_of_change.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_RSI.R b/R/ta_RSI.R index 92a06e855..4e2163266 100644 --- a/R/ta_RSI.R +++ b/R/ta_RSI.R @@ -58,15 +58,15 @@ relative_strength_index.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -78,7 +78,7 @@ relative_strength_index.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -95,7 +95,7 @@ relative_strength_index.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( relative_strength_index.default( x = x, cols = cols, @@ -117,12 +117,36 @@ relative_strength_index.matrix <- function( na.bridge = FALSE, ... ) { - relative_strength_index.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + relative_strength_index.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases relative_strength_index +#' +#' @export +relative_strength_index.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + relative_strength_index.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -206,7 +230,7 @@ relative_strength_index.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -308,7 +332,7 @@ relative_strength_index.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_SAR.R b/R/ta_SAR.R index 7c39d7922..e3a2045f1 100644 --- a/R/ta_SAR.R +++ b/R/ta_SAR.R @@ -61,15 +61,15 @@ parabolic_stop_and_reverse.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -83,7 +83,7 @@ parabolic_stop_and_reverse.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -101,7 +101,7 @@ parabolic_stop_and_reverse.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( parabolic_stop_and_reverse.default( x = x, cols = cols, @@ -125,13 +125,39 @@ parabolic_stop_and_reverse.matrix <- function( na.bridge = FALSE, ... ) { - parabolic_stop_and_reverse.default( - x = x, - cols = cols, - accelerationFactor = accelerationFactor, - afMaximum = afMaximum, - na.bridge = na.bridge, - ... + as.matrix( + parabolic_stop_and_reverse.default( + x = x, + cols = cols, + accelerationFactor = accelerationFactor, + afMaximum = afMaximum, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases parabolic_stop_and_reverse +#' +#' @export +parabolic_stop_and_reverse.xts <- function( + x, + cols, + accelerationFactor = 0.02, + afMaximum = 0.2, + na.bridge = FALSE, + ... +) { + as.xts( + parabolic_stop_and_reverse.default( + x = x, + cols = cols, + accelerationFactor = accelerationFactor, + afMaximum = afMaximum, + na.bridge = na.bridge, + ... + ) ) } @@ -180,7 +206,7 @@ parabolic_stop_and_reverse.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low, + formula.default = ~ high + low, ... ) @@ -286,7 +312,7 @@ parabolic_stop_and_reverse.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low, + formula.default = ~ high + low, ... ) diff --git a/R/ta_SAREXT.R b/R/ta_SAREXT.R index 195a39fa1..a1a74a610 100644 --- a/R/ta_SAREXT.R +++ b/R/ta_SAREXT.R @@ -79,15 +79,15 @@ extended_parabolic_stop_and_reverse.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -107,7 +107,7 @@ extended_parabolic_stop_and_reverse.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -131,7 +131,7 @@ extended_parabolic_stop_and_reverse.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( extended_parabolic_stop_and_reverse.default( x = x, cols = cols, @@ -167,19 +167,57 @@ extended_parabolic_stop_and_reverse.matrix <- function( na.bridge = FALSE, ... ) { - extended_parabolic_stop_and_reverse.default( - x = x, - cols = cols, - startValue = startValue, - offsetOnReverse = offsetOnReverse, - afInitLong = afInitLong, - afLong = afLong, - afMaxLong = afMaxLong, - afInitShort = afInitShort, - afShort = afShort, - afMaxShort = afMaxShort, - na.bridge = na.bridge, - ... + as.matrix( + extended_parabolic_stop_and_reverse.default( + x = x, + cols = cols, + startValue = startValue, + offsetOnReverse = offsetOnReverse, + afInitLong = afInitLong, + afLong = afLong, + afMaxLong = afMaxLong, + afInitShort = afInitShort, + afShort = afShort, + afMaxShort = afMaxShort, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases extended_parabolic_stop_and_reverse +#' +#' @export +extended_parabolic_stop_and_reverse.xts <- function( + x, + cols, + startValue = 0, + offsetOnReverse = 0, + afInitLong = 0.02, + afLong = 0.02, + afMaxLong = 0.2, + afInitShort = 0.02, + afShort = 0.02, + afMaxShort = 0.2, + na.bridge = FALSE, + ... +) { + as.xts( + extended_parabolic_stop_and_reverse.default( + x = x, + cols = cols, + startValue = startValue, + offsetOnReverse = offsetOnReverse, + afInitLong = afInitLong, + afLong = afLong, + afMaxLong = afMaxLong, + afInitShort = afInitShort, + afShort = afShort, + afMaxShort = afMaxShort, + na.bridge = na.bridge, + ... + ) ) } @@ -246,7 +284,7 @@ extended_parabolic_stop_and_reverse.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low, + formula.default = ~ high + low, ... ) @@ -364,7 +402,7 @@ extended_parabolic_stop_and_reverse.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low, + formula.default = ~ high + low, ... ) diff --git a/R/ta_SMA.R b/R/ta_SMA.R index a62d2bc9e..8c45ccbc8 100644 --- a/R/ta_SMA.R +++ b/R/ta_SMA.R @@ -84,15 +84,15 @@ simple_moving_average.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula.default = ~close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -104,7 +104,7 @@ simple_moving_average.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +121,7 @@ simple_moving_average.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( simple_moving_average.default( x = x, cols = cols, @@ -143,15 +143,40 @@ simple_moving_average.matrix <- function( na.bridge = FALSE, ... ) { - simple_moving_average.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + simple_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } +#' @usage NULL +#' @aliases simple_moving_average +#' +#' @export +simple_moving_average.xts <- function( + x, + cols, + timePeriod = 30, + na.bridge = FALSE, + ... +) { + as.xts( + simple_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + + #' @usage NULL #' @aliases simple_moving_average #' @@ -228,7 +253,7 @@ simple_moving_average.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -297,7 +322,7 @@ simple_moving_average.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_STOCH.R b/R/ta_STOCH.R index 81303093c..c43e1d12a 100644 --- a/R/ta_STOCH.R +++ b/R/ta_STOCH.R @@ -63,15 +63,15 @@ stochastic.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -89,7 +89,7 @@ stochastic.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -110,7 +110,7 @@ stochastic.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( stochastic.default( x = x, cols = cols, @@ -140,16 +140,48 @@ stochastic.matrix <- function( na.bridge = FALSE, ... ) { - stochastic.default( - x = x, - cols = cols, - fastKPeriod = fastKPeriod, - slowKPeriod = slowKPeriod, - slowKMa = slowKMa, - slowDPeriod = slowDPeriod, - slowDMa = slowDMa, - na.bridge = na.bridge, - ... + as.matrix( + stochastic.default( + x = x, + cols = cols, + fastKPeriod = fastKPeriod, + slowKPeriod = slowKPeriod, + slowKMa = slowKMa, + slowDPeriod = slowDPeriod, + slowDMa = slowDMa, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases stochastic +#' +#' @export +stochastic.xts <- function( + x, + cols, + fastKPeriod = 5, + slowKPeriod = 3, + slowKMa = 0, + slowDPeriod = 3, + slowDMa = 0, + na.bridge = FALSE, + ... +) { + as.xts( + stochastic.default( + x = x, + cols = cols, + fastKPeriod = fastKPeriod, + slowKPeriod = slowKPeriod, + slowKMa = slowKMa, + slowDPeriod = slowDPeriod, + slowDMa = slowDMa, + na.bridge = na.bridge, + ... + ) ) } @@ -210,7 +242,7 @@ stochastic.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) @@ -321,7 +353,7 @@ stochastic.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) diff --git a/R/ta_STOCHF.R b/R/ta_STOCHF.R index 8b7d58b7e..cbb18bfb1 100644 --- a/R/ta_STOCHF.R +++ b/R/ta_STOCHF.R @@ -64,15 +64,15 @@ fast_stochastic.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -88,7 +88,7 @@ fast_stochastic.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -107,7 +107,7 @@ fast_stochastic.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( fast_stochastic.default( x = x, cols = cols, @@ -133,14 +133,42 @@ fast_stochastic.matrix <- function( na.bridge = FALSE, ... ) { - fast_stochastic.default( - x = x, - cols = cols, - fastKPeriod = fastKPeriod, - fastDPeriod = fastDPeriod, - fastDMa = fastDMa, - na.bridge = na.bridge, - ... + as.matrix( + fast_stochastic.default( + x = x, + cols = cols, + fastKPeriod = fastKPeriod, + fastDPeriod = fastDPeriod, + fastDMa = fastDMa, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases fast_stochastic +#' +#' @export +fast_stochastic.xts <- function( + x, + cols, + fastKPeriod = 5, + fastDPeriod = 3, + fastDMa = 0, + na.bridge = FALSE, + ... +) { + as.xts( + fast_stochastic.default( + x = x, + cols = cols, + fastKPeriod = fastKPeriod, + fastDPeriod = fastDPeriod, + fastDMa = fastDMa, + na.bridge = na.bridge, + ... + ) ) } @@ -195,7 +223,7 @@ fast_stochastic.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) @@ -300,7 +328,7 @@ fast_stochastic.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) diff --git a/R/ta_STOCHRSI.R b/R/ta_STOCHRSI.R index bfc927033..a0f0545c7 100644 --- a/R/ta_STOCHRSI.R +++ b/R/ta_STOCHRSI.R @@ -66,15 +66,15 @@ stochastic_relative_strength_index.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -89,7 +89,7 @@ stochastic_relative_strength_index.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -109,7 +109,7 @@ stochastic_relative_strength_index.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( stochastic_relative_strength_index.default( x = x, cols = cols, @@ -137,15 +137,45 @@ stochastic_relative_strength_index.matrix <- function( na.bridge = FALSE, ... ) { - stochastic_relative_strength_index.default( - x = x, - cols = cols, - timePeriod = timePeriod, - fastKPeriod = fastKPeriod, - fastDPeriod = fastDPeriod, - fastDMa = fastDMa, - na.bridge = na.bridge, - ... + as.matrix( + stochastic_relative_strength_index.default( + x = x, + cols = cols, + timePeriod = timePeriod, + fastKPeriod = fastKPeriod, + fastDPeriod = fastDPeriod, + fastDMa = fastDMa, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases stochastic_relative_strength_index +#' +#' @export +stochastic_relative_strength_index.xts <- function( + x, + cols, + timePeriod = 14, + fastKPeriod = 5, + fastDPeriod = 3, + fastDMa = 0, + na.bridge = FALSE, + ... +) { + as.xts( + stochastic_relative_strength_index.default( + x = x, + cols = cols, + timePeriod = timePeriod, + fastKPeriod = fastKPeriod, + fastDPeriod = fastDPeriod, + fastDMa = fastDMa, + na.bridge = na.bridge, + ... + ) ) } @@ -244,7 +274,7 @@ stochastic_relative_strength_index.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -350,7 +380,7 @@ stochastic_relative_strength_index.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_T3.R b/R/ta_T3.R index fe39a1a3a..1c5b4e1fd 100644 --- a/R/ta_T3.R +++ b/R/ta_T3.R @@ -91,15 +91,15 @@ t3_exponential_moving_average.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula.default = ~close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -112,7 +112,7 @@ t3_exponential_moving_average.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -130,7 +130,7 @@ t3_exponential_moving_average.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( t3_exponential_moving_average.default( x = x, cols = cols, @@ -154,16 +154,43 @@ t3_exponential_moving_average.matrix <- function( na.bridge = FALSE, ... ) { - t3_exponential_moving_average.default( - x = x, - cols = cols, - timePeriod = timePeriod, - volumeFactor = volumeFactor, - na.bridge = na.bridge, - ... + as.matrix( + t3_exponential_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + volumeFactor = volumeFactor, + na.bridge = na.bridge, + ... + ) ) } +#' @usage NULL +#' @aliases t3_exponential_moving_average +#' +#' @export +t3_exponential_moving_average.xts <- function( + x, + cols, + timePeriod = 5, + volumeFactor = 0.7, + na.bridge = FALSE, + ... +) { + as.xts( + t3_exponential_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + volumeFactor = volumeFactor, + na.bridge = na.bridge, + ... + ) + ) +} + + #' @usage NULL #' @aliases t3_exponential_moving_average #' @@ -245,7 +272,7 @@ t3_exponential_moving_average.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -316,7 +343,7 @@ t3_exponential_moving_average.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_TEMA.R b/R/ta_TEMA.R index 4ee93b851..bb291e705 100644 --- a/R/ta_TEMA.R +++ b/R/ta_TEMA.R @@ -84,15 +84,15 @@ triple_exponential_moving_average.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula.default = ~close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -104,7 +104,7 @@ triple_exponential_moving_average.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +121,7 @@ triple_exponential_moving_average.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( triple_exponential_moving_average.default( x = x, cols = cols, @@ -143,15 +143,40 @@ triple_exponential_moving_average.matrix <- function( na.bridge = FALSE, ... ) { - triple_exponential_moving_average.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + triple_exponential_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } +#' @usage NULL +#' @aliases triple_exponential_moving_average +#' +#' @export +triple_exponential_moving_average.xts <- function( + x, + cols, + timePeriod = 30, + na.bridge = FALSE, + ... +) { + as.xts( + triple_exponential_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + + #' @usage NULL #' @aliases triple_exponential_moving_average #' @@ -228,7 +253,7 @@ triple_exponential_moving_average.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -297,7 +322,7 @@ triple_exponential_moving_average.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_TRANGE.R b/R/ta_TRANGE.R index baf6750c5..02ffd07de 100644 --- a/R/ta_TRANGE.R +++ b/R/ta_TRANGE.R @@ -56,15 +56,15 @@ true_range.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -77,7 +77,7 @@ true_range.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -93,7 +93,7 @@ true_range.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( true_range.default( x = x, cols = cols, @@ -113,11 +113,33 @@ true_range.matrix <- function( na.bridge = FALSE, ... ) { - true_range.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + true_range.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases true_range +#' +#' @export +true_range.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + true_range.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } @@ -161,7 +183,7 @@ true_range.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) @@ -252,7 +274,7 @@ true_range.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) diff --git a/R/ta_TRIMA.R b/R/ta_TRIMA.R index f891f7f90..ab269cc26 100644 --- a/R/ta_TRIMA.R +++ b/R/ta_TRIMA.R @@ -84,15 +84,15 @@ triangular_moving_average.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula.default = ~close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -104,7 +104,7 @@ triangular_moving_average.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +121,7 @@ triangular_moving_average.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( triangular_moving_average.default( x = x, cols = cols, @@ -143,15 +143,40 @@ triangular_moving_average.matrix <- function( na.bridge = FALSE, ... ) { - triangular_moving_average.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + triangular_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } +#' @usage NULL +#' @aliases triangular_moving_average +#' +#' @export +triangular_moving_average.xts <- function( + x, + cols, + timePeriod = 30, + na.bridge = FALSE, + ... +) { + as.xts( + triangular_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + + #' @usage NULL #' @aliases triangular_moving_average #' @@ -228,7 +253,7 @@ triangular_moving_average.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -297,7 +322,7 @@ triangular_moving_average.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_TRIX.R b/R/ta_TRIX.R index 19c8a6b77..79ffbae67 100644 --- a/R/ta_TRIX.R +++ b/R/ta_TRIX.R @@ -58,15 +58,15 @@ triple_exponential_average.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -78,7 +78,7 @@ triple_exponential_average.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -95,7 +95,7 @@ triple_exponential_average.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( triple_exponential_average.default( x = x, cols = cols, @@ -117,12 +117,36 @@ triple_exponential_average.matrix <- function( na.bridge = FALSE, ... ) { - triple_exponential_average.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + triple_exponential_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases triple_exponential_average +#' +#' @export +triple_exponential_average.xts <- function( + x, + cols, + timePeriod = 30, + na.bridge = FALSE, + ... +) { + as.xts( + triple_exponential_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -204,7 +228,7 @@ triple_exponential_average.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -297,7 +321,7 @@ triple_exponential_average.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_TYPPRICE.R b/R/ta_TYPPRICE.R index 03bf1d156..fe52e093a 100644 --- a/R/ta_TYPPRICE.R +++ b/R/ta_TYPPRICE.R @@ -56,15 +56,15 @@ typical_price.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -77,7 +77,7 @@ typical_price.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -93,7 +93,7 @@ typical_price.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( typical_price.default( x = x, cols = cols, @@ -113,11 +113,33 @@ typical_price.matrix <- function( na.bridge = FALSE, ... ) { - typical_price.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + typical_price.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases typical_price +#' +#' @export +typical_price.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + typical_price.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } diff --git a/R/ta_ULTOSC.R b/R/ta_ULTOSC.R index 270785429..0c2055968 100644 --- a/R/ta_ULTOSC.R +++ b/R/ta_ULTOSC.R @@ -64,15 +64,15 @@ ultimate_oscillator.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -88,7 +88,7 @@ ultimate_oscillator.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -107,7 +107,7 @@ ultimate_oscillator.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( ultimate_oscillator.default( x = x, cols = cols, @@ -133,14 +133,42 @@ ultimate_oscillator.matrix <- function( na.bridge = FALSE, ... ) { - ultimate_oscillator.default( - x = x, - cols = cols, - firstPeriod = firstPeriod, - secondPeriod = secondPeriod, - thirdPeriod = thirdPeriod, - na.bridge = na.bridge, - ... + as.matrix( + ultimate_oscillator.default( + x = x, + cols = cols, + firstPeriod = firstPeriod, + secondPeriod = secondPeriod, + thirdPeriod = thirdPeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases ultimate_oscillator +#' +#' @export +ultimate_oscillator.xts <- function( + x, + cols, + firstPeriod = 7, + secondPeriod = 14, + thirdPeriod = 28, + na.bridge = FALSE, + ... +) { + as.xts( + ultimate_oscillator.default( + x = x, + cols = cols, + firstPeriod = firstPeriod, + secondPeriod = secondPeriod, + thirdPeriod = thirdPeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -195,7 +223,7 @@ ultimate_oscillator.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) @@ -303,7 +331,7 @@ ultimate_oscillator.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) diff --git a/R/ta_VOLUME.R b/R/ta_VOLUME.R index 89da85349..655f82451 100644 --- a/R/ta_VOLUME.R +++ b/R/ta_VOLUME.R @@ -58,9 +58,9 @@ trading_volume.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ volume + open + close, - data = x, + x = x, + formula.default = ~ volume + open + close, + formula = cols, ... ) @@ -203,7 +203,7 @@ trading_volume.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ volume + open + close, + formula.default = ~ volume + open + close, ... ) @@ -339,7 +339,7 @@ trading_volume.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ volume + open + close, + formula.default = ~ volume + open + close, ... ) diff --git a/R/ta_WCLPRICE.R b/R/ta_WCLPRICE.R index 22243ef6f..cb07fccc1 100644 --- a/R/ta_WCLPRICE.R +++ b/R/ta_WCLPRICE.R @@ -56,15 +56,15 @@ weighted_close_price.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -77,7 +77,7 @@ weighted_close_price.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -93,7 +93,7 @@ weighted_close_price.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( weighted_close_price.default( x = x, cols = cols, @@ -113,11 +113,33 @@ weighted_close_price.matrix <- function( na.bridge = FALSE, ... ) { - weighted_close_price.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + weighted_close_price.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases weighted_close_price +#' +#' @export +weighted_close_price.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + weighted_close_price.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } diff --git a/R/ta_WILLR.R b/R/ta_WILLR.R index 9e667108c..8fe6970e9 100644 --- a/R/ta_WILLR.R +++ b/R/ta_WILLR.R @@ -58,15 +58,15 @@ williams_oscillator.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -80,7 +80,7 @@ williams_oscillator.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -97,7 +97,7 @@ williams_oscillator.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( williams_oscillator.default( x = x, cols = cols, @@ -119,12 +119,36 @@ williams_oscillator.matrix <- function( na.bridge = FALSE, ... ) { - williams_oscillator.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + williams_oscillator.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases williams_oscillator +#' +#' @export +williams_oscillator.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + williams_oscillator.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -173,7 +197,7 @@ williams_oscillator.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) @@ -272,7 +296,7 @@ williams_oscillator.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close, + formula.default = ~ high + low + close, ... ) diff --git a/R/ta_WMA.R b/R/ta_WMA.R index 50b8d38ba..bb8899d4c 100644 --- a/R/ta_WMA.R +++ b/R/ta_WMA.R @@ -84,15 +84,15 @@ weighted_moving_average.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula.default = ~close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -104,7 +104,7 @@ weighted_moving_average.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +121,7 @@ weighted_moving_average.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( weighted_moving_average.default( x = x, cols = cols, @@ -143,15 +143,40 @@ weighted_moving_average.matrix <- function( na.bridge = FALSE, ... ) { - weighted_moving_average.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + weighted_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } +#' @usage NULL +#' @aliases weighted_moving_average +#' +#' @export +weighted_moving_average.xts <- function( + x, + cols, + timePeriod = 30, + na.bridge = FALSE, + ... +) { + as.xts( + weighted_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + + #' @usage NULL #' @aliases weighted_moving_average #' @@ -228,7 +253,7 @@ weighted_moving_average.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -297,7 +322,7 @@ weighted_moving_average.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) From e6b866ae29b53e788cc5c00576e9d34f1aba0a4b Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 10:18:11 +0200 Subject: [PATCH 08/22] :hammer: Added simple unit-tests --- codegen/src/testthat.rs | 16 +++++++++++++--- tests/testthat/helper-library.R | 1 + tests/testthat/test-series.R | 1 - tests/testthat/test-ta_ACCBANDS.R | 13 +++++++++++-- tests/testthat/test-ta_AD.R | 13 +++++++++++-- tests/testthat/test-ta_ADOSC.R | 16 ++++++++++++++-- tests/testthat/test-ta_ADX.R | 13 +++++++++++-- tests/testthat/test-ta_ADXR.R | 13 +++++++++++-- tests/testthat/test-ta_APO.R | 13 +++++++++++-- tests/testthat/test-ta_AROON.R | 9 +++++++++ tests/testthat/test-ta_AROONOSC.R | 13 +++++++++++-- tests/testthat/test-ta_ATR.R | 13 +++++++++++-- tests/testthat/test-ta_AVGDEV.R | 13 +++++++++++-- tests/testthat/test-ta_AVGPRICE.R | 13 +++++++++++-- tests/testthat/test-ta_BBANDS.R | 13 +++++++++++-- tests/testthat/test-ta_BOP.R | 13 +++++++++++-- tests/testthat/test-ta_CCI.R | 13 +++++++++++-- tests/testthat/test-ta_CDL2CROWS.R | 13 +++++++++++-- tests/testthat/test-ta_CDL3BLACKCROWS.R | 13 +++++++++++-- tests/testthat/test-ta_CDL3INSIDE.R | 13 +++++++++++-- tests/testthat/test-ta_CDL3LINESTRIKE.R | 13 +++++++++++-- tests/testthat/test-ta_CDL3OUTSIDE.R | 13 +++++++++++-- tests/testthat/test-ta_CDL3STARSINSOUTH.R | 13 +++++++++++-- tests/testthat/test-ta_CDL3WHITESOLDIERS.R | 13 +++++++++++-- tests/testthat/test-ta_CDLABANDONEDBABY.R | 13 +++++++++++-- tests/testthat/test-ta_CDLADVANCEBLOCK.R | 13 +++++++++++-- tests/testthat/test-ta_CDLBELTHOLD.R | 13 +++++++++++-- tests/testthat/test-ta_CDLBREAKAWAY.R | 13 +++++++++++-- tests/testthat/test-ta_CDLCLOSINGMARUBOZU.R | 13 +++++++++++-- tests/testthat/test-ta_CDLCONCEALBABYSWALL.R | 13 +++++++++++-- tests/testthat/test-ta_CDLCOUNTERATTACK.R | 13 +++++++++++-- tests/testthat/test-ta_CDLDARKCLOUDCOVER.R | 13 +++++++++++-- tests/testthat/test-ta_CDLDOJI.R | 9 +++++++++ tests/testthat/test-ta_CDLDOJISTAR.R | 13 +++++++++++-- tests/testthat/test-ta_CDLDRAGONFLYDOJI.R | 13 +++++++++++-- tests/testthat/test-ta_CDLENGULFING.R | 9 +++++++++ tests/testthat/test-ta_CDLEVENINGDOJISTAR.R | 13 +++++++++++-- tests/testthat/test-ta_CDLEVENINGSTAR.R | 13 +++++++++++-- tests/testthat/test-ta_CDLGAPSIDESIDEWHITE.R | 13 +++++++++++-- tests/testthat/test-ta_CDLGRAVESTONEDOJI.R | 13 +++++++++++-- tests/testthat/test-ta_CDLHAMMER.R | 9 +++++++++ tests/testthat/test-ta_CDLHANGINGMAN.R | 13 +++++++++++-- tests/testthat/test-ta_CDLHARAMI.R | 9 +++++++++ tests/testthat/test-ta_CDLHARAMICROSS.R | 13 +++++++++++-- tests/testthat/test-ta_CDLHIGHWAVE.R | 13 +++++++++++-- tests/testthat/test-ta_CDLHIKKAKE.R | 9 +++++++++ tests/testthat/test-ta_CDLHIKKAKEMOD.R | 13 +++++++++++-- tests/testthat/test-ta_CDLHOMINGPIGEON.R | 13 +++++++++++-- tests/testthat/test-ta_CDLIDENTICAL3CROWS.R | 13 +++++++++++-- tests/testthat/test-ta_CDLINNECK.R | 13 +++++++++++-- tests/testthat/test-ta_CDLINVERTEDHAMMER.R | 13 +++++++++++-- tests/testthat/test-ta_CDLKICKING.R | 9 +++++++++ tests/testthat/test-ta_CDLKICKINGBYLENGTH.R | 13 +++++++++++-- tests/testthat/test-ta_CDLLADDERBOTTOM.R | 13 +++++++++++-- tests/testthat/test-ta_CDLLONGLEGGEDDOJI.R | 13 +++++++++++-- tests/testthat/test-ta_CDLLONGLINE.R | 13 +++++++++++-- tests/testthat/test-ta_CDLMARUBOZU.R | 9 +++++++++ tests/testthat/test-ta_CDLMATCHINGLOW.R | 13 +++++++++++-- tests/testthat/test-ta_CDLMATHOLD.R | 13 +++++++++++-- tests/testthat/test-ta_CDLMORNINGDOJISTAR.R | 13 +++++++++++-- tests/testthat/test-ta_CDLMORNINGSTAR.R | 13 +++++++++++-- tests/testthat/test-ta_CDLONNECK.R | 13 +++++++++++-- tests/testthat/test-ta_CDLPIERCING.R | 9 +++++++++ tests/testthat/test-ta_CDLRICKSHAWMAN.R | 13 +++++++++++-- tests/testthat/test-ta_CDLRISEFALL3METHODS.R | 13 +++++++++++-- tests/testthat/test-ta_CDLSEPARATINGLINES.R | 13 +++++++++++-- tests/testthat/test-ta_CDLSHOOTINGSTAR.R | 13 +++++++++++-- tests/testthat/test-ta_CDLSHORTLINE.R | 13 +++++++++++-- tests/testthat/test-ta_CDLSPINNINGTOP.R | 13 +++++++++++-- tests/testthat/test-ta_CDLSTALLEDPATTERN.R | 13 +++++++++++-- tests/testthat/test-ta_CDLSTICKSANDWICH.R | 13 +++++++++++-- tests/testthat/test-ta_CDLTAKURI.R | 9 +++++++++ tests/testthat/test-ta_CDLTASUKIGAP.R | 13 +++++++++++-- tests/testthat/test-ta_CDLTHRUSTING.R | 9 +++++++++ tests/testthat/test-ta_CDLTRISTAR.R | 9 +++++++++ tests/testthat/test-ta_CDLUNIQUE3RIVER.R | 13 +++++++++++-- tests/testthat/test-ta_CDLUPSIDEGAP2CROWS.R | 13 +++++++++++-- tests/testthat/test-ta_CDLXSIDEGAP3METHODS.R | 13 +++++++++++-- tests/testthat/test-ta_CMO.R | 13 +++++++++++-- tests/testthat/test-ta_DEMA.R | 13 +++++++++++-- tests/testthat/test-ta_DX.R | 13 +++++++++++-- tests/testthat/test-ta_EMA.R | 13 +++++++++++-- tests/testthat/test-ta_HT_DCPERIOD.R | 13 +++++++++++-- tests/testthat/test-ta_HT_DCPHASE.R | 13 +++++++++++-- tests/testthat/test-ta_HT_PHASOR.R | 13 +++++++++++-- tests/testthat/test-ta_HT_SINE.R | 13 +++++++++++-- tests/testthat/test-ta_HT_TRENDLINE.R | 9 +++++++++ tests/testthat/test-ta_HT_TRENDMODE.R | 13 +++++++++++-- tests/testthat/test-ta_IMI.R | 13 +++++++++++-- tests/testthat/test-ta_KAMA.R | 13 +++++++++++-- tests/testthat/test-ta_MACD.R | 13 +++++++++++-- tests/testthat/test-ta_MACDEXT.R | 16 ++++++++++++++-- tests/testthat/test-ta_MACDFIX.R | 16 ++++++++++++++-- tests/testthat/test-ta_MAMA.R | 13 +++++++++++-- tests/testthat/test-ta_MAVP.R | 19 +++++++++++++++++-- tests/testthat/test-ta_MEDPRICE.R | 13 +++++++++++-- tests/testthat/test-ta_MFI.R | 13 +++++++++++-- tests/testthat/test-ta_MIDPOINT.R | 13 +++++++++++-- tests/testthat/test-ta_MIDPRICE.R | 13 +++++++++++-- tests/testthat/test-ta_MINUS_DI.R | 13 +++++++++++-- tests/testthat/test-ta_MINUS_DM.R | 13 +++++++++++-- tests/testthat/test-ta_MOM.R | 9 +++++++++ tests/testthat/test-ta_NATR.R | 13 +++++++++++-- tests/testthat/test-ta_OBV.R | 13 +++++++++++-- tests/testthat/test-ta_PLUS_DI.R | 13 +++++++++++-- tests/testthat/test-ta_PLUS_DM.R | 13 +++++++++++-- tests/testthat/test-ta_PPO.R | 13 +++++++++++-- tests/testthat/test-ta_ROCR.R | 13 +++++++++++-- tests/testthat/test-ta_RSI.R | 13 +++++++++++-- tests/testthat/test-ta_SAR.R | 13 +++++++++++-- tests/testthat/test-ta_SAREXT.R | 13 +++++++++++-- tests/testthat/test-ta_SMA.R | 13 +++++++++++-- tests/testthat/test-ta_STOCH.R | 9 +++++++++ tests/testthat/test-ta_STOCHF.R | 13 +++++++++++-- tests/testthat/test-ta_STOCHRSI.R | 13 +++++++++++-- tests/testthat/test-ta_T3.R | 13 +++++++++++-- tests/testthat/test-ta_TEMA.R | 13 +++++++++++-- tests/testthat/test-ta_TRANGE.R | 13 +++++++++++-- tests/testthat/test-ta_TRIMA.R | 13 +++++++++++-- tests/testthat/test-ta_TRIX.R | 13 +++++++++++-- tests/testthat/test-ta_TYPPRICE.R | 13 +++++++++++-- tests/testthat/test-ta_ULTOSC.R | 13 +++++++++++-- tests/testthat/test-ta_VOLUME.R | 9 +++++++++ tests/testthat/test-ta_WCLPRICE.R | 13 +++++++++++-- tests/testthat/test-ta_WILLR.R | 13 +++++++++++-- tests/testthat/test-ta_WMA.R | 13 +++++++++++-- 126 files changed, 1350 insertions(+), 218 deletions(-) create mode 100644 tests/testthat/helper-library.R diff --git a/codegen/src/testthat.rs b/codegen/src/testthat.rs index 0de023e74..d4f8246e2 100644 --- a/codegen/src/testthat.rs +++ b/codegen/src/testthat.rs @@ -141,6 +141,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(${FUN}(GOOGL${PASS_GOOGL}), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -260,8 +269,8 @@ testthat::expect_equal( #camel### the camelCase lookback alias #camel### is the function itself #camel#testthat::expect_identical( -#camel# object = ${CAMEL}_lookback, -#camel# expected = ${FUN}_lookback +#camel# object = talib:::${CAMEL}_lookback, +#camel# expected = talib:::${FUN}_lookback #camel# ) } @@ -422,6 +431,7 @@ pub fn render_test(f: &MetaData) -> String { .replace("${PASS_SPY}", &pass("SPY")) .replace("${PASS_BTC}", &pass("BTC")) .replace("${PASS_ATOM}", &pass("ATOM")) + .replace("${PASS_GOOGL}", &pass("GOOGL")) }; let mut out = format!("{HEADER}{}", fill(STANDARD_TESTS)); @@ -465,7 +475,7 @@ mod tests { assert!(rendered.contains("output <- bollinger_bands(SPY)")); assert!(rendered.contains("alias <- BBANDS(SPY)")); assert!(rendered.contains("camel <- bollingerBands(SPY)")); - assert!(rendered.contains("object = bollingerBands_lookback,")); + assert!(rendered.contains("object = talib:::bollingerBands_lookback,")); assert!(!rendered.contains("#camel#"), "unstripped camel prefix"); assert!(rendered.contains("cols = ~close")); assert!(rendered.contains("-methods for ")); diff --git a/tests/testthat/helper-library.R b/tests/testthat/helper-library.R new file mode 100644 index 000000000..34b61000a --- /dev/null +++ b/tests/testthat/helper-library.R @@ -0,0 +1 @@ +library(xts) diff --git a/tests/testthat/test-series.R b/tests/testthat/test-series.R index 20a401f2b..2e45b2282 100644 --- a/tests/testthat/test-series.R +++ b/tests/testthat/test-series.R @@ -1,4 +1,3 @@ -library(talib) ## tests for the formula-based column selector ## series() is internal; we exercise it via the indicator pipeline testthat::test_that(desc = "Output is ", code = { diff --git a/tests/testthat/test-ta_ACCBANDS.R b/tests/testthat/test-ta_ACCBANDS.R index 308ca6dba..95ab588c3 100644 --- a/tests/testthat/test-ta_ACCBANDS.R +++ b/tests/testthat/test-ta_ACCBANDS.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(acceleration_bands(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = accelerationBands_lookback, - expected = acceleration_bands_lookback + object = talib:::accelerationBands_lookback, + expected = talib:::acceleration_bands_lookback ) }) diff --git a/tests/testthat/test-ta_AD.R b/tests/testthat/test-ta_AD.R index 7e213ac2c..f6b06c98b 100644 --- a/tests/testthat/test-ta_AD.R +++ b/tests/testthat/test-ta_AD.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(chaikin_accumulation_distribution_line(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -174,8 +183,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = chaikinAccumulationDistributionLine_lookback, - expected = chaikin_accumulation_distribution_line_lookback + object = talib:::chaikinAccumulationDistributionLine_lookback, + expected = talib:::chaikin_accumulation_distribution_line_lookback ) }) diff --git a/tests/testthat/test-ta_ADOSC.R b/tests/testthat/test-ta_ADOSC.R index c2695c102..d4a54b127 100644 --- a/tests/testthat/test-ta_ADOSC.R +++ b/tests/testthat/test-ta_ADOSC.R @@ -53,6 +53,18 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits( + chaikin_accumulation_distribution_oscillator(GOOGL), + class(GOOGL) + ) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -177,8 +189,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = chaikinAccumulationDistributionOscillator_lookback, - expected = chaikin_accumulation_distribution_oscillator_lookback + object = talib:::chaikinAccumulationDistributionOscillator_lookback, + expected = talib:::chaikin_accumulation_distribution_oscillator_lookback ) }) diff --git a/tests/testthat/test-ta_ADX.R b/tests/testthat/test-ta_ADX.R index 7d90debc8..9b68643d8 100644 --- a/tests/testthat/test-ta_ADX.R +++ b/tests/testthat/test-ta_ADX.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(average_directional_movement_index(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = averageDirectionalMovementIndex_lookback, - expected = average_directional_movement_index_lookback + object = talib:::averageDirectionalMovementIndex_lookback, + expected = talib:::average_directional_movement_index_lookback ) }) diff --git a/tests/testthat/test-ta_ADXR.R b/tests/testthat/test-ta_ADXR.R index 56247175a..f2b4390db 100644 --- a/tests/testthat/test-ta_ADXR.R +++ b/tests/testthat/test-ta_ADXR.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(average_directional_movement_index_rating(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -177,8 +186,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = averageDirectionalMovementIndexRating_lookback, - expected = average_directional_movement_index_rating_lookback + object = talib:::averageDirectionalMovementIndexRating_lookback, + expected = talib:::average_directional_movement_index_rating_lookback ) }) diff --git a/tests/testthat/test-ta_APO.R b/tests/testthat/test-ta_APO.R index 0afc08570..95a9c5044 100644 --- a/tests/testthat/test-ta_APO.R +++ b/tests/testthat/test-ta_APO.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(absolute_price_oscillator(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = absolutePriceOscillator_lookback, - expected = absolute_price_oscillator_lookback + object = talib:::absolutePriceOscillator_lookback, + expected = talib:::absolute_price_oscillator_lookback ) }) diff --git a/tests/testthat/test-ta_AROON.R b/tests/testthat/test-ta_AROON.R index 74086f794..ef266d873 100644 --- a/tests/testthat/test-ta_AROON.R +++ b/tests/testthat/test-ta_AROON.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(aroon(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_AROONOSC.R b/tests/testthat/test-ta_AROONOSC.R index 5fe654904..25638d23d 100644 --- a/tests/testthat/test-ta_AROONOSC.R +++ b/tests/testthat/test-ta_AROONOSC.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(aroon_oscillator(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = aroonOscillator_lookback, - expected = aroon_oscillator_lookback + object = talib:::aroonOscillator_lookback, + expected = talib:::aroon_oscillator_lookback ) }) diff --git a/tests/testthat/test-ta_ATR.R b/tests/testthat/test-ta_ATR.R index 74cde10ba..8436d8b0b 100644 --- a/tests/testthat/test-ta_ATR.R +++ b/tests/testthat/test-ta_ATR.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(average_true_range(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = averageTrueRange_lookback, - expected = average_true_range_lookback + object = talib:::averageTrueRange_lookback, + expected = talib:::average_true_range_lookback ) }) diff --git a/tests/testthat/test-ta_AVGDEV.R b/tests/testthat/test-ta_AVGDEV.R index 11e34acaf..c7df0d498 100644 --- a/tests/testthat/test-ta_AVGDEV.R +++ b/tests/testthat/test-ta_AVGDEV.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(average_deviation(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = averageDeviation_lookback, - expected = average_deviation_lookback + object = talib:::averageDeviation_lookback, + expected = talib:::average_deviation_lookback ) }) diff --git a/tests/testthat/test-ta_AVGPRICE.R b/tests/testthat/test-ta_AVGPRICE.R index 3b53ca41c..69b58c96f 100644 --- a/tests/testthat/test-ta_AVGPRICE.R +++ b/tests/testthat/test-ta_AVGPRICE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(average_price(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,7 +180,7 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = averagePrice_lookback, - expected = average_price_lookback + object = talib:::averagePrice_lookback, + expected = talib:::average_price_lookback ) }) diff --git a/tests/testthat/test-ta_BBANDS.R b/tests/testthat/test-ta_BBANDS.R index 3e6597f2d..36d821479 100644 --- a/tests/testthat/test-ta_BBANDS.R +++ b/tests/testthat/test-ta_BBANDS.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(bollinger_bands(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = bollingerBands_lookback, - expected = bollinger_bands_lookback + object = talib:::bollingerBands_lookback, + expected = talib:::bollinger_bands_lookback ) }) diff --git a/tests/testthat/test-ta_BOP.R b/tests/testthat/test-ta_BOP.R index 5c403ff07..cab304dc9 100644 --- a/tests/testthat/test-ta_BOP.R +++ b/tests/testthat/test-ta_BOP.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(balance_of_power(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = balanceOfPower_lookback, - expected = balance_of_power_lookback + object = talib:::balanceOfPower_lookback, + expected = talib:::balance_of_power_lookback ) }) diff --git a/tests/testthat/test-ta_CCI.R b/tests/testthat/test-ta_CCI.R index 628ad43ab..06d040c17 100644 --- a/tests/testthat/test-ta_CCI.R +++ b/tests/testthat/test-ta_CCI.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(commodity_channel_index(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = commodityChannelIndex_lookback, - expected = commodity_channel_index_lookback + object = talib:::commodityChannelIndex_lookback, + expected = talib:::commodity_channel_index_lookback ) }) diff --git a/tests/testthat/test-ta_CDL2CROWS.R b/tests/testthat/test-ta_CDL2CROWS.R index 19c2807e4..ac63e3303 100644 --- a/tests/testthat/test-ta_CDL2CROWS.R +++ b/tests/testthat/test-ta_CDL2CROWS.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(two_crows(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = twoCrows_lookback, - expected = two_crows_lookback + object = talib:::twoCrows_lookback, + expected = talib:::two_crows_lookback ) }) diff --git a/tests/testthat/test-ta_CDL3BLACKCROWS.R b/tests/testthat/test-ta_CDL3BLACKCROWS.R index 80f9fd02b..c20127cf9 100644 --- a/tests/testthat/test-ta_CDL3BLACKCROWS.R +++ b/tests/testthat/test-ta_CDL3BLACKCROWS.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(three_black_crows(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = threeBlackCrows_lookback, - expected = three_black_crows_lookback + object = talib:::threeBlackCrows_lookback, + expected = talib:::three_black_crows_lookback ) }) diff --git a/tests/testthat/test-ta_CDL3INSIDE.R b/tests/testthat/test-ta_CDL3INSIDE.R index 8a0467228..f3f0e20ad 100644 --- a/tests/testthat/test-ta_CDL3INSIDE.R +++ b/tests/testthat/test-ta_CDL3INSIDE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(three_inside(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = threeInside_lookback, - expected = three_inside_lookback + object = talib:::threeInside_lookback, + expected = talib:::three_inside_lookback ) }) diff --git a/tests/testthat/test-ta_CDL3LINESTRIKE.R b/tests/testthat/test-ta_CDL3LINESTRIKE.R index 47e3e5ecf..b11804eed 100644 --- a/tests/testthat/test-ta_CDL3LINESTRIKE.R +++ b/tests/testthat/test-ta_CDL3LINESTRIKE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(three_line_strike(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = threeLineStrike_lookback, - expected = three_line_strike_lookback + object = talib:::threeLineStrike_lookback, + expected = talib:::three_line_strike_lookback ) }) diff --git a/tests/testthat/test-ta_CDL3OUTSIDE.R b/tests/testthat/test-ta_CDL3OUTSIDE.R index c475587ca..0b1f8c1d2 100644 --- a/tests/testthat/test-ta_CDL3OUTSIDE.R +++ b/tests/testthat/test-ta_CDL3OUTSIDE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(three_outside(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = threeOutside_lookback, - expected = three_outside_lookback + object = talib:::threeOutside_lookback, + expected = talib:::three_outside_lookback ) }) diff --git a/tests/testthat/test-ta_CDL3STARSINSOUTH.R b/tests/testthat/test-ta_CDL3STARSINSOUTH.R index 1ffc00750..01f367995 100644 --- a/tests/testthat/test-ta_CDL3STARSINSOUTH.R +++ b/tests/testthat/test-ta_CDL3STARSINSOUTH.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(three_stars_in_the_south(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = threeStarsInTheSouth_lookback, - expected = three_stars_in_the_south_lookback + object = talib:::threeStarsInTheSouth_lookback, + expected = talib:::three_stars_in_the_south_lookback ) }) diff --git a/tests/testthat/test-ta_CDL3WHITESOLDIERS.R b/tests/testthat/test-ta_CDL3WHITESOLDIERS.R index e797561a7..b5ef8c5b2 100644 --- a/tests/testthat/test-ta_CDL3WHITESOLDIERS.R +++ b/tests/testthat/test-ta_CDL3WHITESOLDIERS.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(three_white_soldiers(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = threeWhiteSoldiers_lookback, - expected = three_white_soldiers_lookback + object = talib:::threeWhiteSoldiers_lookback, + expected = talib:::three_white_soldiers_lookback ) }) diff --git a/tests/testthat/test-ta_CDLABANDONEDBABY.R b/tests/testthat/test-ta_CDLABANDONEDBABY.R index 45ec30d53..c85a96ce7 100644 --- a/tests/testthat/test-ta_CDLABANDONEDBABY.R +++ b/tests/testthat/test-ta_CDLABANDONEDBABY.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(abandoned_baby(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = abandonedBaby_lookback, - expected = abandoned_baby_lookback + object = talib:::abandonedBaby_lookback, + expected = talib:::abandoned_baby_lookback ) }) diff --git a/tests/testthat/test-ta_CDLADVANCEBLOCK.R b/tests/testthat/test-ta_CDLADVANCEBLOCK.R index c227abe68..cdf3feaf3 100644 --- a/tests/testthat/test-ta_CDLADVANCEBLOCK.R +++ b/tests/testthat/test-ta_CDLADVANCEBLOCK.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(advance_block(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = advanceBlock_lookback, - expected = advance_block_lookback + object = talib:::advanceBlock_lookback, + expected = talib:::advance_block_lookback ) }) diff --git a/tests/testthat/test-ta_CDLBELTHOLD.R b/tests/testthat/test-ta_CDLBELTHOLD.R index 900066356..77f95a5bc 100644 --- a/tests/testthat/test-ta_CDLBELTHOLD.R +++ b/tests/testthat/test-ta_CDLBELTHOLD.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(belt_hold(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = beltHold_lookback, - expected = belt_hold_lookback + object = talib:::beltHold_lookback, + expected = talib:::belt_hold_lookback ) }) diff --git a/tests/testthat/test-ta_CDLBREAKAWAY.R b/tests/testthat/test-ta_CDLBREAKAWAY.R index 7929ed752..7c8611d21 100644 --- a/tests/testthat/test-ta_CDLBREAKAWAY.R +++ b/tests/testthat/test-ta_CDLBREAKAWAY.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(break_away(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = breakAway_lookback, - expected = break_away_lookback + object = talib:::breakAway_lookback, + expected = talib:::break_away_lookback ) }) diff --git a/tests/testthat/test-ta_CDLCLOSINGMARUBOZU.R b/tests/testthat/test-ta_CDLCLOSINGMARUBOZU.R index 51c46d9cc..73dd60c7b 100644 --- a/tests/testthat/test-ta_CDLCLOSINGMARUBOZU.R +++ b/tests/testthat/test-ta_CDLCLOSINGMARUBOZU.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(closing_marubozu(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = closingMarubozu_lookback, - expected = closing_marubozu_lookback + object = talib:::closingMarubozu_lookback, + expected = talib:::closing_marubozu_lookback ) }) diff --git a/tests/testthat/test-ta_CDLCONCEALBABYSWALL.R b/tests/testthat/test-ta_CDLCONCEALBABYSWALL.R index 251b4f2ce..4ee002f8f 100644 --- a/tests/testthat/test-ta_CDLCONCEALBABYSWALL.R +++ b/tests/testthat/test-ta_CDLCONCEALBABYSWALL.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(concealing_baby_swallow(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = concealingBabySwallow_lookback, - expected = concealing_baby_swallow_lookback + object = talib:::concealingBabySwallow_lookback, + expected = talib:::concealing_baby_swallow_lookback ) }) diff --git a/tests/testthat/test-ta_CDLCOUNTERATTACK.R b/tests/testthat/test-ta_CDLCOUNTERATTACK.R index fdb6310b0..c334da4b0 100644 --- a/tests/testthat/test-ta_CDLCOUNTERATTACK.R +++ b/tests/testthat/test-ta_CDLCOUNTERATTACK.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(counter_attack(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = counterAttack_lookback, - expected = counter_attack_lookback + object = talib:::counterAttack_lookback, + expected = talib:::counter_attack_lookback ) }) diff --git a/tests/testthat/test-ta_CDLDARKCLOUDCOVER.R b/tests/testthat/test-ta_CDLDARKCLOUDCOVER.R index d1cc2d240..c5ea7142f 100644 --- a/tests/testthat/test-ta_CDLDARKCLOUDCOVER.R +++ b/tests/testthat/test-ta_CDLDARKCLOUDCOVER.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(dark_cloud_cover(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = darkCloudCover_lookback, - expected = dark_cloud_cover_lookback + object = talib:::darkCloudCover_lookback, + expected = talib:::dark_cloud_cover_lookback ) }) diff --git a/tests/testthat/test-ta_CDLDOJI.R b/tests/testthat/test-ta_CDLDOJI.R index 3c448493e..57333d26f 100644 --- a/tests/testthat/test-ta_CDLDOJI.R +++ b/tests/testthat/test-ta_CDLDOJI.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(doji(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLDOJISTAR.R b/tests/testthat/test-ta_CDLDOJISTAR.R index 7a6f8ec25..7a40d41e1 100644 --- a/tests/testthat/test-ta_CDLDOJISTAR.R +++ b/tests/testthat/test-ta_CDLDOJISTAR.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(doji_star(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = dojiStar_lookback, - expected = doji_star_lookback + object = talib:::dojiStar_lookback, + expected = talib:::doji_star_lookback ) }) diff --git a/tests/testthat/test-ta_CDLDRAGONFLYDOJI.R b/tests/testthat/test-ta_CDLDRAGONFLYDOJI.R index 4e05f5327..c4deaf290 100644 --- a/tests/testthat/test-ta_CDLDRAGONFLYDOJI.R +++ b/tests/testthat/test-ta_CDLDRAGONFLYDOJI.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(dragonfly_doji(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = dragonflyDoji_lookback, - expected = dragonfly_doji_lookback + object = talib:::dragonflyDoji_lookback, + expected = talib:::dragonfly_doji_lookback ) }) diff --git a/tests/testthat/test-ta_CDLENGULFING.R b/tests/testthat/test-ta_CDLENGULFING.R index fe3e34aa7..9078ee51d 100644 --- a/tests/testthat/test-ta_CDLENGULFING.R +++ b/tests/testthat/test-ta_CDLENGULFING.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(engulfing(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLEVENINGDOJISTAR.R b/tests/testthat/test-ta_CDLEVENINGDOJISTAR.R index eb609b7eb..f80a09cc4 100644 --- a/tests/testthat/test-ta_CDLEVENINGDOJISTAR.R +++ b/tests/testthat/test-ta_CDLEVENINGDOJISTAR.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(evening_doji_star(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = eveningDojiStar_lookback, - expected = evening_doji_star_lookback + object = talib:::eveningDojiStar_lookback, + expected = talib:::evening_doji_star_lookback ) }) diff --git a/tests/testthat/test-ta_CDLEVENINGSTAR.R b/tests/testthat/test-ta_CDLEVENINGSTAR.R index 2ec4d9af4..0f4c5f0ec 100644 --- a/tests/testthat/test-ta_CDLEVENINGSTAR.R +++ b/tests/testthat/test-ta_CDLEVENINGSTAR.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(evening_star(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = eveningStar_lookback, - expected = evening_star_lookback + object = talib:::eveningStar_lookback, + expected = talib:::evening_star_lookback ) }) diff --git a/tests/testthat/test-ta_CDLGAPSIDESIDEWHITE.R b/tests/testthat/test-ta_CDLGAPSIDESIDEWHITE.R index 0ec6abfa4..f306e66ef 100644 --- a/tests/testthat/test-ta_CDLGAPSIDESIDEWHITE.R +++ b/tests/testthat/test-ta_CDLGAPSIDESIDEWHITE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(gaps_side_white(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = gapsSideWhite_lookback, - expected = gaps_side_white_lookback + object = talib:::gapsSideWhite_lookback, + expected = talib:::gaps_side_white_lookback ) }) diff --git a/tests/testthat/test-ta_CDLGRAVESTONEDOJI.R b/tests/testthat/test-ta_CDLGRAVESTONEDOJI.R index d1bc22eb1..7dd52d7ed 100644 --- a/tests/testthat/test-ta_CDLGRAVESTONEDOJI.R +++ b/tests/testthat/test-ta_CDLGRAVESTONEDOJI.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(gravestone_doji(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = gravestoneDoji_lookback, - expected = gravestone_doji_lookback + object = talib:::gravestoneDoji_lookback, + expected = talib:::gravestone_doji_lookback ) }) diff --git a/tests/testthat/test-ta_CDLHAMMER.R b/tests/testthat/test-ta_CDLHAMMER.R index 7d9407e32..2eb9e25e8 100644 --- a/tests/testthat/test-ta_CDLHAMMER.R +++ b/tests/testthat/test-ta_CDLHAMMER.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(hammer(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLHANGINGMAN.R b/tests/testthat/test-ta_CDLHANGINGMAN.R index 6676e75df..bfccec440 100644 --- a/tests/testthat/test-ta_CDLHANGINGMAN.R +++ b/tests/testthat/test-ta_CDLHANGINGMAN.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(hanging_man(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = hangingMan_lookback, - expected = hanging_man_lookback + object = talib:::hangingMan_lookback, + expected = talib:::hanging_man_lookback ) }) diff --git a/tests/testthat/test-ta_CDLHARAMI.R b/tests/testthat/test-ta_CDLHARAMI.R index 4180a6b23..1e71490a8 100644 --- a/tests/testthat/test-ta_CDLHARAMI.R +++ b/tests/testthat/test-ta_CDLHARAMI.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(harami(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLHARAMICROSS.R b/tests/testthat/test-ta_CDLHARAMICROSS.R index 22e33aee8..30b6e4a3f 100644 --- a/tests/testthat/test-ta_CDLHARAMICROSS.R +++ b/tests/testthat/test-ta_CDLHARAMICROSS.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(harami_cross(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = haramiCross_lookback, - expected = harami_cross_lookback + object = talib:::haramiCross_lookback, + expected = talib:::harami_cross_lookback ) }) diff --git a/tests/testthat/test-ta_CDLHIGHWAVE.R b/tests/testthat/test-ta_CDLHIGHWAVE.R index 2db4ab2ac..f5c5b9ee3 100644 --- a/tests/testthat/test-ta_CDLHIGHWAVE.R +++ b/tests/testthat/test-ta_CDLHIGHWAVE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(high_wave(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = highWave_lookback, - expected = high_wave_lookback + object = talib:::highWave_lookback, + expected = talib:::high_wave_lookback ) }) diff --git a/tests/testthat/test-ta_CDLHIKKAKE.R b/tests/testthat/test-ta_CDLHIKKAKE.R index 4d7547392..ff424a4ba 100644 --- a/tests/testthat/test-ta_CDLHIKKAKE.R +++ b/tests/testthat/test-ta_CDLHIKKAKE.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(hikakke(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLHIKKAKEMOD.R b/tests/testthat/test-ta_CDLHIKKAKEMOD.R index 5d598d585..e3f6663dc 100644 --- a/tests/testthat/test-ta_CDLHIKKAKEMOD.R +++ b/tests/testthat/test-ta_CDLHIKKAKEMOD.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(hikakke_mod(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = hikakkeMod_lookback, - expected = hikakke_mod_lookback + object = talib:::hikakkeMod_lookback, + expected = talib:::hikakke_mod_lookback ) }) diff --git a/tests/testthat/test-ta_CDLHOMINGPIGEON.R b/tests/testthat/test-ta_CDLHOMINGPIGEON.R index c24bffaf4..2b93bd828 100644 --- a/tests/testthat/test-ta_CDLHOMINGPIGEON.R +++ b/tests/testthat/test-ta_CDLHOMINGPIGEON.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(homing_pigeon(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = homingPigeon_lookback, - expected = homing_pigeon_lookback + object = talib:::homingPigeon_lookback, + expected = talib:::homing_pigeon_lookback ) }) diff --git a/tests/testthat/test-ta_CDLIDENTICAL3CROWS.R b/tests/testthat/test-ta_CDLIDENTICAL3CROWS.R index 7976fe6c9..4b8bc3eef 100644 --- a/tests/testthat/test-ta_CDLIDENTICAL3CROWS.R +++ b/tests/testthat/test-ta_CDLIDENTICAL3CROWS.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(three_identical_crows(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = threeIdenticalCrows_lookback, - expected = three_identical_crows_lookback + object = talib:::threeIdenticalCrows_lookback, + expected = talib:::three_identical_crows_lookback ) }) diff --git a/tests/testthat/test-ta_CDLINNECK.R b/tests/testthat/test-ta_CDLINNECK.R index 00786c55b..ce6085526 100644 --- a/tests/testthat/test-ta_CDLINNECK.R +++ b/tests/testthat/test-ta_CDLINNECK.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(in_neck(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = inNeck_lookback, - expected = in_neck_lookback + object = talib:::inNeck_lookback, + expected = talib:::in_neck_lookback ) }) diff --git a/tests/testthat/test-ta_CDLINVERTEDHAMMER.R b/tests/testthat/test-ta_CDLINVERTEDHAMMER.R index 91736f76d..90e8d2176 100644 --- a/tests/testthat/test-ta_CDLINVERTEDHAMMER.R +++ b/tests/testthat/test-ta_CDLINVERTEDHAMMER.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(inverted_hammer(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = invertedHammer_lookback, - expected = inverted_hammer_lookback + object = talib:::invertedHammer_lookback, + expected = talib:::inverted_hammer_lookback ) }) diff --git a/tests/testthat/test-ta_CDLKICKING.R b/tests/testthat/test-ta_CDLKICKING.R index 5a8fd173d..d5b551457 100644 --- a/tests/testthat/test-ta_CDLKICKING.R +++ b/tests/testthat/test-ta_CDLKICKING.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(kicking(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLKICKINGBYLENGTH.R b/tests/testthat/test-ta_CDLKICKINGBYLENGTH.R index 8f4aa7b4f..278164e80 100644 --- a/tests/testthat/test-ta_CDLKICKINGBYLENGTH.R +++ b/tests/testthat/test-ta_CDLKICKINGBYLENGTH.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(kicking_baby_length(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = kickingBabyLength_lookback, - expected = kicking_baby_length_lookback + object = talib:::kickingBabyLength_lookback, + expected = talib:::kicking_baby_length_lookback ) }) diff --git a/tests/testthat/test-ta_CDLLADDERBOTTOM.R b/tests/testthat/test-ta_CDLLADDERBOTTOM.R index 0bc5eddfb..c60c6e2b6 100644 --- a/tests/testthat/test-ta_CDLLADDERBOTTOM.R +++ b/tests/testthat/test-ta_CDLLADDERBOTTOM.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(ladder_bottom(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = ladderBottom_lookback, - expected = ladder_bottom_lookback + object = talib:::ladderBottom_lookback, + expected = talib:::ladder_bottom_lookback ) }) diff --git a/tests/testthat/test-ta_CDLLONGLEGGEDDOJI.R b/tests/testthat/test-ta_CDLLONGLEGGEDDOJI.R index 0f206eec4..4eb159c6a 100644 --- a/tests/testthat/test-ta_CDLLONGLEGGEDDOJI.R +++ b/tests/testthat/test-ta_CDLLONGLEGGEDDOJI.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(long_legged_doji(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = longLeggedDoji_lookback, - expected = long_legged_doji_lookback + object = talib:::longLeggedDoji_lookback, + expected = talib:::long_legged_doji_lookback ) }) diff --git a/tests/testthat/test-ta_CDLLONGLINE.R b/tests/testthat/test-ta_CDLLONGLINE.R index 5738cb65e..26d2ba49e 100644 --- a/tests/testthat/test-ta_CDLLONGLINE.R +++ b/tests/testthat/test-ta_CDLLONGLINE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(long_line(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = longLine_lookback, - expected = long_line_lookback + object = talib:::longLine_lookback, + expected = talib:::long_line_lookback ) }) diff --git a/tests/testthat/test-ta_CDLMARUBOZU.R b/tests/testthat/test-ta_CDLMARUBOZU.R index 20cc3f005..bcc7dd068 100644 --- a/tests/testthat/test-ta_CDLMARUBOZU.R +++ b/tests/testthat/test-ta_CDLMARUBOZU.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(marubozu(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLMATCHINGLOW.R b/tests/testthat/test-ta_CDLMATCHINGLOW.R index 5e48bedc4..af0b78c6a 100644 --- a/tests/testthat/test-ta_CDLMATCHINGLOW.R +++ b/tests/testthat/test-ta_CDLMATCHINGLOW.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(matching_low(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = matchingLow_lookback, - expected = matching_low_lookback + object = talib:::matchingLow_lookback, + expected = talib:::matching_low_lookback ) }) diff --git a/tests/testthat/test-ta_CDLMATHOLD.R b/tests/testthat/test-ta_CDLMATHOLD.R index 60ba87730..78ec4b36c 100644 --- a/tests/testthat/test-ta_CDLMATHOLD.R +++ b/tests/testthat/test-ta_CDLMATHOLD.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(mat_hold(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = matHold_lookback, - expected = mat_hold_lookback + object = talib:::matHold_lookback, + expected = talib:::mat_hold_lookback ) }) diff --git a/tests/testthat/test-ta_CDLMORNINGDOJISTAR.R b/tests/testthat/test-ta_CDLMORNINGDOJISTAR.R index 19e9194e8..ea697a3fa 100644 --- a/tests/testthat/test-ta_CDLMORNINGDOJISTAR.R +++ b/tests/testthat/test-ta_CDLMORNINGDOJISTAR.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(morning_doji_star(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = morningDojiStar_lookback, - expected = morning_doji_star_lookback + object = talib:::morningDojiStar_lookback, + expected = talib:::morning_doji_star_lookback ) }) diff --git a/tests/testthat/test-ta_CDLMORNINGSTAR.R b/tests/testthat/test-ta_CDLMORNINGSTAR.R index 6073fe73f..d6e0be244 100644 --- a/tests/testthat/test-ta_CDLMORNINGSTAR.R +++ b/tests/testthat/test-ta_CDLMORNINGSTAR.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(morning_star(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = morningStar_lookback, - expected = morning_star_lookback + object = talib:::morningStar_lookback, + expected = talib:::morning_star_lookback ) }) diff --git a/tests/testthat/test-ta_CDLONNECK.R b/tests/testthat/test-ta_CDLONNECK.R index 372497f18..dd2819cc4 100644 --- a/tests/testthat/test-ta_CDLONNECK.R +++ b/tests/testthat/test-ta_CDLONNECK.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(on_neck(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = onNeck_lookback, - expected = on_neck_lookback + object = talib:::onNeck_lookback, + expected = talib:::on_neck_lookback ) }) diff --git a/tests/testthat/test-ta_CDLPIERCING.R b/tests/testthat/test-ta_CDLPIERCING.R index 035b20694..644a76a0a 100644 --- a/tests/testthat/test-ta_CDLPIERCING.R +++ b/tests/testthat/test-ta_CDLPIERCING.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(piercing(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLRICKSHAWMAN.R b/tests/testthat/test-ta_CDLRICKSHAWMAN.R index da0fb5026..a322329b8 100644 --- a/tests/testthat/test-ta_CDLRICKSHAWMAN.R +++ b/tests/testthat/test-ta_CDLRICKSHAWMAN.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(rickshaw_man(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = rickshawMan_lookback, - expected = rickshaw_man_lookback + object = talib:::rickshawMan_lookback, + expected = talib:::rickshaw_man_lookback ) }) diff --git a/tests/testthat/test-ta_CDLRISEFALL3METHODS.R b/tests/testthat/test-ta_CDLRISEFALL3METHODS.R index eb82b9560..e97d1fd61 100644 --- a/tests/testthat/test-ta_CDLRISEFALL3METHODS.R +++ b/tests/testthat/test-ta_CDLRISEFALL3METHODS.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(rise_fall_3_methods(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = riseFall3Methods_lookback, - expected = rise_fall_3_methods_lookback + object = talib:::riseFall3Methods_lookback, + expected = talib:::rise_fall_3_methods_lookback ) }) diff --git a/tests/testthat/test-ta_CDLSEPARATINGLINES.R b/tests/testthat/test-ta_CDLSEPARATINGLINES.R index 98635fc50..e19d3e2fe 100644 --- a/tests/testthat/test-ta_CDLSEPARATINGLINES.R +++ b/tests/testthat/test-ta_CDLSEPARATINGLINES.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(separating_lines(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = separatingLines_lookback, - expected = separating_lines_lookback + object = talib:::separatingLines_lookback, + expected = talib:::separating_lines_lookback ) }) diff --git a/tests/testthat/test-ta_CDLSHOOTINGSTAR.R b/tests/testthat/test-ta_CDLSHOOTINGSTAR.R index 93739a5ac..37e6ed4a2 100644 --- a/tests/testthat/test-ta_CDLSHOOTINGSTAR.R +++ b/tests/testthat/test-ta_CDLSHOOTINGSTAR.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(shooting_star(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = shootingStar_lookback, - expected = shooting_star_lookback + object = talib:::shootingStar_lookback, + expected = talib:::shooting_star_lookback ) }) diff --git a/tests/testthat/test-ta_CDLSHORTLINE.R b/tests/testthat/test-ta_CDLSHORTLINE.R index 07f1f8305..479817782 100644 --- a/tests/testthat/test-ta_CDLSHORTLINE.R +++ b/tests/testthat/test-ta_CDLSHORTLINE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(short_line(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = shortLine_lookback, - expected = short_line_lookback + object = talib:::shortLine_lookback, + expected = talib:::short_line_lookback ) }) diff --git a/tests/testthat/test-ta_CDLSPINNINGTOP.R b/tests/testthat/test-ta_CDLSPINNINGTOP.R index 0a32c4408..74b33933e 100644 --- a/tests/testthat/test-ta_CDLSPINNINGTOP.R +++ b/tests/testthat/test-ta_CDLSPINNINGTOP.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(spinning_top(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = spinningTop_lookback, - expected = spinning_top_lookback + object = talib:::spinningTop_lookback, + expected = talib:::spinning_top_lookback ) }) diff --git a/tests/testthat/test-ta_CDLSTALLEDPATTERN.R b/tests/testthat/test-ta_CDLSTALLEDPATTERN.R index e5c9c393f..a3040514c 100644 --- a/tests/testthat/test-ta_CDLSTALLEDPATTERN.R +++ b/tests/testthat/test-ta_CDLSTALLEDPATTERN.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(stalled_pattern(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = stalledPattern_lookback, - expected = stalled_pattern_lookback + object = talib:::stalledPattern_lookback, + expected = talib:::stalled_pattern_lookback ) }) diff --git a/tests/testthat/test-ta_CDLSTICKSANDWICH.R b/tests/testthat/test-ta_CDLSTICKSANDWICH.R index afd8436ae..286301a41 100644 --- a/tests/testthat/test-ta_CDLSTICKSANDWICH.R +++ b/tests/testthat/test-ta_CDLSTICKSANDWICH.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(stick_sandwich(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = stickSandwich_lookback, - expected = stick_sandwich_lookback + object = talib:::stickSandwich_lookback, + expected = talib:::stick_sandwich_lookback ) }) diff --git a/tests/testthat/test-ta_CDLTAKURI.R b/tests/testthat/test-ta_CDLTAKURI.R index eac53b76d..41a2a81d0 100644 --- a/tests/testthat/test-ta_CDLTAKURI.R +++ b/tests/testthat/test-ta_CDLTAKURI.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(takuri(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLTASUKIGAP.R b/tests/testthat/test-ta_CDLTASUKIGAP.R index a6a9c01c0..6b90cbba8 100644 --- a/tests/testthat/test-ta_CDLTASUKIGAP.R +++ b/tests/testthat/test-ta_CDLTASUKIGAP.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(tasuki_gap(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = tasukiGap_lookback, - expected = tasuki_gap_lookback + object = talib:::tasukiGap_lookback, + expected = talib:::tasuki_gap_lookback ) }) diff --git a/tests/testthat/test-ta_CDLTHRUSTING.R b/tests/testthat/test-ta_CDLTHRUSTING.R index abf172840..d5ad6e552 100644 --- a/tests/testthat/test-ta_CDLTHRUSTING.R +++ b/tests/testthat/test-ta_CDLTHRUSTING.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(thrusting(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLTRISTAR.R b/tests/testthat/test-ta_CDLTRISTAR.R index 111ae2979..b09a137fb 100644 --- a/tests/testthat/test-ta_CDLTRISTAR.R +++ b/tests/testthat/test-ta_CDLTRISTAR.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(tristar(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLUNIQUE3RIVER.R b/tests/testthat/test-ta_CDLUNIQUE3RIVER.R index 060e0bdf3..7993346d1 100644 --- a/tests/testthat/test-ta_CDLUNIQUE3RIVER.R +++ b/tests/testthat/test-ta_CDLUNIQUE3RIVER.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(unique_3_river(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = unique3River_lookback, - expected = unique_3_river_lookback + object = talib:::unique3River_lookback, + expected = talib:::unique_3_river_lookback ) }) diff --git a/tests/testthat/test-ta_CDLUPSIDEGAP2CROWS.R b/tests/testthat/test-ta_CDLUPSIDEGAP2CROWS.R index 3b9064fab..1514fb111 100644 --- a/tests/testthat/test-ta_CDLUPSIDEGAP2CROWS.R +++ b/tests/testthat/test-ta_CDLUPSIDEGAP2CROWS.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(upside_gap_2_crows(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = upsideGap2Crows_lookback, - expected = upside_gap_2_crows_lookback + object = talib:::upsideGap2Crows_lookback, + expected = talib:::upside_gap_2_crows_lookback ) }) diff --git a/tests/testthat/test-ta_CDLXSIDEGAP3METHODS.R b/tests/testthat/test-ta_CDLXSIDEGAP3METHODS.R index 560702e9d..57e112893 100644 --- a/tests/testthat/test-ta_CDLXSIDEGAP3METHODS.R +++ b/tests/testthat/test-ta_CDLXSIDEGAP3METHODS.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(xside_gap_3_methods(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = xsideGap3Methods_lookback, - expected = xside_gap_3_methods_lookback + object = talib:::xsideGap3Methods_lookback, + expected = talib:::xside_gap_3_methods_lookback ) }) diff --git a/tests/testthat/test-ta_CMO.R b/tests/testthat/test-ta_CMO.R index 60309aaf8..f73ef8a7e 100644 --- a/tests/testthat/test-ta_CMO.R +++ b/tests/testthat/test-ta_CMO.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(chande_momentum_oscillator(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = chandeMomentumOscillator_lookback, - expected = chande_momentum_oscillator_lookback + object = talib:::chandeMomentumOscillator_lookback, + expected = talib:::chande_momentum_oscillator_lookback ) }) diff --git a/tests/testthat/test-ta_DEMA.R b/tests/testthat/test-ta_DEMA.R index 8fd321bb1..fcba06a7a 100644 --- a/tests/testthat/test-ta_DEMA.R +++ b/tests/testthat/test-ta_DEMA.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(double_exponential_moving_average(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = doubleExponentialMovingAverage_lookback, - expected = double_exponential_moving_average_lookback + object = talib:::doubleExponentialMovingAverage_lookback, + expected = talib:::double_exponential_moving_average_lookback ) }) diff --git a/tests/testthat/test-ta_DX.R b/tests/testthat/test-ta_DX.R index 9948141cb..15c4e9061 100644 --- a/tests/testthat/test-ta_DX.R +++ b/tests/testthat/test-ta_DX.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(directional_movement_index(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = directionalMovementIndex_lookback, - expected = directional_movement_index_lookback + object = talib:::directionalMovementIndex_lookback, + expected = talib:::directional_movement_index_lookback ) }) diff --git a/tests/testthat/test-ta_EMA.R b/tests/testthat/test-ta_EMA.R index 50f493f8d..d6273f620 100644 --- a/tests/testthat/test-ta_EMA.R +++ b/tests/testthat/test-ta_EMA.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(exponential_moving_average(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = exponentialMovingAverage_lookback, - expected = exponential_moving_average_lookback + object = talib:::exponentialMovingAverage_lookback, + expected = talib:::exponential_moving_average_lookback ) }) diff --git a/tests/testthat/test-ta_HT_DCPERIOD.R b/tests/testthat/test-ta_HT_DCPERIOD.R index 4cd8490f4..fa5bf1f0a 100644 --- a/tests/testthat/test-ta_HT_DCPERIOD.R +++ b/tests/testthat/test-ta_HT_DCPERIOD.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(dominant_cycle_period(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = dominantCyclePeriod_lookback, - expected = dominant_cycle_period_lookback + object = talib:::dominantCyclePeriod_lookback, + expected = talib:::dominant_cycle_period_lookback ) }) diff --git a/tests/testthat/test-ta_HT_DCPHASE.R b/tests/testthat/test-ta_HT_DCPHASE.R index 06680bd3b..1dc664ddc 100644 --- a/tests/testthat/test-ta_HT_DCPHASE.R +++ b/tests/testthat/test-ta_HT_DCPHASE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(dominant_cycle_phase(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = dominantCyclePhase_lookback, - expected = dominant_cycle_phase_lookback + object = talib:::dominantCyclePhase_lookback, + expected = talib:::dominant_cycle_phase_lookback ) }) diff --git a/tests/testthat/test-ta_HT_PHASOR.R b/tests/testthat/test-ta_HT_PHASOR.R index d68729c49..d774875b2 100644 --- a/tests/testthat/test-ta_HT_PHASOR.R +++ b/tests/testthat/test-ta_HT_PHASOR.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(phasor_components(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = phasorComponents_lookback, - expected = phasor_components_lookback + object = talib:::phasorComponents_lookback, + expected = talib:::phasor_components_lookback ) }) diff --git a/tests/testthat/test-ta_HT_SINE.R b/tests/testthat/test-ta_HT_SINE.R index 9aeb09ada..92af5848c 100644 --- a/tests/testthat/test-ta_HT_SINE.R +++ b/tests/testthat/test-ta_HT_SINE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(sine_wave(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = sineWave_lookback, - expected = sine_wave_lookback + object = talib:::sineWave_lookback, + expected = talib:::sine_wave_lookback ) }) diff --git a/tests/testthat/test-ta_HT_TRENDLINE.R b/tests/testthat/test-ta_HT_TRENDLINE.R index 6d6c694e0..a32fb84ad 100644 --- a/tests/testthat/test-ta_HT_TRENDLINE.R +++ b/tests/testthat/test-ta_HT_TRENDLINE.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(trendline(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_HT_TRENDMODE.R b/tests/testthat/test-ta_HT_TRENDMODE.R index 7606d6f7e..b42877523 100644 --- a/tests/testthat/test-ta_HT_TRENDMODE.R +++ b/tests/testthat/test-ta_HT_TRENDMODE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(trend_cycle_mode(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = trendCycleMode_lookback, - expected = trend_cycle_mode_lookback + object = talib:::trendCycleMode_lookback, + expected = talib:::trend_cycle_mode_lookback ) }) diff --git a/tests/testthat/test-ta_IMI.R b/tests/testthat/test-ta_IMI.R index bc1f760e7..ed3736758 100644 --- a/tests/testthat/test-ta_IMI.R +++ b/tests/testthat/test-ta_IMI.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(intraday_movement_index(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = intradayMovementIndex_lookback, - expected = intraday_movement_index_lookback + object = talib:::intradayMovementIndex_lookback, + expected = talib:::intraday_movement_index_lookback ) }) diff --git a/tests/testthat/test-ta_KAMA.R b/tests/testthat/test-ta_KAMA.R index 802cc02b1..e501b2fde 100644 --- a/tests/testthat/test-ta_KAMA.R +++ b/tests/testthat/test-ta_KAMA.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(kaufman_adaptive_moving_average(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = kaufmanAdaptiveMovingAverage_lookback, - expected = kaufman_adaptive_moving_average_lookback + object = talib:::kaufmanAdaptiveMovingAverage_lookback, + expected = talib:::kaufman_adaptive_moving_average_lookback ) }) diff --git a/tests/testthat/test-ta_MACD.R b/tests/testthat/test-ta_MACD.R index 461f9d724..f1286795c 100644 --- a/tests/testthat/test-ta_MACD.R +++ b/tests/testthat/test-ta_MACD.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(moving_average_convergence_divergence(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -174,8 +183,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = movingAverageConvergenceDivergence_lookback, - expected = moving_average_convergence_divergence_lookback + object = talib:::movingAverageConvergenceDivergence_lookback, + expected = talib:::moving_average_convergence_divergence_lookback ) }) diff --git a/tests/testthat/test-ta_MACDEXT.R b/tests/testthat/test-ta_MACDEXT.R index ee5bf6b7c..51864364f 100644 --- a/tests/testthat/test-ta_MACDEXT.R +++ b/tests/testthat/test-ta_MACDEXT.R @@ -59,6 +59,18 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits( + extended_moving_average_convergence_divergence(GOOGL), + class(GOOGL) + ) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -183,8 +195,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = extendedMovingAverageConvergenceDivergence_lookback, - expected = extended_moving_average_convergence_divergence_lookback + object = talib:::extendedMovingAverageConvergenceDivergence_lookback, + expected = talib:::extended_moving_average_convergence_divergence_lookback ) }) diff --git a/tests/testthat/test-ta_MACDFIX.R b/tests/testthat/test-ta_MACDFIX.R index 962c1ff8e..29fdcf6d6 100644 --- a/tests/testthat/test-ta_MACDFIX.R +++ b/tests/testthat/test-ta_MACDFIX.R @@ -53,6 +53,18 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits( + fixed_moving_average_convergence_divergence(GOOGL), + class(GOOGL) + ) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -177,8 +189,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = fixedMovingAverageConvergenceDivergence_lookback, - expected = fixed_moving_average_convergence_divergence_lookback + object = talib:::fixedMovingAverageConvergenceDivergence_lookback, + expected = talib:::fixed_moving_average_convergence_divergence_lookback ) }) diff --git a/tests/testthat/test-ta_MAMA.R b/tests/testthat/test-ta_MAMA.R index 45b82b846..1c9c005d8 100644 --- a/tests/testthat/test-ta_MAMA.R +++ b/tests/testthat/test-ta_MAMA.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(mesa_adaptive_moving_average(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = mesaAdaptiveMovingAverage_lookback, - expected = mesa_adaptive_moving_average_lookback + object = talib:::mesaAdaptiveMovingAverage_lookback, + expected = talib:::mesa_adaptive_moving_average_lookback ) }) diff --git a/tests/testthat/test-ta_MAVP.R b/tests/testthat/test-ta_MAVP.R index fdea4cadb..909bb8e76 100644 --- a/tests/testthat/test-ta_MAVP.R +++ b/tests/testthat/test-ta_MAVP.R @@ -59,6 +59,21 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits( + variable_moving_average_period( + GOOGL, + periods = rep(5, nrow(GOOGL)) + ), + class(GOOGL) + ) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -196,8 +211,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = variableMovingAveragePeriod_lookback, - expected = variable_moving_average_period_lookback + object = talib:::variableMovingAveragePeriod_lookback, + expected = talib:::variable_moving_average_period_lookback ) }) diff --git a/tests/testthat/test-ta_MEDPRICE.R b/tests/testthat/test-ta_MEDPRICE.R index 3feef755a..dfc32133c 100644 --- a/tests/testthat/test-ta_MEDPRICE.R +++ b/tests/testthat/test-ta_MEDPRICE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(median_price(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,7 +180,7 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = medianPrice_lookback, - expected = median_price_lookback + object = talib:::medianPrice_lookback, + expected = talib:::median_price_lookback ) }) diff --git a/tests/testthat/test-ta_MFI.R b/tests/testthat/test-ta_MFI.R index 984f257e2..2ac14a929 100644 --- a/tests/testthat/test-ta_MFI.R +++ b/tests/testthat/test-ta_MFI.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(money_flow_index(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = moneyFlowIndex_lookback, - expected = money_flow_index_lookback + object = talib:::moneyFlowIndex_lookback, + expected = talib:::money_flow_index_lookback ) }) diff --git a/tests/testthat/test-ta_MIDPOINT.R b/tests/testthat/test-ta_MIDPOINT.R index 2431486bc..b3d237ced 100644 --- a/tests/testthat/test-ta_MIDPOINT.R +++ b/tests/testthat/test-ta_MIDPOINT.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(midpoint_period(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = midpointPeriod_lookback, - expected = midpoint_period_lookback + object = talib:::midpointPeriod_lookback, + expected = talib:::midpoint_period_lookback ) }) diff --git a/tests/testthat/test-ta_MIDPRICE.R b/tests/testthat/test-ta_MIDPRICE.R index d7427f7b4..fa9132026 100644 --- a/tests/testthat/test-ta_MIDPRICE.R +++ b/tests/testthat/test-ta_MIDPRICE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(midpoint_price(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = midpointPrice_lookback, - expected = midpoint_price_lookback + object = talib:::midpointPrice_lookback, + expected = talib:::midpoint_price_lookback ) }) diff --git a/tests/testthat/test-ta_MINUS_DI.R b/tests/testthat/test-ta_MINUS_DI.R index 0783afded..5bf06469b 100644 --- a/tests/testthat/test-ta_MINUS_DI.R +++ b/tests/testthat/test-ta_MINUS_DI.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(minus_directional_indicator(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = minusDirectionalIndicator_lookback, - expected = minus_directional_indicator_lookback + object = talib:::minusDirectionalIndicator_lookback, + expected = talib:::minus_directional_indicator_lookback ) }) diff --git a/tests/testthat/test-ta_MINUS_DM.R b/tests/testthat/test-ta_MINUS_DM.R index 12057c895..4eb52f96a 100644 --- a/tests/testthat/test-ta_MINUS_DM.R +++ b/tests/testthat/test-ta_MINUS_DM.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(minus_directional_movement(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = minusDirectionalMovement_lookback, - expected = minus_directional_movement_lookback + object = talib:::minusDirectionalMovement_lookback, + expected = talib:::minus_directional_movement_lookback ) }) diff --git a/tests/testthat/test-ta_MOM.R b/tests/testthat/test-ta_MOM.R index f58f4781e..558e63016 100644 --- a/tests/testthat/test-ta_MOM.R +++ b/tests/testthat/test-ta_MOM.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(momentum(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_NATR.R b/tests/testthat/test-ta_NATR.R index 7be93951c..378f775aa 100644 --- a/tests/testthat/test-ta_NATR.R +++ b/tests/testthat/test-ta_NATR.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(normalized_average_true_range(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = normalizedAverageTrueRange_lookback, - expected = normalized_average_true_range_lookback + object = talib:::normalizedAverageTrueRange_lookback, + expected = talib:::normalized_average_true_range_lookback ) }) diff --git a/tests/testthat/test-ta_OBV.R b/tests/testthat/test-ta_OBV.R index bb3efc449..91f3869e6 100644 --- a/tests/testthat/test-ta_OBV.R +++ b/tests/testthat/test-ta_OBV.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(on_balance_volume(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = onBalanceVolume_lookback, - expected = on_balance_volume_lookback + object = talib:::onBalanceVolume_lookback, + expected = talib:::on_balance_volume_lookback ) }) diff --git a/tests/testthat/test-ta_PLUS_DI.R b/tests/testthat/test-ta_PLUS_DI.R index fb69803dd..19b085ae9 100644 --- a/tests/testthat/test-ta_PLUS_DI.R +++ b/tests/testthat/test-ta_PLUS_DI.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(plus_directional_indicator(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = plusDirectionalIndicator_lookback, - expected = plus_directional_indicator_lookback + object = talib:::plusDirectionalIndicator_lookback, + expected = talib:::plus_directional_indicator_lookback ) }) diff --git a/tests/testthat/test-ta_PLUS_DM.R b/tests/testthat/test-ta_PLUS_DM.R index 08a95c80f..5a462177d 100644 --- a/tests/testthat/test-ta_PLUS_DM.R +++ b/tests/testthat/test-ta_PLUS_DM.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(plus_directional_movement(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = plusDirectionalMovement_lookback, - expected = plus_directional_movement_lookback + object = talib:::plusDirectionalMovement_lookback, + expected = talib:::plus_directional_movement_lookback ) }) diff --git a/tests/testthat/test-ta_PPO.R b/tests/testthat/test-ta_PPO.R index baaaefdb1..2839a0f77 100644 --- a/tests/testthat/test-ta_PPO.R +++ b/tests/testthat/test-ta_PPO.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(percentage_price_oscillator(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = percentagePriceOscillator_lookback, - expected = percentage_price_oscillator_lookback + object = talib:::percentagePriceOscillator_lookback, + expected = talib:::percentage_price_oscillator_lookback ) }) diff --git a/tests/testthat/test-ta_ROCR.R b/tests/testthat/test-ta_ROCR.R index 158b85d8d..3a52c25de 100644 --- a/tests/testthat/test-ta_ROCR.R +++ b/tests/testthat/test-ta_ROCR.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(ratio_of_change(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = ratioOfChange_lookback, - expected = ratio_of_change_lookback + object = talib:::ratioOfChange_lookback, + expected = talib:::ratio_of_change_lookback ) }) diff --git a/tests/testthat/test-ta_RSI.R b/tests/testthat/test-ta_RSI.R index efedda617..38c61e729 100644 --- a/tests/testthat/test-ta_RSI.R +++ b/tests/testthat/test-ta_RSI.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(relative_strength_index(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = relativeStrengthIndex_lookback, - expected = relative_strength_index_lookback + object = talib:::relativeStrengthIndex_lookback, + expected = talib:::relative_strength_index_lookback ) }) diff --git a/tests/testthat/test-ta_SAR.R b/tests/testthat/test-ta_SAR.R index 28cea0b41..521416a58 100644 --- a/tests/testthat/test-ta_SAR.R +++ b/tests/testthat/test-ta_SAR.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(parabolic_stop_and_reverse(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = parabolicStopAndReverse_lookback, - expected = parabolic_stop_and_reverse_lookback + object = talib:::parabolicStopAndReverse_lookback, + expected = talib:::parabolic_stop_and_reverse_lookback ) }) diff --git a/tests/testthat/test-ta_SAREXT.R b/tests/testthat/test-ta_SAREXT.R index 99fcea294..14d17f644 100644 --- a/tests/testthat/test-ta_SAREXT.R +++ b/tests/testthat/test-ta_SAREXT.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(extended_parabolic_stop_and_reverse(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = extendedParabolicStopAndReverse_lookback, - expected = extended_parabolic_stop_and_reverse_lookback + object = talib:::extendedParabolicStopAndReverse_lookback, + expected = talib:::extended_parabolic_stop_and_reverse_lookback ) }) diff --git a/tests/testthat/test-ta_SMA.R b/tests/testthat/test-ta_SMA.R index 6356c86e4..1a18d6994 100644 --- a/tests/testthat/test-ta_SMA.R +++ b/tests/testthat/test-ta_SMA.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(simple_moving_average(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = simpleMovingAverage_lookback, - expected = simple_moving_average_lookback + object = talib:::simpleMovingAverage_lookback, + expected = talib:::simple_moving_average_lookback ) }) diff --git a/tests/testthat/test-ta_STOCH.R b/tests/testthat/test-ta_STOCH.R index cbc6ef9e7..27258422e 100644 --- a/tests/testthat/test-ta_STOCH.R +++ b/tests/testthat/test-ta_STOCH.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(stochastic(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_STOCHF.R b/tests/testthat/test-ta_STOCHF.R index dd1fa7d74..7663422da 100644 --- a/tests/testthat/test-ta_STOCHF.R +++ b/tests/testthat/test-ta_STOCHF.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(fast_stochastic(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = fastStochastic_lookback, - expected = fast_stochastic_lookback + object = talib:::fastStochastic_lookback, + expected = talib:::fast_stochastic_lookback ) }) diff --git a/tests/testthat/test-ta_STOCHRSI.R b/tests/testthat/test-ta_STOCHRSI.R index d06027462..bfa5693e5 100644 --- a/tests/testthat/test-ta_STOCHRSI.R +++ b/tests/testthat/test-ta_STOCHRSI.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(stochastic_relative_strength_index(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = stochasticRelativeStrengthIndex_lookback, - expected = stochastic_relative_strength_index_lookback + object = talib:::stochasticRelativeStrengthIndex_lookback, + expected = talib:::stochastic_relative_strength_index_lookback ) }) diff --git a/tests/testthat/test-ta_T3.R b/tests/testthat/test-ta_T3.R index a895f4cc2..90618f2d3 100644 --- a/tests/testthat/test-ta_T3.R +++ b/tests/testthat/test-ta_T3.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(t3_exponential_moving_average(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = t3ExponentialMovingAverage_lookback, - expected = t3_exponential_moving_average_lookback + object = talib:::t3ExponentialMovingAverage_lookback, + expected = talib:::t3_exponential_moving_average_lookback ) }) diff --git a/tests/testthat/test-ta_TEMA.R b/tests/testthat/test-ta_TEMA.R index 2673c4212..098b9e1db 100644 --- a/tests/testthat/test-ta_TEMA.R +++ b/tests/testthat/test-ta_TEMA.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(triple_exponential_moving_average(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = tripleExponentialMovingAverage_lookback, - expected = triple_exponential_moving_average_lookback + object = talib:::tripleExponentialMovingAverage_lookback, + expected = talib:::triple_exponential_moving_average_lookback ) }) diff --git a/tests/testthat/test-ta_TRANGE.R b/tests/testthat/test-ta_TRANGE.R index c08da3233..370abca74 100644 --- a/tests/testthat/test-ta_TRANGE.R +++ b/tests/testthat/test-ta_TRANGE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(true_range(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = trueRange_lookback, - expected = true_range_lookback + object = talib:::trueRange_lookback, + expected = talib:::true_range_lookback ) }) diff --git a/tests/testthat/test-ta_TRIMA.R b/tests/testthat/test-ta_TRIMA.R index 999d10407..8b782824a 100644 --- a/tests/testthat/test-ta_TRIMA.R +++ b/tests/testthat/test-ta_TRIMA.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(triangular_moving_average(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = triangularMovingAverage_lookback, - expected = triangular_moving_average_lookback + object = talib:::triangularMovingAverage_lookback, + expected = talib:::triangular_moving_average_lookback ) }) diff --git a/tests/testthat/test-ta_TRIX.R b/tests/testthat/test-ta_TRIX.R index f4558b8ab..bd8ff0e67 100644 --- a/tests/testthat/test-ta_TRIX.R +++ b/tests/testthat/test-ta_TRIX.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(triple_exponential_average(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = tripleExponentialAverage_lookback, - expected = triple_exponential_average_lookback + object = talib:::tripleExponentialAverage_lookback, + expected = talib:::triple_exponential_average_lookback ) }) diff --git a/tests/testthat/test-ta_TYPPRICE.R b/tests/testthat/test-ta_TYPPRICE.R index 3563eadce..3c7991d25 100644 --- a/tests/testthat/test-ta_TYPPRICE.R +++ b/tests/testthat/test-ta_TYPPRICE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(typical_price(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,7 +180,7 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = typicalPrice_lookback, - expected = typical_price_lookback + object = talib:::typicalPrice_lookback, + expected = talib:::typical_price_lookback ) }) diff --git a/tests/testthat/test-ta_ULTOSC.R b/tests/testthat/test-ta_ULTOSC.R index 364a34a53..209d23bd5 100644 --- a/tests/testthat/test-ta_ULTOSC.R +++ b/tests/testthat/test-ta_ULTOSC.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(ultimate_oscillator(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = ultimateOscillator_lookback, - expected = ultimate_oscillator_lookback + object = talib:::ultimateOscillator_lookback, + expected = talib:::ultimate_oscillator_lookback ) }) diff --git a/tests/testthat/test-ta_VOLUME.R b/tests/testthat/test-ta_VOLUME.R index 2d5ad295f..9572409fc 100644 --- a/tests/testthat/test-ta_VOLUME.R +++ b/tests/testthat/test-ta_VOLUME.R @@ -42,6 +42,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(trading_volume(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_WCLPRICE.R b/tests/testthat/test-ta_WCLPRICE.R index 2da136640..f55b489d8 100644 --- a/tests/testthat/test-ta_WCLPRICE.R +++ b/tests/testthat/test-ta_WCLPRICE.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(weighted_close_price(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,7 +180,7 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = weightedClosePrice_lookback, - expected = weighted_close_price_lookback + object = talib:::weightedClosePrice_lookback, + expected = talib:::weighted_close_price_lookback ) }) diff --git a/tests/testthat/test-ta_WILLR.R b/tests/testthat/test-ta_WILLR.R index 94c622b69..c8d599381 100644 --- a/tests/testthat/test-ta_WILLR.R +++ b/tests/testthat/test-ta_WILLR.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(williams_oscillator(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = williamsOscillator_lookback, - expected = williams_oscillator_lookback + object = talib:::williamsOscillator_lookback, + expected = talib:::williams_oscillator_lookback ) }) diff --git a/tests/testthat/test-ta_WMA.R b/tests/testthat/test-ta_WMA.R index 1f04deb4a..d7e631177 100644 --- a/tests/testthat/test-ta_WMA.R +++ b/tests/testthat/test-ta_WMA.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(weighted_moving_average(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = weightedMovingAverage_lookback, - expected = weighted_moving_average_lookback + object = talib:::weightedMovingAverage_lookback, + expected = talib:::weighted_moving_average_lookback ) }) From 1c9d63ed0ae4c698804d6b1faa26a1d045654949 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 11:53:55 +0200 Subject: [PATCH 09/22] :hammer: Regenerated new indicators and unit-tests --- NAMESPACE | 138 +++++++++++++++++++++++++++++++++- R/ta_CMF.R | 52 +++++++++---- R/ta_CMOU.R | 52 +++++++++---- R/ta_HMA.R | 53 +++++++++---- R/ta_NVI.R | 48 ++++++++---- R/ta_PVI.R | 48 ++++++++---- R/ta_PVO.R | 60 +++++++++++---- R/ta_VWMA.R | 53 +++++++++---- tests/testthat/test-ta_CMF.R | 13 +++- tests/testthat/test-ta_CMOU.R | 13 +++- tests/testthat/test-ta_HMA.R | 13 +++- tests/testthat/test-ta_NVI.R | 13 +++- tests/testthat/test-ta_PVI.R | 13 +++- tests/testthat/test-ta_PVO.R | 13 +++- tests/testthat/test-ta_VWMA.R | 13 +++- 15 files changed, 482 insertions(+), 113 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 0d03aaad3..c2a65c4cd 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,274 +1,329 @@ # Generated by roxygen2: do not edit by hand S3method("$",chart_theme) +S3method("[[",ta_series) S3method(.DollarNames,chart_theme) S3method(abandoned_baby,data.frame) S3method(abandoned_baby,default) S3method(abandoned_baby,ggplot) S3method(abandoned_baby,matrix) S3method(abandoned_baby,plotly) +S3method(abandoned_baby,xts) S3method(absolute_price_oscillator,data.frame) S3method(absolute_price_oscillator,default) S3method(absolute_price_oscillator,ggplot) S3method(absolute_price_oscillator,matrix) S3method(absolute_price_oscillator,numeric) S3method(absolute_price_oscillator,plotly) +S3method(absolute_price_oscillator,xts) S3method(acceleration_bands,data.frame) S3method(acceleration_bands,default) S3method(acceleration_bands,ggplot) S3method(acceleration_bands,matrix) S3method(acceleration_bands,plotly) +S3method(acceleration_bands,xts) S3method(advance_block,data.frame) S3method(advance_block,default) S3method(advance_block,ggplot) S3method(advance_block,matrix) S3method(advance_block,plotly) +S3method(advance_block,xts) S3method(aroon,data.frame) S3method(aroon,default) S3method(aroon,ggplot) S3method(aroon,matrix) S3method(aroon,plotly) +S3method(aroon,xts) S3method(aroon_oscillator,data.frame) S3method(aroon_oscillator,default) S3method(aroon_oscillator,ggplot) S3method(aroon_oscillator,matrix) S3method(aroon_oscillator,plotly) +S3method(aroon_oscillator,xts) +S3method(as.data.frame,ta_object) S3method(as.maType,double) S3method(as.maType,integer) S3method(as.maType,maType) +S3method(as.matrix,ta_object) +S3method(as.xts,ta_object) S3method(average_deviation,data.frame) S3method(average_deviation,default) S3method(average_deviation,matrix) S3method(average_deviation,numeric) +S3method(average_deviation,xts) S3method(average_directional_movement_index,data.frame) S3method(average_directional_movement_index,default) S3method(average_directional_movement_index,ggplot) S3method(average_directional_movement_index,matrix) S3method(average_directional_movement_index,plotly) +S3method(average_directional_movement_index,xts) S3method(average_directional_movement_index_rating,data.frame) S3method(average_directional_movement_index_rating,default) S3method(average_directional_movement_index_rating,ggplot) S3method(average_directional_movement_index_rating,matrix) S3method(average_directional_movement_index_rating,plotly) +S3method(average_directional_movement_index_rating,xts) S3method(average_price,data.frame) S3method(average_price,default) S3method(average_price,matrix) +S3method(average_price,xts) S3method(average_true_range,data.frame) S3method(average_true_range,default) S3method(average_true_range,ggplot) S3method(average_true_range,matrix) S3method(average_true_range,plotly) +S3method(average_true_range,xts) S3method(balance_of_power,data.frame) S3method(balance_of_power,default) S3method(balance_of_power,ggplot) S3method(balance_of_power,matrix) S3method(balance_of_power,plotly) +S3method(balance_of_power,xts) S3method(belt_hold,data.frame) S3method(belt_hold,default) S3method(belt_hold,ggplot) S3method(belt_hold,matrix) S3method(belt_hold,plotly) +S3method(belt_hold,xts) S3method(bollinger_bands,data.frame) S3method(bollinger_bands,default) S3method(bollinger_bands,ggplot) S3method(bollinger_bands,matrix) S3method(bollinger_bands,numeric) S3method(bollinger_bands,plotly) +S3method(bollinger_bands,xts) S3method(break_away,data.frame) S3method(break_away,default) S3method(break_away,ggplot) S3method(break_away,matrix) S3method(break_away,plotly) +S3method(break_away,xts) S3method(build_plotly,plotly) S3method(chaikin_accumulation_distribution_line,data.frame) S3method(chaikin_accumulation_distribution_line,default) S3method(chaikin_accumulation_distribution_line,ggplot) S3method(chaikin_accumulation_distribution_line,matrix) S3method(chaikin_accumulation_distribution_line,plotly) +S3method(chaikin_accumulation_distribution_line,xts) S3method(chaikin_accumulation_distribution_oscillator,data.frame) S3method(chaikin_accumulation_distribution_oscillator,default) S3method(chaikin_accumulation_distribution_oscillator,ggplot) S3method(chaikin_accumulation_distribution_oscillator,matrix) S3method(chaikin_accumulation_distribution_oscillator,plotly) +S3method(chaikin_accumulation_distribution_oscillator,xts) S3method(chaikin_money_flow,data.frame) S3method(chaikin_money_flow,default) S3method(chaikin_money_flow,ggplot) S3method(chaikin_money_flow,matrix) S3method(chaikin_money_flow,plotly) +S3method(chaikin_money_flow,xts) S3method(chande_momentum_oscillator,data.frame) S3method(chande_momentum_oscillator,default) S3method(chande_momentum_oscillator,ggplot) S3method(chande_momentum_oscillator,matrix) S3method(chande_momentum_oscillator,numeric) S3method(chande_momentum_oscillator,plotly) +S3method(chande_momentum_oscillator,xts) S3method(chart,default) S3method(closing_marubozu,data.frame) S3method(closing_marubozu,default) S3method(closing_marubozu,ggplot) S3method(closing_marubozu,matrix) S3method(closing_marubozu,plotly) +S3method(closing_marubozu,xts) S3method(commodity_channel_index,data.frame) S3method(commodity_channel_index,default) S3method(commodity_channel_index,ggplot) S3method(commodity_channel_index,matrix) S3method(commodity_channel_index,plotly) +S3method(commodity_channel_index,xts) S3method(concealing_baby_swallow,data.frame) S3method(concealing_baby_swallow,default) S3method(concealing_baby_swallow,ggplot) S3method(concealing_baby_swallow,matrix) S3method(concealing_baby_swallow,plotly) +S3method(concealing_baby_swallow,xts) S3method(counter_attack,data.frame) S3method(counter_attack,default) S3method(counter_attack,ggplot) S3method(counter_attack,matrix) S3method(counter_attack,plotly) +S3method(counter_attack,xts) S3method(dark_cloud_cover,data.frame) S3method(dark_cloud_cover,default) S3method(dark_cloud_cover,ggplot) S3method(dark_cloud_cover,matrix) S3method(dark_cloud_cover,plotly) +S3method(dark_cloud_cover,xts) S3method(directional_movement_index,data.frame) S3method(directional_movement_index,default) S3method(directional_movement_index,ggplot) S3method(directional_movement_index,matrix) S3method(directional_movement_index,plotly) +S3method(directional_movement_index,xts) S3method(doji,data.frame) S3method(doji,default) S3method(doji,ggplot) S3method(doji,matrix) S3method(doji,plotly) +S3method(doji,xts) S3method(doji_star,data.frame) S3method(doji_star,default) S3method(doji_star,ggplot) S3method(doji_star,matrix) S3method(doji_star,plotly) +S3method(doji_star,xts) S3method(dominant_cycle_period,data.frame) S3method(dominant_cycle_period,default) S3method(dominant_cycle_period,ggplot) S3method(dominant_cycle_period,matrix) S3method(dominant_cycle_period,numeric) S3method(dominant_cycle_period,plotly) +S3method(dominant_cycle_period,xts) S3method(dominant_cycle_phase,data.frame) S3method(dominant_cycle_phase,default) S3method(dominant_cycle_phase,ggplot) S3method(dominant_cycle_phase,matrix) S3method(dominant_cycle_phase,numeric) S3method(dominant_cycle_phase,plotly) +S3method(dominant_cycle_phase,xts) S3method(double_exponential_moving_average,data.frame) S3method(double_exponential_moving_average,default) S3method(double_exponential_moving_average,ggplot) S3method(double_exponential_moving_average,matrix) S3method(double_exponential_moving_average,numeric) S3method(double_exponential_moving_average,plotly) +S3method(double_exponential_moving_average,xts) S3method(dragonfly_doji,data.frame) S3method(dragonfly_doji,default) S3method(dragonfly_doji,ggplot) S3method(dragonfly_doji,matrix) S3method(dragonfly_doji,plotly) +S3method(dragonfly_doji,xts) S3method(engulfing,data.frame) S3method(engulfing,default) S3method(engulfing,ggplot) S3method(engulfing,matrix) S3method(engulfing,plotly) +S3method(engulfing,xts) S3method(evening_doji_star,data.frame) S3method(evening_doji_star,default) S3method(evening_doji_star,ggplot) S3method(evening_doji_star,matrix) S3method(evening_doji_star,plotly) +S3method(evening_doji_star,xts) S3method(evening_star,data.frame) S3method(evening_star,default) S3method(evening_star,ggplot) S3method(evening_star,matrix) S3method(evening_star,plotly) +S3method(evening_star,xts) S3method(exponential_moving_average,data.frame) S3method(exponential_moving_average,default) S3method(exponential_moving_average,ggplot) S3method(exponential_moving_average,matrix) S3method(exponential_moving_average,numeric) S3method(exponential_moving_average,plotly) +S3method(exponential_moving_average,xts) S3method(extended_moving_average_convergence_divergence,data.frame) S3method(extended_moving_average_convergence_divergence,default) S3method(extended_moving_average_convergence_divergence,ggplot) S3method(extended_moving_average_convergence_divergence,matrix) S3method(extended_moving_average_convergence_divergence,numeric) S3method(extended_moving_average_convergence_divergence,plotly) +S3method(extended_moving_average_convergence_divergence,xts) S3method(extended_parabolic_stop_and_reverse,data.frame) S3method(extended_parabolic_stop_and_reverse,default) S3method(extended_parabolic_stop_and_reverse,ggplot) S3method(extended_parabolic_stop_and_reverse,matrix) S3method(extended_parabolic_stop_and_reverse,plotly) +S3method(extended_parabolic_stop_and_reverse,xts) S3method(fast_stochastic,data.frame) S3method(fast_stochastic,default) S3method(fast_stochastic,ggplot) S3method(fast_stochastic,matrix) S3method(fast_stochastic,plotly) +S3method(fast_stochastic,xts) S3method(fixed_moving_average_convergence_divergence,data.frame) S3method(fixed_moving_average_convergence_divergence,default) S3method(fixed_moving_average_convergence_divergence,ggplot) S3method(fixed_moving_average_convergence_divergence,matrix) S3method(fixed_moving_average_convergence_divergence,numeric) S3method(fixed_moving_average_convergence_divergence,plotly) +S3method(fixed_moving_average_convergence_divergence,xts) S3method(gaps_side_white,data.frame) S3method(gaps_side_white,default) S3method(gaps_side_white,ggplot) S3method(gaps_side_white,matrix) S3method(gaps_side_white,plotly) +S3method(gaps_side_white,xts) S3method(gravestone_doji,data.frame) S3method(gravestone_doji,default) S3method(gravestone_doji,ggplot) S3method(gravestone_doji,matrix) S3method(gravestone_doji,plotly) +S3method(gravestone_doji,xts) S3method(hammer,data.frame) S3method(hammer,default) S3method(hammer,ggplot) S3method(hammer,matrix) S3method(hammer,plotly) +S3method(hammer,xts) S3method(hanging_man,data.frame) S3method(hanging_man,default) S3method(hanging_man,ggplot) S3method(hanging_man,matrix) S3method(hanging_man,plotly) +S3method(hanging_man,xts) S3method(harami,data.frame) S3method(harami,default) S3method(harami,ggplot) S3method(harami,matrix) S3method(harami,plotly) +S3method(harami,xts) S3method(harami_cross,data.frame) S3method(harami_cross,default) S3method(harami_cross,ggplot) S3method(harami_cross,matrix) S3method(harami_cross,plotly) +S3method(harami_cross,xts) S3method(high_wave,data.frame) S3method(high_wave,default) S3method(high_wave,ggplot) S3method(high_wave,matrix) S3method(high_wave,plotly) +S3method(high_wave,xts) S3method(hikakke,data.frame) S3method(hikakke,default) S3method(hikakke,ggplot) S3method(hikakke,matrix) S3method(hikakke,plotly) +S3method(hikakke,xts) S3method(hikakke_mod,data.frame) S3method(hikakke_mod,default) S3method(hikakke_mod,ggplot) S3method(hikakke_mod,matrix) S3method(hikakke_mod,plotly) +S3method(hikakke_mod,xts) S3method(homing_pigeon,data.frame) S3method(homing_pigeon,default) S3method(homing_pigeon,ggplot) S3method(homing_pigeon,matrix) S3method(homing_pigeon,plotly) +S3method(homing_pigeon,xts) S3method(hull_moving_average,data.frame) S3method(hull_moving_average,default) S3method(hull_moving_average,ggplot) S3method(hull_moving_average,matrix) S3method(hull_moving_average,numeric) S3method(hull_moving_average,plotly) +S3method(hull_moving_average,xts) S3method(in_neck,data.frame) S3method(in_neck,default) S3method(in_neck,ggplot) S3method(in_neck,matrix) S3method(in_neck,plotly) +S3method(in_neck,xts) S3method(index,default) S3method(index,xts) S3method(indicator,"function") @@ -277,11 +332,13 @@ S3method(intraday_movement_index,default) S3method(intraday_movement_index,ggplot) S3method(intraday_movement_index,matrix) S3method(intraday_movement_index,plotly) +S3method(intraday_movement_index,xts) S3method(inverted_hammer,data.frame) S3method(inverted_hammer,default) S3method(inverted_hammer,ggplot) S3method(inverted_hammer,matrix) S3method(inverted_hammer,plotly) +S3method(inverted_hammer,xts) S3method(is.empty,character) S3method(is.empty,default) S3method(is.empty,list) @@ -291,168 +348,201 @@ S3method(kaufman_adaptive_moving_average,ggplot) S3method(kaufman_adaptive_moving_average,matrix) S3method(kaufman_adaptive_moving_average,numeric) S3method(kaufman_adaptive_moving_average,plotly) +S3method(kaufman_adaptive_moving_average,xts) S3method(kicking,data.frame) S3method(kicking,default) S3method(kicking,ggplot) S3method(kicking,matrix) S3method(kicking,plotly) +S3method(kicking,xts) S3method(kicking_baby_length,data.frame) S3method(kicking_baby_length,default) S3method(kicking_baby_length,ggplot) S3method(kicking_baby_length,matrix) S3method(kicking_baby_length,plotly) +S3method(kicking_baby_length,xts) S3method(ladder_bottom,data.frame) S3method(ladder_bottom,default) S3method(ladder_bottom,ggplot) S3method(ladder_bottom,matrix) S3method(ladder_bottom,plotly) +S3method(ladder_bottom,xts) S3method(long_legged_doji,data.frame) S3method(long_legged_doji,default) S3method(long_legged_doji,ggplot) S3method(long_legged_doji,matrix) S3method(long_legged_doji,plotly) +S3method(long_legged_doji,xts) S3method(long_line,data.frame) S3method(long_line,default) S3method(long_line,ggplot) S3method(long_line,matrix) S3method(long_line,plotly) +S3method(long_line,xts) S3method(map_dfr,double) S3method(map_dfr,integer) +S3method(map_dfr,ta_object) S3method(marubozu,data.frame) S3method(marubozu,default) S3method(marubozu,ggplot) S3method(marubozu,matrix) S3method(marubozu,plotly) +S3method(marubozu,xts) S3method(mat_hold,data.frame) S3method(mat_hold,default) S3method(mat_hold,ggplot) S3method(mat_hold,matrix) S3method(mat_hold,plotly) +S3method(mat_hold,xts) S3method(matching_low,data.frame) S3method(matching_low,default) S3method(matching_low,ggplot) S3method(matching_low,matrix) S3method(matching_low,plotly) +S3method(matching_low,xts) S3method(median_price,data.frame) S3method(median_price,default) S3method(median_price,matrix) +S3method(median_price,xts) S3method(mesa_adaptive_moving_average,data.frame) S3method(mesa_adaptive_moving_average,default) S3method(mesa_adaptive_moving_average,ggplot) S3method(mesa_adaptive_moving_average,matrix) S3method(mesa_adaptive_moving_average,numeric) S3method(mesa_adaptive_moving_average,plotly) +S3method(mesa_adaptive_moving_average,xts) S3method(midpoint_period,data.frame) S3method(midpoint_period,default) S3method(midpoint_period,ggplot) S3method(midpoint_period,matrix) S3method(midpoint_period,numeric) S3method(midpoint_period,plotly) +S3method(midpoint_period,xts) S3method(midpoint_price,data.frame) S3method(midpoint_price,default) S3method(midpoint_price,ggplot) S3method(midpoint_price,matrix) S3method(midpoint_price,plotly) +S3method(midpoint_price,xts) S3method(minus_directional_indicator,data.frame) S3method(minus_directional_indicator,default) S3method(minus_directional_indicator,ggplot) S3method(minus_directional_indicator,matrix) S3method(minus_directional_indicator,plotly) +S3method(minus_directional_indicator,xts) S3method(minus_directional_movement,data.frame) S3method(minus_directional_movement,default) S3method(minus_directional_movement,ggplot) S3method(minus_directional_movement,matrix) S3method(minus_directional_movement,plotly) +S3method(minus_directional_movement,xts) S3method(momentum,data.frame) S3method(momentum,default) S3method(momentum,ggplot) S3method(momentum,matrix) S3method(momentum,numeric) S3method(momentum,plotly) +S3method(momentum,xts) S3method(money_flow_index,data.frame) S3method(money_flow_index,default) S3method(money_flow_index,ggplot) S3method(money_flow_index,matrix) S3method(money_flow_index,plotly) +S3method(money_flow_index,xts) S3method(morning_doji_star,data.frame) S3method(morning_doji_star,default) S3method(morning_doji_star,ggplot) S3method(morning_doji_star,matrix) S3method(morning_doji_star,plotly) +S3method(morning_doji_star,xts) S3method(morning_star,data.frame) S3method(morning_star,default) S3method(morning_star,ggplot) S3method(morning_star,matrix) S3method(morning_star,plotly) +S3method(morning_star,xts) S3method(moving_average_convergence_divergence,data.frame) S3method(moving_average_convergence_divergence,default) S3method(moving_average_convergence_divergence,ggplot) S3method(moving_average_convergence_divergence,matrix) S3method(moving_average_convergence_divergence,numeric) S3method(moving_average_convergence_divergence,plotly) +S3method(moving_average_convergence_divergence,xts) S3method(negative_volume_index,data.frame) S3method(negative_volume_index,default) S3method(negative_volume_index,ggplot) S3method(negative_volume_index,matrix) S3method(negative_volume_index,plotly) +S3method(negative_volume_index,xts) S3method(normalized_average_true_range,data.frame) S3method(normalized_average_true_range,default) S3method(normalized_average_true_range,ggplot) S3method(normalized_average_true_range,matrix) S3method(normalized_average_true_range,plotly) +S3method(normalized_average_true_range,xts) S3method(on_balance_volume,data.frame) S3method(on_balance_volume,default) S3method(on_balance_volume,ggplot) S3method(on_balance_volume,matrix) S3method(on_balance_volume,plotly) +S3method(on_balance_volume,xts) S3method(on_neck,data.frame) S3method(on_neck,default) S3method(on_neck,ggplot) S3method(on_neck,matrix) S3method(on_neck,plotly) +S3method(on_neck,xts) S3method(parabolic_stop_and_reverse,data.frame) S3method(parabolic_stop_and_reverse,default) S3method(parabolic_stop_and_reverse,ggplot) S3method(parabolic_stop_and_reverse,matrix) S3method(parabolic_stop_and_reverse,plotly) +S3method(parabolic_stop_and_reverse,xts) S3method(percentage_price_oscillator,data.frame) S3method(percentage_price_oscillator,default) S3method(percentage_price_oscillator,ggplot) S3method(percentage_price_oscillator,matrix) S3method(percentage_price_oscillator,numeric) S3method(percentage_price_oscillator,plotly) +S3method(percentage_price_oscillator,xts) S3method(percentage_volume_oscillator,data.frame) S3method(percentage_volume_oscillator,default) S3method(percentage_volume_oscillator,ggplot) S3method(percentage_volume_oscillator,matrix) S3method(percentage_volume_oscillator,numeric) S3method(percentage_volume_oscillator,plotly) +S3method(percentage_volume_oscillator,xts) S3method(phasor_components,data.frame) S3method(phasor_components,default) S3method(phasor_components,ggplot) S3method(phasor_components,matrix) S3method(phasor_components,numeric) S3method(phasor_components,plotly) +S3method(phasor_components,xts) S3method(piercing,data.frame) S3method(piercing,default) S3method(piercing,ggplot) S3method(piercing,matrix) S3method(piercing,plotly) +S3method(piercing,xts) S3method(plus_directional_indicator,data.frame) S3method(plus_directional_indicator,default) S3method(plus_directional_indicator,ggplot) S3method(plus_directional_indicator,matrix) S3method(plus_directional_indicator,plotly) +S3method(plus_directional_indicator,xts) S3method(plus_directional_movement,data.frame) S3method(plus_directional_movement,default) S3method(plus_directional_movement,ggplot) S3method(plus_directional_movement,matrix) S3method(plus_directional_movement,plotly) +S3method(plus_directional_movement,xts) S3method(positive_volume_index,data.frame) S3method(positive_volume_index,default) S3method(positive_volume_index,ggplot) S3method(positive_volume_index,matrix) S3method(positive_volume_index,plotly) +S3method(positive_volume_index,xts) S3method(print,talib_chart) S3method(print,talib_gg_chart) S3method(ratio_of_change,data.frame) @@ -461,22 +551,26 @@ S3method(ratio_of_change,ggplot) S3method(ratio_of_change,matrix) S3method(ratio_of_change,numeric) S3method(ratio_of_change,plotly) +S3method(ratio_of_change,xts) S3method(relative_strength_index,data.frame) S3method(relative_strength_index,default) S3method(relative_strength_index,ggplot) S3method(relative_strength_index,matrix) S3method(relative_strength_index,numeric) S3method(relative_strength_index,plotly) +S3method(relative_strength_index,xts) S3method(rickshaw_man,data.frame) S3method(rickshaw_man,default) S3method(rickshaw_man,ggplot) S3method(rickshaw_man,matrix) S3method(rickshaw_man,plotly) +S3method(rickshaw_man,xts) S3method(rise_fall_3_methods,data.frame) S3method(rise_fall_3_methods,default) S3method(rise_fall_3_methods,ggplot) S3method(rise_fall_3_methods,matrix) S3method(rise_fall_3_methods,plotly) +S3method(rise_fall_3_methods,xts) S3method(rolling_beta,default) S3method(rolling_beta,numeric) S3method(rolling_correlation,default) @@ -496,9 +590,12 @@ S3method(separating_lines,default) S3method(separating_lines,ggplot) S3method(separating_lines,matrix) S3method(separating_lines,plotly) -S3method(series,formula) +S3method(separating_lines,xts) +S3method(series,data.frame) S3method(series,ggplot) +S3method(series,matrix) S3method(series,plotly) +S3method(series,xts) S3method(set_index,character) S3method(set_index,numeric) S3method(set_rownames,data.frame) @@ -508,105 +605,125 @@ S3method(shooting_star,default) S3method(shooting_star,ggplot) S3method(shooting_star,matrix) S3method(shooting_star,plotly) +S3method(shooting_star,xts) S3method(short_line,data.frame) S3method(short_line,default) S3method(short_line,ggplot) S3method(short_line,matrix) S3method(short_line,plotly) +S3method(short_line,xts) S3method(simple_moving_average,data.frame) S3method(simple_moving_average,default) S3method(simple_moving_average,ggplot) S3method(simple_moving_average,matrix) S3method(simple_moving_average,numeric) S3method(simple_moving_average,plotly) +S3method(simple_moving_average,xts) S3method(sine_wave,data.frame) S3method(sine_wave,default) S3method(sine_wave,ggplot) S3method(sine_wave,matrix) S3method(sine_wave,numeric) S3method(sine_wave,plotly) +S3method(sine_wave,xts) S3method(spinning_top,data.frame) S3method(spinning_top,default) S3method(spinning_top,ggplot) S3method(spinning_top,matrix) S3method(spinning_top,plotly) +S3method(spinning_top,xts) S3method(stalled_pattern,data.frame) S3method(stalled_pattern,default) S3method(stalled_pattern,ggplot) S3method(stalled_pattern,matrix) S3method(stalled_pattern,plotly) +S3method(stalled_pattern,xts) S3method(stick_sandwich,data.frame) S3method(stick_sandwich,default) S3method(stick_sandwich,ggplot) S3method(stick_sandwich,matrix) S3method(stick_sandwich,plotly) +S3method(stick_sandwich,xts) S3method(stochastic,data.frame) S3method(stochastic,default) S3method(stochastic,ggplot) S3method(stochastic,matrix) S3method(stochastic,plotly) +S3method(stochastic,xts) S3method(stochastic_relative_strength_index,data.frame) S3method(stochastic_relative_strength_index,default) S3method(stochastic_relative_strength_index,ggplot) S3method(stochastic_relative_strength_index,matrix) S3method(stochastic_relative_strength_index,numeric) S3method(stochastic_relative_strength_index,plotly) +S3method(stochastic_relative_strength_index,xts) S3method(t3_exponential_moving_average,data.frame) S3method(t3_exponential_moving_average,default) S3method(t3_exponential_moving_average,ggplot) S3method(t3_exponential_moving_average,matrix) S3method(t3_exponential_moving_average,numeric) S3method(t3_exponential_moving_average,plotly) +S3method(t3_exponential_moving_average,xts) S3method(takuri,data.frame) S3method(takuri,default) S3method(takuri,ggplot) S3method(takuri,matrix) S3method(takuri,plotly) +S3method(takuri,xts) S3method(tasuki_gap,data.frame) S3method(tasuki_gap,default) S3method(tasuki_gap,ggplot) S3method(tasuki_gap,matrix) S3method(tasuki_gap,plotly) +S3method(tasuki_gap,xts) S3method(three_black_crows,data.frame) S3method(three_black_crows,default) S3method(three_black_crows,ggplot) S3method(three_black_crows,matrix) S3method(three_black_crows,plotly) +S3method(three_black_crows,xts) S3method(three_identical_crows,data.frame) S3method(three_identical_crows,default) S3method(three_identical_crows,ggplot) S3method(three_identical_crows,matrix) S3method(three_identical_crows,plotly) +S3method(three_identical_crows,xts) S3method(three_inside,data.frame) S3method(three_inside,default) S3method(three_inside,ggplot) S3method(three_inside,matrix) S3method(three_inside,plotly) +S3method(three_inside,xts) S3method(three_line_strike,data.frame) S3method(three_line_strike,default) S3method(three_line_strike,ggplot) S3method(three_line_strike,matrix) S3method(three_line_strike,plotly) +S3method(three_line_strike,xts) S3method(three_outside,data.frame) S3method(three_outside,default) S3method(three_outside,ggplot) S3method(three_outside,matrix) S3method(three_outside,plotly) +S3method(three_outside,xts) S3method(three_stars_in_the_south,data.frame) S3method(three_stars_in_the_south,default) S3method(three_stars_in_the_south,ggplot) S3method(three_stars_in_the_south,matrix) S3method(three_stars_in_the_south,plotly) +S3method(three_stars_in_the_south,xts) S3method(three_white_soldiers,data.frame) S3method(three_white_soldiers,default) S3method(three_white_soldiers,ggplot) S3method(three_white_soldiers,matrix) S3method(three_white_soldiers,plotly) +S3method(three_white_soldiers,xts) S3method(thrusting,data.frame) S3method(thrusting,default) S3method(thrusting,ggplot) S3method(thrusting,matrix) S3method(thrusting,plotly) +S3method(thrusting,xts) S3method(trading_volume,data.frame) S3method(trading_volume,default) S3method(trading_volume,ggplot) @@ -619,100 +736,119 @@ S3method(trend_cycle_mode,ggplot) S3method(trend_cycle_mode,matrix) S3method(trend_cycle_mode,numeric) S3method(trend_cycle_mode,plotly) +S3method(trend_cycle_mode,xts) S3method(trendline,data.frame) S3method(trendline,default) S3method(trendline,ggplot) S3method(trendline,matrix) S3method(trendline,numeric) S3method(trendline,plotly) +S3method(trendline,xts) S3method(triangular_moving_average,data.frame) S3method(triangular_moving_average,default) S3method(triangular_moving_average,ggplot) S3method(triangular_moving_average,matrix) S3method(triangular_moving_average,numeric) S3method(triangular_moving_average,plotly) +S3method(triangular_moving_average,xts) S3method(triple_exponential_average,data.frame) S3method(triple_exponential_average,default) S3method(triple_exponential_average,ggplot) S3method(triple_exponential_average,matrix) S3method(triple_exponential_average,numeric) S3method(triple_exponential_average,plotly) +S3method(triple_exponential_average,xts) S3method(triple_exponential_moving_average,data.frame) S3method(triple_exponential_moving_average,default) S3method(triple_exponential_moving_average,ggplot) S3method(triple_exponential_moving_average,matrix) S3method(triple_exponential_moving_average,numeric) S3method(triple_exponential_moving_average,plotly) +S3method(triple_exponential_moving_average,xts) S3method(tristar,data.frame) S3method(tristar,default) S3method(tristar,ggplot) S3method(tristar,matrix) S3method(tristar,plotly) +S3method(tristar,xts) S3method(true_range,data.frame) S3method(true_range,default) S3method(true_range,ggplot) S3method(true_range,matrix) S3method(true_range,plotly) +S3method(true_range,xts) S3method(two_crows,data.frame) S3method(two_crows,default) S3method(two_crows,ggplot) S3method(two_crows,matrix) S3method(two_crows,plotly) +S3method(two_crows,xts) S3method(typical_price,data.frame) S3method(typical_price,default) S3method(typical_price,matrix) +S3method(typical_price,xts) S3method(ultimate_oscillator,data.frame) S3method(ultimate_oscillator,default) S3method(ultimate_oscillator,ggplot) S3method(ultimate_oscillator,matrix) S3method(ultimate_oscillator,plotly) +S3method(ultimate_oscillator,xts) S3method(unique_3_river,data.frame) S3method(unique_3_river,default) S3method(unique_3_river,ggplot) S3method(unique_3_river,matrix) S3method(unique_3_river,plotly) +S3method(unique_3_river,xts) S3method(unsmoothed_chande_momentum_oscillator,data.frame) S3method(unsmoothed_chande_momentum_oscillator,default) S3method(unsmoothed_chande_momentum_oscillator,ggplot) S3method(unsmoothed_chande_momentum_oscillator,matrix) S3method(unsmoothed_chande_momentum_oscillator,numeric) S3method(unsmoothed_chande_momentum_oscillator,plotly) +S3method(unsmoothed_chande_momentum_oscillator,xts) S3method(upside_gap_2_crows,data.frame) S3method(upside_gap_2_crows,default) S3method(upside_gap_2_crows,ggplot) S3method(upside_gap_2_crows,matrix) S3method(upside_gap_2_crows,plotly) +S3method(upside_gap_2_crows,xts) S3method(variable_moving_average_period,data.frame) S3method(variable_moving_average_period,default) S3method(variable_moving_average_period,ggplot) S3method(variable_moving_average_period,matrix) S3method(variable_moving_average_period,numeric) S3method(variable_moving_average_period,plotly) +S3method(variable_moving_average_period,xts) S3method(volume_weighted_moving_average,data.frame) S3method(volume_weighted_moving_average,default) S3method(volume_weighted_moving_average,ggplot) S3method(volume_weighted_moving_average,matrix) S3method(volume_weighted_moving_average,numeric) S3method(volume_weighted_moving_average,plotly) +S3method(volume_weighted_moving_average,xts) S3method(weighted_close_price,data.frame) S3method(weighted_close_price,default) S3method(weighted_close_price,matrix) +S3method(weighted_close_price,xts) S3method(weighted_moving_average,data.frame) S3method(weighted_moving_average,default) S3method(weighted_moving_average,ggplot) S3method(weighted_moving_average,matrix) S3method(weighted_moving_average,numeric) S3method(weighted_moving_average,plotly) +S3method(weighted_moving_average,xts) S3method(williams_oscillator,data.frame) S3method(williams_oscillator,default) S3method(williams_oscillator,ggplot) S3method(williams_oscillator,matrix) S3method(williams_oscillator,plotly) +S3method(williams_oscillator,xts) S3method(xside_gap_3_methods,data.frame) S3method(xside_gap_3_methods,default) S3method(xside_gap_3_methods,ggplot) S3method(xside_gap_3_methods,matrix) S3method(xside_gap_3_methods,plotly) +S3method(xside_gap_3_methods,xts) export(ACCBANDS) export(AD) export(ADOSC) diff --git a/R/ta_CMF.R b/R/ta_CMF.R index fe14c12fc..b340c2262 100644 --- a/R/ta_CMF.R +++ b/R/ta_CMF.R @@ -58,15 +58,15 @@ chaikin_money_flow.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ high + low + close + volume, - data = x, + x = x, + formula = cols, + formula.default = ~ high + low + close + volume, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -81,7 +81,7 @@ chaikin_money_flow.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -98,7 +98,7 @@ chaikin_money_flow.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( chaikin_money_flow.default( x = x, cols = cols, @@ -120,12 +120,36 @@ chaikin_money_flow.matrix <- function( na.bridge = FALSE, ... ) { - chaikin_money_flow.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + chaikin_money_flow.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases chaikin_money_flow +#' +#' @export +chaikin_money_flow.xts <- function( + x, + cols, + timePeriod = 20, + na.bridge = FALSE, + ... +) { + as.xts( + chaikin_money_flow.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -172,7 +196,7 @@ chaikin_money_flow.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close + volume, + formula.default = ~ high + low + close + volume, ... ) @@ -272,7 +296,7 @@ chaikin_money_flow.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ high + low + close + volume, + formula.default = ~ high + low + close + volume, ... ) diff --git a/R/ta_CMOU.R b/R/ta_CMOU.R index c9a45bbd3..85726887e 100644 --- a/R/ta_CMOU.R +++ b/R/ta_CMOU.R @@ -58,15 +58,15 @@ unsmoothed_chande_momentum_oscillator.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula = cols, + formula.default = ~close, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -78,7 +78,7 @@ unsmoothed_chande_momentum_oscillator.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -95,7 +95,7 @@ unsmoothed_chande_momentum_oscillator.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( unsmoothed_chande_momentum_oscillator.default( x = x, cols = cols, @@ -117,12 +117,36 @@ unsmoothed_chande_momentum_oscillator.matrix <- function( na.bridge = FALSE, ... ) { - unsmoothed_chande_momentum_oscillator.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + unsmoothed_chande_momentum_oscillator.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases unsmoothed_chande_momentum_oscillator +#' +#' @export +unsmoothed_chande_momentum_oscillator.xts <- function( + x, + cols, + timePeriod = 14, + na.bridge = FALSE, + ... +) { + as.xts( + unsmoothed_chande_momentum_oscillator.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } @@ -204,7 +228,7 @@ unsmoothed_chande_momentum_oscillator.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -304,7 +328,7 @@ unsmoothed_chande_momentum_oscillator.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_HMA.R b/R/ta_HMA.R index 53692c7c6..fef2435a0 100644 --- a/R/ta_HMA.R +++ b/R/ta_HMA.R @@ -84,15 +84,15 @@ hull_moving_average.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~close, - data = x, + x = x, + formula.default = ~close, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -104,7 +104,7 @@ hull_moving_average.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -121,7 +121,7 @@ hull_moving_average.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( hull_moving_average.default( x = x, cols = cols, @@ -143,15 +143,40 @@ hull_moving_average.matrix <- function( na.bridge = FALSE, ... ) { - hull_moving_average.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + hull_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } +#' @usage NULL +#' @aliases hull_moving_average +#' +#' @export +hull_moving_average.xts <- function( + x, + cols, + timePeriod = 20, + na.bridge = FALSE, + ... +) { + as.xts( + hull_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + + #' @usage NULL #' @aliases hull_moving_average #' @@ -228,7 +253,7 @@ hull_moving_average.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) @@ -297,7 +322,7 @@ hull_moving_average.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~close, + formula.default = ~close, ... ) diff --git a/R/ta_NVI.R b/R/ta_NVI.R index a03bb6b08..ad9509803 100644 --- a/R/ta_NVI.R +++ b/R/ta_NVI.R @@ -56,15 +56,15 @@ negative_volume_index.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ close + volume, - data = x, + x = x, + formula = cols, + formula.default = ~ close + volume, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -76,7 +76,7 @@ negative_volume_index.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -92,7 +92,7 @@ negative_volume_index.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( negative_volume_index.default( x = x, cols = cols, @@ -112,11 +112,33 @@ negative_volume_index.matrix <- function( na.bridge = FALSE, ... ) { - negative_volume_index.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + negative_volume_index.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases negative_volume_index +#' +#' @export +negative_volume_index.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + negative_volume_index.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } @@ -160,7 +182,7 @@ negative_volume_index.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ close + volume, + formula.default = ~ close + volume, ... ) @@ -258,7 +280,7 @@ negative_volume_index.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ close + volume, + formula.default = ~ close + volume, ... ) diff --git a/R/ta_PVI.R b/R/ta_PVI.R index 028442976..eb31c8d8f 100644 --- a/R/ta_PVI.R +++ b/R/ta_PVI.R @@ -56,15 +56,15 @@ positive_volume_index.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ close + volume, - data = x, + x = x, + formula = cols, + formula.default = ~ close + volume, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -76,7 +76,7 @@ positive_volume_index.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -92,7 +92,7 @@ positive_volume_index.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( positive_volume_index.default( x = x, cols = cols, @@ -112,11 +112,33 @@ positive_volume_index.matrix <- function( na.bridge = FALSE, ... ) { - positive_volume_index.default( - x = x, - cols = cols, - na.bridge = na.bridge, - ... + as.matrix( + positive_volume_index.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases positive_volume_index +#' +#' @export +positive_volume_index.xts <- function( + x, + cols, + na.bridge = FALSE, + ... +) { + as.xts( + positive_volume_index.default( + x = x, + cols = cols, + na.bridge = na.bridge, + ... + ) ) } @@ -160,7 +182,7 @@ positive_volume_index.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ close + volume, + formula.default = ~ close + volume, ... ) @@ -258,7 +280,7 @@ positive_volume_index.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ close + volume, + formula.default = ~ close + volume, ... ) diff --git a/R/ta_PVO.R b/R/ta_PVO.R index 4ac93d36c..ce2336e1c 100644 --- a/R/ta_PVO.R +++ b/R/ta_PVO.R @@ -64,15 +64,15 @@ percentage_volume_oscillator.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~volume, - data = x, + x = x, + formula = cols, + formula.default = ~volume, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -86,7 +86,7 @@ percentage_volume_oscillator.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -105,7 +105,7 @@ percentage_volume_oscillator.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( percentage_volume_oscillator.default( x = x, cols = cols, @@ -131,14 +131,42 @@ percentage_volume_oscillator.matrix <- function( na.bridge = FALSE, ... ) { - percentage_volume_oscillator.default( - x = x, - cols = cols, - fastPeriod = fastPeriod, - slowPeriod = slowPeriod, - maType = maType, - na.bridge = na.bridge, - ... + as.matrix( + percentage_volume_oscillator.default( + x = x, + cols = cols, + fastPeriod = fastPeriod, + slowPeriod = slowPeriod, + maType = maType, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases percentage_volume_oscillator +#' +#' @export +percentage_volume_oscillator.xts <- function( + x, + cols, + fastPeriod = 12, + slowPeriod = 26, + maType = 1, + na.bridge = FALSE, + ... +) { + as.xts( + percentage_volume_oscillator.default( + x = x, + cols = cols, + fastPeriod = fastPeriod, + slowPeriod = slowPeriod, + maType = maType, + na.bridge = na.bridge, + ... + ) ) } @@ -230,7 +258,7 @@ percentage_volume_oscillator.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~volume, + formula.default = ~volume, ... ) @@ -334,7 +362,7 @@ percentage_volume_oscillator.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~volume, + formula.default = ~volume, ... ) diff --git a/R/ta_VWMA.R b/R/ta_VWMA.R index 7e77bb4ca..59e0059f2 100644 --- a/R/ta_VWMA.R +++ b/R/ta_VWMA.R @@ -84,15 +84,15 @@ volume_weighted_moving_average.default <- function( ## construct series ## from input constructed_series <- series( - x = cols, - default_formula = ~ close + volume, - data = x, + x = x, + formula.default = ~ close + volume, + formula = cols, ... ) ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -105,7 +105,7 @@ volume_weighted_moving_average.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -122,7 +122,7 @@ volume_weighted_moving_average.data.frame <- function( na.bridge = FALSE, ... ) { - map_dfr( + as.data.frame( volume_weighted_moving_average.default( x = x, cols = cols, @@ -144,15 +144,40 @@ volume_weighted_moving_average.matrix <- function( na.bridge = FALSE, ... ) { - volume_weighted_moving_average.default( - x = x, - cols = cols, - timePeriod = timePeriod, - na.bridge = na.bridge, - ... + as.matrix( + volume_weighted_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) ) } +#' @usage NULL +#' @aliases volume_weighted_moving_average +#' +#' @export +volume_weighted_moving_average.xts <- function( + x, + cols, + timePeriod = 30, + na.bridge = FALSE, + ... +) { + as.xts( + volume_weighted_moving_average.default( + x = x, + cols = cols, + timePeriod = timePeriod, + na.bridge = na.bridge, + ... + ) + ) +} + + #' @usage NULL #' @aliases volume_weighted_moving_average #' @@ -229,7 +254,7 @@ volume_weighted_moving_average.plotly <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ close + volume, + formula.default = ~ close + volume, ... ) @@ -298,7 +323,7 @@ volume_weighted_moving_average.ggplot <- function( constructed_series <- series( x = x, formula = cols, - default_formula = ~ close + volume, + formula.default = ~ close + volume, ... ) diff --git a/tests/testthat/test-ta_CMF.R b/tests/testthat/test-ta_CMF.R index d6037c57f..e78ab73bf 100644 --- a/tests/testthat/test-ta_CMF.R +++ b/tests/testthat/test-ta_CMF.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(chaikin_money_flow(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = chaikinMoneyFlow_lookback, - expected = chaikin_money_flow_lookback + object = talib:::chaikinMoneyFlow_lookback, + expected = talib:::chaikin_money_flow_lookback ) }) diff --git a/tests/testthat/test-ta_CMOU.R b/tests/testthat/test-ta_CMOU.R index 967ccea0d..ec9d25da3 100644 --- a/tests/testthat/test-ta_CMOU.R +++ b/tests/testthat/test-ta_CMOU.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(unsmoothed_chande_momentum_oscillator(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -174,8 +183,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = unsmoothedChandeMomentumOscillator_lookback, - expected = unsmoothed_chande_momentum_oscillator_lookback + object = talib:::unsmoothedChandeMomentumOscillator_lookback, + expected = talib:::unsmoothed_chande_momentum_oscillator_lookback ) }) diff --git a/tests/testthat/test-ta_HMA.R b/tests/testthat/test-ta_HMA.R index bca9ad22f..451540a64 100644 --- a/tests/testthat/test-ta_HMA.R +++ b/tests/testthat/test-ta_HMA.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(hull_moving_average(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = hullMovingAverage_lookback, - expected = hull_moving_average_lookback + object = talib:::hullMovingAverage_lookback, + expected = talib:::hull_moving_average_lookback ) }) diff --git a/tests/testthat/test-ta_NVI.R b/tests/testthat/test-ta_NVI.R index 88e844a63..81bea7a26 100644 --- a/tests/testthat/test-ta_NVI.R +++ b/tests/testthat/test-ta_NVI.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(negative_volume_index(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = negativeVolumeIndex_lookback, - expected = negative_volume_index_lookback + object = talib:::negativeVolumeIndex_lookback, + expected = talib:::negative_volume_index_lookback ) }) diff --git a/tests/testthat/test-ta_PVI.R b/tests/testthat/test-ta_PVI.R index f0f1946db..dbeb17061 100644 --- a/tests/testthat/test-ta_PVI.R +++ b/tests/testthat/test-ta_PVI.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(positive_volume_index(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = positiveVolumeIndex_lookback, - expected = positive_volume_index_lookback + object = talib:::positiveVolumeIndex_lookback, + expected = talib:::positive_volume_index_lookback ) }) diff --git a/tests/testthat/test-ta_PVO.R b/tests/testthat/test-ta_PVO.R index e690f585e..348e09fad 100644 --- a/tests/testthat/test-ta_PVO.R +++ b/tests/testthat/test-ta_PVO.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(percentage_volume_oscillator(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = percentageVolumeOscillator_lookback, - expected = percentage_volume_oscillator_lookback + object = talib:::percentageVolumeOscillator_lookback, + expected = talib:::percentage_volume_oscillator_lookback ) }) diff --git a/tests/testthat/test-ta_VWMA.R b/tests/testthat/test-ta_VWMA.R index 06315df74..1b10cbd72 100644 --- a/tests/testthat/test-ta_VWMA.R +++ b/tests/testthat/test-ta_VWMA.R @@ -53,6 +53,15 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + ## 1) check that the output class + ## matches the input class + testthat::expect_true( + inherits(volume_weighted_moving_average(GOOGL), class(GOOGL)) + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -171,8 +180,8 @@ testthat::test_that(desc = 'Lookback equivalence', code = { ## the camelCase lookback alias ## is the function itself testthat::expect_identical( - object = volumeWeightedMovingAverage_lookback, - expected = volume_weighted_moving_average_lookback + object = talib:::volumeWeightedMovingAverage_lookback, + expected = talib:::volume_weighted_moving_average_lookback ) }) From 1de50f94a1210f8e639a31787e831b132cca4531 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 12:22:27 +0200 Subject: [PATCH 10/22] :books: Updated NEWS with -methods --- NEWS.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/NEWS.md b/NEWS.md index e6a89c34d..3364bf493 100644 --- a/NEWS.md +++ b/NEWS.md @@ -21,6 +21,28 @@ Its use-case is customized control-flows for downstream wrappers and/or packages * The source code have been re-written so it generates the underlying TA-Lib wrappers using preprocessors and X-Macros, which compiles much faster than before. +* _**\**-methods:_—All indicators now supports \-objects. These methods are considered the primary entry point for *all* indicators, and can be considered stable from v1.0.0, where changes—if any—will be implemented gradually after a deprecation period. The method uses the same signature as before, see the example below: + +``` r +library(xts) + +tail( + x <- talib::bollinger_bands( + talib::GOOGL + ) +) +#> UpperBand MiddleBand LowerBand +#> 2021-12-22 149.1432 144.4920 139.8408 +#> 2021-12-23 149.2513 144.5318 139.8124 +#> 2021-12-27 149.6263 144.8180 140.0097 +#> 2021-12-28 149.7444 144.8758 140.0072 +#> 2021-12-29 149.8398 145.1137 140.3876 +#> 2021-12-30 149.7308 145.3711 141.0115 + +class(x) +#> [1] "xts" "zoo" +``` + * _**MAVP:** Moving Average Variable Periods_—The function calculates a moving average with variable periods between candles. See below: ```R From 03ce82ab3dd638ec13306fe71d23b490b254d154 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 14:36:43 +0200 Subject: [PATCH 11/22] :bug:-fix: indicator() were using old arguments --- man/examples/indicator.R | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/man/examples/indicator.R b/man/examples/indicator.R index 31707f426..8394d4bcd 100644 --- a/man/examples/indicator.R +++ b/man/examples/indicator.R @@ -4,20 +4,20 @@ data(BTC, package = "talib") ## standalone indicator chart ## (no prior chart() call needed) talib::indicator( - talib::RSI, - data = BTC + talib::RSI, + data = BTC ) ## attach an indicator to a price chart talib::chart(BTC) -talib::indicator(talib::RSI, n = 14) +talib::indicator(talib::RSI, timePeriod = 14) ## multiple indicators on the same panel talib::chart(BTC) talib::indicator( - talib::RSI(n = 10), - talib::RSI(n = 14), - talib::RSI(n = 21) + talib::RSI(timePeriod = 10), + talib::RSI(timePeriod = 14), + talib::RSI(timePeriod = 21) ) ## reset chart state From 0742f7ee62596158e9ce1acc561efbd88cfc09e1 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 15:21:06 +0200 Subject: [PATCH 12/22] :bug: Rewrote column-resolution in series.xts() * series.xts() now resolves each formula variable to exactly one column - exact name matches first, then quantmod-style suffix matches (close -> TICKER.Close), both case-insensitive and regex-free - and returns the columns in formula order, so the C layer receives high/low/close/... in the positions the indicator expects regardless of the physical column layout of the . * This fixes silently wrong values for multi-input indicators on reordered or substring-colliding column layouts, honors explicit 'cols =' selections exactly, errors on missing or ambiguous columns instead of computing on arbitrary ones, and accepts lowercase open/high/low/close names. * Unused model.frame-arguments ('subset', ...) now warn instead of being silently dropped. Chart data overrides with quantmod-named (indicator(RSI, data = x)) resolve through the same path and now work. --- R/series.R | 137 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 96 insertions(+), 41 deletions(-) diff --git a/R/series.R b/R/series.R index 1a0658811..35e5d2587 100644 --- a/R/series.R +++ b/R/series.R @@ -278,55 +278,110 @@ series.xts <- function( "ta_series" ) - ## fast-track to returning values - ## if the 'x' is correctly just one column - if (NCOL(x) == 1L && length(all.vars(formula.default)) == 1L) { - return(x) - } - - ## assert correctness of the passed - ## formulas + ## fast-track univariate input: a single-column + ## is consumed as-is when the indicator expects a single + ## series, regardless of its column name if (missing(formula)) { - ## the core assumption is that the default - ## formula never matches the actual names of - ## the passed because it returns as - ## TICKER.Open, TICKER.High, ..., TICKER.Adjusted - ## - ## So the first step is to convert the default formula - ## to to title case - formula.default <- stats::reformulate( - as.title_case( - grep( - pattern = paste(all.vars(formula.default), collapse = "|"), - x = names(x), - value = TRUE, - ignore.case = TRUE - ) - ) - ) + if (NCOL(x) == 1L && length(all.vars(formula.default)) == 1L) { + return(x) + } + ## if the formula is not passed ## it should be replaced by the default formula <- formula.default } - ## assert that columns exists - ## and emit message if not - assert_column_names( - formula = formula, - available_variables = names(x) + if (...length()) { + warning( + "'...' is passed but is unused for .", + call. = FALSE + ) + } + + ## an explicit formula must cover at least the variables + ## expected by the indicator's default. A longer formula is + ## allowed - downstream code only consumes what it needs. + formula_length <- length(all.vars(formula)) + default_length <- length(all.vars(formula.default)) + + assert( + x = formula_length >= default_length, + call = sys.call(sys.parent()), + paste0("Expected 'cols' length to be ", default_length, "."), + paste0("Got length ", formula_length, "."), + paste0( + "Uses ", + paste0("'", all.vars(formula.default), "'", collapse = ", "), + " by default." + ) + ) + + passed_variables <- all.vars(formula) + available_variables <- colnames(x) + + lowered_passed <- tolower(passed_variables) + lowered_available <- tolower(available_variables) + + ## match matrix: one row per formula variable, one column + ## per column. Exact name matches win over + ## quantmod-style suffix matches (close -> TICKER.Close) so + ## a plain 'Close' column is preferred over 'Adj.Close'; + ## columns are resolved in formula order because the C layer + ## consumes them positionally + exact_hits <- outer( + lowered_passed, + lowered_available, + `==` + ) + + suffix_hits <- outer( + paste0(".", lowered_passed), + lowered_available, + function(suffix, name) endsWith(name, suffix) + ) + + suffix_hits[rowSums(exact_hits) > 0L, ] <- FALSE + + hits <- exact_hits | suffix_hits + matches <- rowSums(hits) + + assert( + x = all(matches > 0L), + call = sys.call(sys.parent()), + paste( + "Expected to find columns", + paste0("'", passed_variables, "'", collapse = ", ") + ), + paste0( + "available columns: ", + paste0("'", available_variables, "'", collapse = ", ") + ) ) - ## extract all matching column - ## names - ## - ## NOTE: This step is not necessary if the - ## cols are not passed as its already been - ## identified an asserted - identified_columns <- grep( - pattern = paste(all.vars(formula), collapse = "|"), - x = names(x), - value = TRUE + assert( + x = all(matches == 1L), + call = sys.call(sys.parent()), + paste( + "Ambiguous columns", + paste0("'", passed_variables[matches > 1L], "'", collapse = ", "), + "." + ), + paste0( + "Matches: ", + paste0( + "'", + available_variables[ + colSums(hits[matches > 1L, , drop = FALSE]) > 0L + ], + "'", + collapse = ", " + ), + "." + ) ) - return(x[[match(identified_columns, names(x))]]) + ## the single TRUE per row is the resolved column + identified_columns <- max.col(hits, ties.method = "first") + + x[, identified_columns, drop = FALSE] } From bd56514383100bcbe011311f7e6a948253fbb68c Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 15:39:48 +0200 Subject: [PATCH 13/22] :bug: Guarded input and completed the VOLUME() xts rollout * Every .xts method now calls assert_xts(): the {xts} namespace is loaded on demand via requireNamespace(), with a clear error when the package is not installed. library(talib); RSI(GOOGL) works in vanilla sessions - and in zoo-only sessions - instead of dying with 'subscript out of bounds'; the GOOGL man-page example runs under R CMD check again. * set_index() gained a default method with a clear message, replacing the bare 'no applicable method' failure on malformed -classed input. * trading_volume() received the xts rollout the generated wrappers already had: index()/set_index() plumbing, a trading_volume.xts method, and the class stamp in src/volume.c that every generated C wrapper attaches via wrapper.h - VOLUME(xts) returns a proper carrying the input's index and the actual volume column. trading_volume.matrix now wraps in as.matrix() like the template, so matrix output stays a plain . * Regenerated wrappers via make codegen; the only generated diff is the assert_xts() guard in each of the 129 .xts methods. --- NAMESPACE | 2 + R/ta_ACCBANDS.R | 2 + R/ta_AD.R | 2 + R/ta_ADOSC.R | 2 + R/ta_ADX.R | 2 + R/ta_ADXR.R | 2 + R/ta_APO.R | 2 + R/ta_AROON.R | 2 + R/ta_AROONOSC.R | 2 + R/ta_ATR.R | 2 + R/ta_AVGDEV.R | 2 + R/ta_AVGPRICE.R | 2 + R/ta_BBANDS.R | 2 + R/ta_BOP.R | 2 + R/ta_CCI.R | 2 + R/ta_CDL2CROWS.R | 2 + R/ta_CDL3BLACKCROWS.R | 2 + R/ta_CDL3INSIDE.R | 2 + R/ta_CDL3LINESTRIKE.R | 2 + R/ta_CDL3OUTSIDE.R | 2 + R/ta_CDL3STARSINSOUTH.R | 2 + R/ta_CDL3WHITESOLDIERS.R | 2 + R/ta_CDLABANDONEDBABY.R | 2 + R/ta_CDLADVANCEBLOCK.R | 2 + R/ta_CDLBELTHOLD.R | 2 + R/ta_CDLBREAKAWAY.R | 2 + R/ta_CDLCLOSINGMARUBOZU.R | 2 + R/ta_CDLCONCEALBABYSWALL.R | 2 + R/ta_CDLCOUNTERATTACK.R | 2 + R/ta_CDLDARKCLOUDCOVER.R | 2 + R/ta_CDLDOJI.R | 2 + R/ta_CDLDOJISTAR.R | 2 + R/ta_CDLDRAGONFLYDOJI.R | 2 + R/ta_CDLENGULFING.R | 2 + R/ta_CDLEVENINGDOJISTAR.R | 2 + R/ta_CDLEVENINGSTAR.R | 2 + R/ta_CDLGAPSIDESIDEWHITE.R | 2 + R/ta_CDLGRAVESTONEDOJI.R | 2 + R/ta_CDLHAMMER.R | 2 + R/ta_CDLHANGINGMAN.R | 2 + R/ta_CDLHARAMI.R | 2 + R/ta_CDLHARAMICROSS.R | 2 + R/ta_CDLHIGHWAVE.R | 2 + R/ta_CDLHIKKAKE.R | 2 + R/ta_CDLHIKKAKEMOD.R | 2 + R/ta_CDLHOMINGPIGEON.R | 2 + R/ta_CDLIDENTICAL3CROWS.R | 2 + R/ta_CDLINNECK.R | 2 + R/ta_CDLINVERTEDHAMMER.R | 2 + R/ta_CDLKICKING.R | 2 + R/ta_CDLKICKINGBYLENGTH.R | 2 + R/ta_CDLLADDERBOTTOM.R | 2 + R/ta_CDLLONGLEGGEDDOJI.R | 2 + R/ta_CDLLONGLINE.R | 2 + R/ta_CDLMARUBOZU.R | 2 + R/ta_CDLMATCHINGLOW.R | 2 + R/ta_CDLMATHOLD.R | 2 + R/ta_CDLMORNINGDOJISTAR.R | 2 + R/ta_CDLMORNINGSTAR.R | 2 + R/ta_CDLONNECK.R | 2 + R/ta_CDLPIERCING.R | 2 + R/ta_CDLRICKSHAWMAN.R | 2 + R/ta_CDLRISEFALL3METHODS.R | 2 + R/ta_CDLSEPARATINGLINES.R | 2 + R/ta_CDLSHOOTINGSTAR.R | 2 + R/ta_CDLSHORTLINE.R | 2 + R/ta_CDLSPINNINGTOP.R | 2 + R/ta_CDLSTALLEDPATTERN.R | 2 + R/ta_CDLSTICKSANDWICH.R | 2 + R/ta_CDLTAKURI.R | 2 + R/ta_CDLTASUKIGAP.R | 2 + R/ta_CDLTHRUSTING.R | 2 + R/ta_CDLTRISTAR.R | 2 + R/ta_CDLUNIQUE3RIVER.R | 2 + R/ta_CDLUPSIDEGAP2CROWS.R | 2 + R/ta_CDLXSIDEGAP3METHODS.R | 2 + R/ta_CMF.R | 2 + R/ta_CMO.R | 2 + R/ta_CMOU.R | 2 + R/ta_DEMA.R | 2 + R/ta_DX.R | 2 + R/ta_EMA.R | 2 + R/ta_HMA.R | 2 + R/ta_HT_DCPERIOD.R | 2 + R/ta_HT_DCPHASE.R | 2 + R/ta_HT_PHASOR.R | 2 + R/ta_HT_SINE.R | 2 + R/ta_HT_TRENDLINE.R | 2 + R/ta_HT_TRENDMODE.R | 2 + R/ta_IMI.R | 2 + R/ta_KAMA.R | 2 + R/ta_MACD.R | 2 + R/ta_MACDEXT.R | 2 + R/ta_MACDFIX.R | 2 + R/ta_MAMA.R | 2 + R/ta_MAVP.R | 2 + R/ta_MEDPRICE.R | 2 + R/ta_MFI.R | 2 + R/ta_MIDPOINT.R | 2 + R/ta_MIDPRICE.R | 2 + R/ta_MINUS_DI.R | 2 + R/ta_MINUS_DM.R | 2 + R/ta_MOM.R | 2 + R/ta_NATR.R | 2 + R/ta_NVI.R | 2 + R/ta_OBV.R | 2 + R/ta_PLUS_DI.R | 2 + R/ta_PLUS_DM.R | 2 + R/ta_PPO.R | 2 + R/ta_PVI.R | 2 + R/ta_PVO.R | 2 + R/ta_ROCR.R | 2 + R/ta_RSI.R | 2 + R/ta_SAR.R | 2 + R/ta_SAREXT.R | 2 + R/ta_SMA.R | 2 + R/ta_STOCH.R | 2 + R/ta_STOCHF.R | 2 + R/ta_STOCHRSI.R | 2 + R/ta_T3.R | 2 + R/ta_TEMA.R | 2 + R/ta_TRANGE.R | 2 + R/ta_TRIMA.R | 2 + R/ta_TRIX.R | 2 + R/ta_TYPPRICE.R | 2 + R/ta_ULTOSC.R | 2 + R/ta_VOLUME.R | 42 +++++++++++++++++---- R/ta_VWMA.R | 2 + R/ta_WCLPRICE.R | 2 + R/ta_WILLR.R | 2 + R/ta_WMA.R | 2 + R/utils.R | 24 ++++++++++++ codegen/templates/candlestick_template.R | 2 + codegen/templates/indicator_template.R | 2 + codegen/templates/moving_average_template.R | 2 + src/volume.c | 8 ++++ 136 files changed, 332 insertions(+), 8 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index c2a65c4cd..b8aff3592 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -597,6 +597,7 @@ S3method(series,matrix) S3method(series,plotly) S3method(series,xts) S3method(set_index,character) +S3method(set_index,default) S3method(set_index,numeric) S3method(set_rownames,data.frame) S3method(set_rownames,matrix) @@ -730,6 +731,7 @@ S3method(trading_volume,ggplot) S3method(trading_volume,matrix) S3method(trading_volume,numeric) S3method(trading_volume,plotly) +S3method(trading_volume,xts) S3method(trend_cycle_mode,data.frame) S3method(trend_cycle_mode,default) S3method(trend_cycle_mode,ggplot) diff --git a/R/ta_ACCBANDS.R b/R/ta_ACCBANDS.R index df45a2430..32cad2c03 100644 --- a/R/ta_ACCBANDS.R +++ b/R/ta_ACCBANDS.R @@ -141,6 +141,8 @@ acceleration_bands.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( acceleration_bands.default( x = x, diff --git a/R/ta_AD.R b/R/ta_AD.R index 4f5336024..b16632b1e 100644 --- a/R/ta_AD.R +++ b/R/ta_AD.R @@ -134,6 +134,8 @@ chaikin_accumulation_distribution_line.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( chaikin_accumulation_distribution_line.default( x = x, diff --git a/R/ta_ADOSC.R b/R/ta_ADOSC.R index 571f75880..4b5e02149 100644 --- a/R/ta_ADOSC.R +++ b/R/ta_ADOSC.R @@ -151,6 +151,8 @@ chaikin_accumulation_distribution_oscillator.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( chaikin_accumulation_distribution_oscillator.default( x = x, diff --git a/R/ta_ADX.R b/R/ta_ADX.R index a1218a659..40c28a2ba 100644 --- a/R/ta_ADX.R +++ b/R/ta_ADX.R @@ -141,6 +141,8 @@ average_directional_movement_index.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( average_directional_movement_index.default( x = x, diff --git a/R/ta_ADXR.R b/R/ta_ADXR.R index 76f39d637..3a44b5906 100644 --- a/R/ta_ADXR.R +++ b/R/ta_ADXR.R @@ -141,6 +141,8 @@ average_directional_movement_index_rating.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( average_directional_movement_index_rating.default( x = x, diff --git a/R/ta_APO.R b/R/ta_APO.R index 1ab78d545..d4c20ba90 100644 --- a/R/ta_APO.R +++ b/R/ta_APO.R @@ -157,6 +157,8 @@ absolute_price_oscillator.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( absolute_price_oscillator.default( x = x, diff --git a/R/ta_AROON.R b/R/ta_AROON.R index 52da7c9d2..0ac0aa481 100644 --- a/R/ta_AROON.R +++ b/R/ta_AROON.R @@ -133,6 +133,8 @@ aroon.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( aroon.default( x = x, diff --git a/R/ta_AROONOSC.R b/R/ta_AROONOSC.R index f949315fb..87ec327b7 100644 --- a/R/ta_AROONOSC.R +++ b/R/ta_AROONOSC.R @@ -140,6 +140,8 @@ aroon_oscillator.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( aroon_oscillator.default( x = x, diff --git a/R/ta_ATR.R b/R/ta_ATR.R index de8dfe295..356066903 100644 --- a/R/ta_ATR.R +++ b/R/ta_ATR.R @@ -141,6 +141,8 @@ average_true_range.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( average_true_range.default( x = x, diff --git a/R/ta_AVGDEV.R b/R/ta_AVGDEV.R index 0da081c91..62c661c43 100644 --- a/R/ta_AVGDEV.R +++ b/R/ta_AVGDEV.R @@ -139,6 +139,8 @@ average_deviation.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( average_deviation.default( x = x, diff --git a/R/ta_AVGPRICE.R b/R/ta_AVGPRICE.R index 990f8c7f7..cd7743a7e 100644 --- a/R/ta_AVGPRICE.R +++ b/R/ta_AVGPRICE.R @@ -134,6 +134,8 @@ average_price.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( average_price.default( x = x, diff --git a/R/ta_BBANDS.R b/R/ta_BBANDS.R index a65c36b5f..b3ba9b067 100644 --- a/R/ta_BBANDS.R +++ b/R/ta_BBANDS.R @@ -165,6 +165,8 @@ bollinger_bands.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( bollinger_bands.default( x = x, diff --git a/R/ta_BOP.R b/R/ta_BOP.R index 003ea17fc..dd38776ff 100644 --- a/R/ta_BOP.R +++ b/R/ta_BOP.R @@ -134,6 +134,8 @@ balance_of_power.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( balance_of_power.default( x = x, diff --git a/R/ta_CCI.R b/R/ta_CCI.R index f7a0cd886..f2011144b 100644 --- a/R/ta_CCI.R +++ b/R/ta_CCI.R @@ -141,6 +141,8 @@ commodity_channel_index.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( commodity_channel_index.default( x = x, diff --git a/R/ta_CDL2CROWS.R b/R/ta_CDL2CROWS.R index b93871907..041cecd50 100644 --- a/R/ta_CDL2CROWS.R +++ b/R/ta_CDL2CROWS.R @@ -159,6 +159,8 @@ two_crows.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( two_crows.default( x = x, diff --git a/R/ta_CDL3BLACKCROWS.R b/R/ta_CDL3BLACKCROWS.R index c7a8ab32b..e768f5cc7 100644 --- a/R/ta_CDL3BLACKCROWS.R +++ b/R/ta_CDL3BLACKCROWS.R @@ -159,6 +159,8 @@ three_black_crows.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( three_black_crows.default( x = x, diff --git a/R/ta_CDL3INSIDE.R b/R/ta_CDL3INSIDE.R index 8a45348d4..01b5be798 100644 --- a/R/ta_CDL3INSIDE.R +++ b/R/ta_CDL3INSIDE.R @@ -159,6 +159,8 @@ three_inside.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( three_inside.default( x = x, diff --git a/R/ta_CDL3LINESTRIKE.R b/R/ta_CDL3LINESTRIKE.R index 7c829bc7b..d8785b4d5 100644 --- a/R/ta_CDL3LINESTRIKE.R +++ b/R/ta_CDL3LINESTRIKE.R @@ -159,6 +159,8 @@ three_line_strike.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( three_line_strike.default( x = x, diff --git a/R/ta_CDL3OUTSIDE.R b/R/ta_CDL3OUTSIDE.R index fe631607b..9631570a1 100644 --- a/R/ta_CDL3OUTSIDE.R +++ b/R/ta_CDL3OUTSIDE.R @@ -159,6 +159,8 @@ three_outside.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( three_outside.default( x = x, diff --git a/R/ta_CDL3STARSINSOUTH.R b/R/ta_CDL3STARSINSOUTH.R index 5f112cb3d..481ccd6f5 100644 --- a/R/ta_CDL3STARSINSOUTH.R +++ b/R/ta_CDL3STARSINSOUTH.R @@ -159,6 +159,8 @@ three_stars_in_the_south.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( three_stars_in_the_south.default( x = x, diff --git a/R/ta_CDL3WHITESOLDIERS.R b/R/ta_CDL3WHITESOLDIERS.R index afb361db8..04b97f4bf 100644 --- a/R/ta_CDL3WHITESOLDIERS.R +++ b/R/ta_CDL3WHITESOLDIERS.R @@ -159,6 +159,8 @@ three_white_soldiers.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( three_white_soldiers.default( x = x, diff --git a/R/ta_CDLABANDONEDBABY.R b/R/ta_CDLABANDONEDBABY.R index 3ee8b4fab..7774f8f28 100644 --- a/R/ta_CDLABANDONEDBABY.R +++ b/R/ta_CDLABANDONEDBABY.R @@ -167,6 +167,8 @@ abandoned_baby.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( abandoned_baby.default( x = x, diff --git a/R/ta_CDLADVANCEBLOCK.R b/R/ta_CDLADVANCEBLOCK.R index c30ac27a3..cf0a27b2f 100644 --- a/R/ta_CDLADVANCEBLOCK.R +++ b/R/ta_CDLADVANCEBLOCK.R @@ -159,6 +159,8 @@ advance_block.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( advance_block.default( x = x, diff --git a/R/ta_CDLBELTHOLD.R b/R/ta_CDLBELTHOLD.R index ecfa9bd92..8e9d7ab8c 100644 --- a/R/ta_CDLBELTHOLD.R +++ b/R/ta_CDLBELTHOLD.R @@ -159,6 +159,8 @@ belt_hold.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( belt_hold.default( x = x, diff --git a/R/ta_CDLBREAKAWAY.R b/R/ta_CDLBREAKAWAY.R index f4fe5c822..e2a6d84f1 100644 --- a/R/ta_CDLBREAKAWAY.R +++ b/R/ta_CDLBREAKAWAY.R @@ -159,6 +159,8 @@ break_away.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( break_away.default( x = x, diff --git a/R/ta_CDLCLOSINGMARUBOZU.R b/R/ta_CDLCLOSINGMARUBOZU.R index e7e6b0662..b4934ab82 100644 --- a/R/ta_CDLCLOSINGMARUBOZU.R +++ b/R/ta_CDLCLOSINGMARUBOZU.R @@ -159,6 +159,8 @@ closing_marubozu.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( closing_marubozu.default( x = x, diff --git a/R/ta_CDLCONCEALBABYSWALL.R b/R/ta_CDLCONCEALBABYSWALL.R index dd97bea69..230b40268 100644 --- a/R/ta_CDLCONCEALBABYSWALL.R +++ b/R/ta_CDLCONCEALBABYSWALL.R @@ -159,6 +159,8 @@ concealing_baby_swallow.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( concealing_baby_swallow.default( x = x, diff --git a/R/ta_CDLCOUNTERATTACK.R b/R/ta_CDLCOUNTERATTACK.R index 279529d8c..1ae7e62a7 100644 --- a/R/ta_CDLCOUNTERATTACK.R +++ b/R/ta_CDLCOUNTERATTACK.R @@ -159,6 +159,8 @@ counter_attack.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( counter_attack.default( x = x, diff --git a/R/ta_CDLDARKCLOUDCOVER.R b/R/ta_CDLDARKCLOUDCOVER.R index b53d9dd96..3642e3abf 100644 --- a/R/ta_CDLDARKCLOUDCOVER.R +++ b/R/ta_CDLDARKCLOUDCOVER.R @@ -167,6 +167,8 @@ dark_cloud_cover.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( dark_cloud_cover.default( x = x, diff --git a/R/ta_CDLDOJI.R b/R/ta_CDLDOJI.R index 80741735e..822363ed6 100644 --- a/R/ta_CDLDOJI.R +++ b/R/ta_CDLDOJI.R @@ -152,6 +152,8 @@ doji.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( doji.default( x = x, diff --git a/R/ta_CDLDOJISTAR.R b/R/ta_CDLDOJISTAR.R index d86604f52..5a90b6ff9 100644 --- a/R/ta_CDLDOJISTAR.R +++ b/R/ta_CDLDOJISTAR.R @@ -159,6 +159,8 @@ doji_star.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( doji_star.default( x = x, diff --git a/R/ta_CDLDRAGONFLYDOJI.R b/R/ta_CDLDRAGONFLYDOJI.R index 842335c68..7be22b576 100644 --- a/R/ta_CDLDRAGONFLYDOJI.R +++ b/R/ta_CDLDRAGONFLYDOJI.R @@ -159,6 +159,8 @@ dragonfly_doji.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( dragonfly_doji.default( x = x, diff --git a/R/ta_CDLENGULFING.R b/R/ta_CDLENGULFING.R index 8b4dae593..cb9005901 100644 --- a/R/ta_CDLENGULFING.R +++ b/R/ta_CDLENGULFING.R @@ -152,6 +152,8 @@ engulfing.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( engulfing.default( x = x, diff --git a/R/ta_CDLEVENINGDOJISTAR.R b/R/ta_CDLEVENINGDOJISTAR.R index 252d1569d..af912b5a4 100644 --- a/R/ta_CDLEVENINGDOJISTAR.R +++ b/R/ta_CDLEVENINGDOJISTAR.R @@ -167,6 +167,8 @@ evening_doji_star.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( evening_doji_star.default( x = x, diff --git a/R/ta_CDLEVENINGSTAR.R b/R/ta_CDLEVENINGSTAR.R index 796722682..6b66a5e45 100644 --- a/R/ta_CDLEVENINGSTAR.R +++ b/R/ta_CDLEVENINGSTAR.R @@ -167,6 +167,8 @@ evening_star.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( evening_star.default( x = x, diff --git a/R/ta_CDLGAPSIDESIDEWHITE.R b/R/ta_CDLGAPSIDESIDEWHITE.R index 2eec8e064..ead58bc7d 100644 --- a/R/ta_CDLGAPSIDESIDEWHITE.R +++ b/R/ta_CDLGAPSIDESIDEWHITE.R @@ -159,6 +159,8 @@ gaps_side_white.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( gaps_side_white.default( x = x, diff --git a/R/ta_CDLGRAVESTONEDOJI.R b/R/ta_CDLGRAVESTONEDOJI.R index bf6d3d8ef..3be0fba9f 100644 --- a/R/ta_CDLGRAVESTONEDOJI.R +++ b/R/ta_CDLGRAVESTONEDOJI.R @@ -159,6 +159,8 @@ gravestone_doji.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( gravestone_doji.default( x = x, diff --git a/R/ta_CDLHAMMER.R b/R/ta_CDLHAMMER.R index 5b90f50c1..89bc13c06 100644 --- a/R/ta_CDLHAMMER.R +++ b/R/ta_CDLHAMMER.R @@ -152,6 +152,8 @@ hammer.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( hammer.default( x = x, diff --git a/R/ta_CDLHANGINGMAN.R b/R/ta_CDLHANGINGMAN.R index fc447681c..1fabca8df 100644 --- a/R/ta_CDLHANGINGMAN.R +++ b/R/ta_CDLHANGINGMAN.R @@ -159,6 +159,8 @@ hanging_man.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( hanging_man.default( x = x, diff --git a/R/ta_CDLHARAMI.R b/R/ta_CDLHARAMI.R index b62de4412..7eaa4db61 100644 --- a/R/ta_CDLHARAMI.R +++ b/R/ta_CDLHARAMI.R @@ -152,6 +152,8 @@ harami.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( harami.default( x = x, diff --git a/R/ta_CDLHARAMICROSS.R b/R/ta_CDLHARAMICROSS.R index 32dbb0e98..02d501340 100644 --- a/R/ta_CDLHARAMICROSS.R +++ b/R/ta_CDLHARAMICROSS.R @@ -159,6 +159,8 @@ harami_cross.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( harami_cross.default( x = x, diff --git a/R/ta_CDLHIGHWAVE.R b/R/ta_CDLHIGHWAVE.R index 3e7a4a9e6..234665571 100644 --- a/R/ta_CDLHIGHWAVE.R +++ b/R/ta_CDLHIGHWAVE.R @@ -159,6 +159,8 @@ high_wave.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( high_wave.default( x = x, diff --git a/R/ta_CDLHIKKAKE.R b/R/ta_CDLHIKKAKE.R index 23a0298c5..f7889ab37 100644 --- a/R/ta_CDLHIKKAKE.R +++ b/R/ta_CDLHIKKAKE.R @@ -152,6 +152,8 @@ hikakke.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( hikakke.default( x = x, diff --git a/R/ta_CDLHIKKAKEMOD.R b/R/ta_CDLHIKKAKEMOD.R index a39e23127..8aff4780a 100644 --- a/R/ta_CDLHIKKAKEMOD.R +++ b/R/ta_CDLHIKKAKEMOD.R @@ -159,6 +159,8 @@ hikakke_mod.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( hikakke_mod.default( x = x, diff --git a/R/ta_CDLHOMINGPIGEON.R b/R/ta_CDLHOMINGPIGEON.R index 71e3ed75e..95087e229 100644 --- a/R/ta_CDLHOMINGPIGEON.R +++ b/R/ta_CDLHOMINGPIGEON.R @@ -159,6 +159,8 @@ homing_pigeon.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( homing_pigeon.default( x = x, diff --git a/R/ta_CDLIDENTICAL3CROWS.R b/R/ta_CDLIDENTICAL3CROWS.R index 112f413d0..4d8da4797 100644 --- a/R/ta_CDLIDENTICAL3CROWS.R +++ b/R/ta_CDLIDENTICAL3CROWS.R @@ -159,6 +159,8 @@ three_identical_crows.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( three_identical_crows.default( x = x, diff --git a/R/ta_CDLINNECK.R b/R/ta_CDLINNECK.R index b88b97deb..5b2b777d1 100644 --- a/R/ta_CDLINNECK.R +++ b/R/ta_CDLINNECK.R @@ -159,6 +159,8 @@ in_neck.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( in_neck.default( x = x, diff --git a/R/ta_CDLINVERTEDHAMMER.R b/R/ta_CDLINVERTEDHAMMER.R index 8182ab320..be02d8c1f 100644 --- a/R/ta_CDLINVERTEDHAMMER.R +++ b/R/ta_CDLINVERTEDHAMMER.R @@ -159,6 +159,8 @@ inverted_hammer.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( inverted_hammer.default( x = x, diff --git a/R/ta_CDLKICKING.R b/R/ta_CDLKICKING.R index d42724c5d..3b01d6a6a 100644 --- a/R/ta_CDLKICKING.R +++ b/R/ta_CDLKICKING.R @@ -152,6 +152,8 @@ kicking.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( kicking.default( x = x, diff --git a/R/ta_CDLKICKINGBYLENGTH.R b/R/ta_CDLKICKINGBYLENGTH.R index 6f34cbd8d..d41d15238 100644 --- a/R/ta_CDLKICKINGBYLENGTH.R +++ b/R/ta_CDLKICKINGBYLENGTH.R @@ -159,6 +159,8 @@ kicking_baby_length.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( kicking_baby_length.default( x = x, diff --git a/R/ta_CDLLADDERBOTTOM.R b/R/ta_CDLLADDERBOTTOM.R index d30d7379f..6bd060d71 100644 --- a/R/ta_CDLLADDERBOTTOM.R +++ b/R/ta_CDLLADDERBOTTOM.R @@ -159,6 +159,8 @@ ladder_bottom.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( ladder_bottom.default( x = x, diff --git a/R/ta_CDLLONGLEGGEDDOJI.R b/R/ta_CDLLONGLEGGEDDOJI.R index 048802691..46662a3a6 100644 --- a/R/ta_CDLLONGLEGGEDDOJI.R +++ b/R/ta_CDLLONGLEGGEDDOJI.R @@ -159,6 +159,8 @@ long_legged_doji.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( long_legged_doji.default( x = x, diff --git a/R/ta_CDLLONGLINE.R b/R/ta_CDLLONGLINE.R index 643959243..00e59f270 100644 --- a/R/ta_CDLLONGLINE.R +++ b/R/ta_CDLLONGLINE.R @@ -159,6 +159,8 @@ long_line.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( long_line.default( x = x, diff --git a/R/ta_CDLMARUBOZU.R b/R/ta_CDLMARUBOZU.R index 9912e3c41..3061b07c9 100644 --- a/R/ta_CDLMARUBOZU.R +++ b/R/ta_CDLMARUBOZU.R @@ -152,6 +152,8 @@ marubozu.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( marubozu.default( x = x, diff --git a/R/ta_CDLMATCHINGLOW.R b/R/ta_CDLMATCHINGLOW.R index 2a7c42c3c..585d9d479 100644 --- a/R/ta_CDLMATCHINGLOW.R +++ b/R/ta_CDLMATCHINGLOW.R @@ -159,6 +159,8 @@ matching_low.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( matching_low.default( x = x, diff --git a/R/ta_CDLMATHOLD.R b/R/ta_CDLMATHOLD.R index b3e8a1409..04fcb0fb5 100644 --- a/R/ta_CDLMATHOLD.R +++ b/R/ta_CDLMATHOLD.R @@ -167,6 +167,8 @@ mat_hold.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( mat_hold.default( x = x, diff --git a/R/ta_CDLMORNINGDOJISTAR.R b/R/ta_CDLMORNINGDOJISTAR.R index 5382877a4..2bc40b3eb 100644 --- a/R/ta_CDLMORNINGDOJISTAR.R +++ b/R/ta_CDLMORNINGDOJISTAR.R @@ -167,6 +167,8 @@ morning_doji_star.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( morning_doji_star.default( x = x, diff --git a/R/ta_CDLMORNINGSTAR.R b/R/ta_CDLMORNINGSTAR.R index 98e2b4f41..8ce6e2a56 100644 --- a/R/ta_CDLMORNINGSTAR.R +++ b/R/ta_CDLMORNINGSTAR.R @@ -167,6 +167,8 @@ morning_star.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( morning_star.default( x = x, diff --git a/R/ta_CDLONNECK.R b/R/ta_CDLONNECK.R index 962ee3ebf..1f6c60444 100644 --- a/R/ta_CDLONNECK.R +++ b/R/ta_CDLONNECK.R @@ -159,6 +159,8 @@ on_neck.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( on_neck.default( x = x, diff --git a/R/ta_CDLPIERCING.R b/R/ta_CDLPIERCING.R index bde204751..c7396581a 100644 --- a/R/ta_CDLPIERCING.R +++ b/R/ta_CDLPIERCING.R @@ -152,6 +152,8 @@ piercing.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( piercing.default( x = x, diff --git a/R/ta_CDLRICKSHAWMAN.R b/R/ta_CDLRICKSHAWMAN.R index 65c8893d9..6e1898764 100644 --- a/R/ta_CDLRICKSHAWMAN.R +++ b/R/ta_CDLRICKSHAWMAN.R @@ -159,6 +159,8 @@ rickshaw_man.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( rickshaw_man.default( x = x, diff --git a/R/ta_CDLRISEFALL3METHODS.R b/R/ta_CDLRISEFALL3METHODS.R index fb9951282..6528f17b3 100644 --- a/R/ta_CDLRISEFALL3METHODS.R +++ b/R/ta_CDLRISEFALL3METHODS.R @@ -159,6 +159,8 @@ rise_fall_3_methods.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( rise_fall_3_methods.default( x = x, diff --git a/R/ta_CDLSEPARATINGLINES.R b/R/ta_CDLSEPARATINGLINES.R index e3c8eb9f0..8f5c6ab14 100644 --- a/R/ta_CDLSEPARATINGLINES.R +++ b/R/ta_CDLSEPARATINGLINES.R @@ -159,6 +159,8 @@ separating_lines.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( separating_lines.default( x = x, diff --git a/R/ta_CDLSHOOTINGSTAR.R b/R/ta_CDLSHOOTINGSTAR.R index 567abbec9..bac07392d 100644 --- a/R/ta_CDLSHOOTINGSTAR.R +++ b/R/ta_CDLSHOOTINGSTAR.R @@ -159,6 +159,8 @@ shooting_star.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( shooting_star.default( x = x, diff --git a/R/ta_CDLSHORTLINE.R b/R/ta_CDLSHORTLINE.R index ec3eb8510..d9dfab58a 100644 --- a/R/ta_CDLSHORTLINE.R +++ b/R/ta_CDLSHORTLINE.R @@ -159,6 +159,8 @@ short_line.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( short_line.default( x = x, diff --git a/R/ta_CDLSPINNINGTOP.R b/R/ta_CDLSPINNINGTOP.R index 4295f9465..1443cec3d 100644 --- a/R/ta_CDLSPINNINGTOP.R +++ b/R/ta_CDLSPINNINGTOP.R @@ -159,6 +159,8 @@ spinning_top.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( spinning_top.default( x = x, diff --git a/R/ta_CDLSTALLEDPATTERN.R b/R/ta_CDLSTALLEDPATTERN.R index c98694daf..4212dee12 100644 --- a/R/ta_CDLSTALLEDPATTERN.R +++ b/R/ta_CDLSTALLEDPATTERN.R @@ -159,6 +159,8 @@ stalled_pattern.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( stalled_pattern.default( x = x, diff --git a/R/ta_CDLSTICKSANDWICH.R b/R/ta_CDLSTICKSANDWICH.R index e693238f7..5adf2a511 100644 --- a/R/ta_CDLSTICKSANDWICH.R +++ b/R/ta_CDLSTICKSANDWICH.R @@ -159,6 +159,8 @@ stick_sandwich.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( stick_sandwich.default( x = x, diff --git a/R/ta_CDLTAKURI.R b/R/ta_CDLTAKURI.R index 8e6cb53ff..66f468a1a 100644 --- a/R/ta_CDLTAKURI.R +++ b/R/ta_CDLTAKURI.R @@ -152,6 +152,8 @@ takuri.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( takuri.default( x = x, diff --git a/R/ta_CDLTASUKIGAP.R b/R/ta_CDLTASUKIGAP.R index 742a38c18..32bf8dd06 100644 --- a/R/ta_CDLTASUKIGAP.R +++ b/R/ta_CDLTASUKIGAP.R @@ -159,6 +159,8 @@ tasuki_gap.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( tasuki_gap.default( x = x, diff --git a/R/ta_CDLTHRUSTING.R b/R/ta_CDLTHRUSTING.R index 66401b334..cc9a891c1 100644 --- a/R/ta_CDLTHRUSTING.R +++ b/R/ta_CDLTHRUSTING.R @@ -152,6 +152,8 @@ thrusting.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( thrusting.default( x = x, diff --git a/R/ta_CDLTRISTAR.R b/R/ta_CDLTRISTAR.R index 61f313998..65584fabd 100644 --- a/R/ta_CDLTRISTAR.R +++ b/R/ta_CDLTRISTAR.R @@ -152,6 +152,8 @@ tristar.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( tristar.default( x = x, diff --git a/R/ta_CDLUNIQUE3RIVER.R b/R/ta_CDLUNIQUE3RIVER.R index a1bae95d2..08699e581 100644 --- a/R/ta_CDLUNIQUE3RIVER.R +++ b/R/ta_CDLUNIQUE3RIVER.R @@ -159,6 +159,8 @@ unique_3_river.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( unique_3_river.default( x = x, diff --git a/R/ta_CDLUPSIDEGAP2CROWS.R b/R/ta_CDLUPSIDEGAP2CROWS.R index c06185d1c..182cca25d 100644 --- a/R/ta_CDLUPSIDEGAP2CROWS.R +++ b/R/ta_CDLUPSIDEGAP2CROWS.R @@ -159,6 +159,8 @@ upside_gap_2_crows.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( upside_gap_2_crows.default( x = x, diff --git a/R/ta_CDLXSIDEGAP3METHODS.R b/R/ta_CDLXSIDEGAP3METHODS.R index f4dad065a..d04485fa3 100644 --- a/R/ta_CDLXSIDEGAP3METHODS.R +++ b/R/ta_CDLXSIDEGAP3METHODS.R @@ -159,6 +159,8 @@ xside_gap_3_methods.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( xside_gap_3_methods.default( x = x, diff --git a/R/ta_CMF.R b/R/ta_CMF.R index b340c2262..ed58ce830 100644 --- a/R/ta_CMF.R +++ b/R/ta_CMF.R @@ -142,6 +142,8 @@ chaikin_money_flow.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( chaikin_money_flow.default( x = x, diff --git a/R/ta_CMO.R b/R/ta_CMO.R index f60ef6e57..d17320dcf 100644 --- a/R/ta_CMO.R +++ b/R/ta_CMO.R @@ -139,6 +139,8 @@ chande_momentum_oscillator.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( chande_momentum_oscillator.default( x = x, diff --git a/R/ta_CMOU.R b/R/ta_CMOU.R index 85726887e..43aa0f9d6 100644 --- a/R/ta_CMOU.R +++ b/R/ta_CMOU.R @@ -139,6 +139,8 @@ unsmoothed_chande_momentum_oscillator.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( unsmoothed_chande_momentum_oscillator.default( x = x, diff --git a/R/ta_DEMA.R b/R/ta_DEMA.R index 21625eb87..fc7b9d30f 100644 --- a/R/ta_DEMA.R +++ b/R/ta_DEMA.R @@ -165,6 +165,8 @@ double_exponential_moving_average.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( double_exponential_moving_average.default( x = x, diff --git a/R/ta_DX.R b/R/ta_DX.R index cc8f22a37..3d4ba1a3a 100644 --- a/R/ta_DX.R +++ b/R/ta_DX.R @@ -141,6 +141,8 @@ directional_movement_index.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( directional_movement_index.default( x = x, diff --git a/R/ta_EMA.R b/R/ta_EMA.R index 321d02ed0..99a8e11dd 100644 --- a/R/ta_EMA.R +++ b/R/ta_EMA.R @@ -165,6 +165,8 @@ exponential_moving_average.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( exponential_moving_average.default( x = x, diff --git a/R/ta_HMA.R b/R/ta_HMA.R index fef2435a0..687b5ba91 100644 --- a/R/ta_HMA.R +++ b/R/ta_HMA.R @@ -165,6 +165,8 @@ hull_moving_average.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( hull_moving_average.default( x = x, diff --git a/R/ta_HT_DCPERIOD.R b/R/ta_HT_DCPERIOD.R index 3d0476927..fc6b093e3 100644 --- a/R/ta_HT_DCPERIOD.R +++ b/R/ta_HT_DCPERIOD.R @@ -131,6 +131,8 @@ dominant_cycle_period.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( dominant_cycle_period.default( x = x, diff --git a/R/ta_HT_DCPHASE.R b/R/ta_HT_DCPHASE.R index fc1ab908b..606290b91 100644 --- a/R/ta_HT_DCPHASE.R +++ b/R/ta_HT_DCPHASE.R @@ -131,6 +131,8 @@ dominant_cycle_phase.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( dominant_cycle_phase.default( x = x, diff --git a/R/ta_HT_PHASOR.R b/R/ta_HT_PHASOR.R index d10285866..f3fe09cda 100644 --- a/R/ta_HT_PHASOR.R +++ b/R/ta_HT_PHASOR.R @@ -131,6 +131,8 @@ phasor_components.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( phasor_components.default( x = x, diff --git a/R/ta_HT_SINE.R b/R/ta_HT_SINE.R index 5a4120cac..1f902a412 100644 --- a/R/ta_HT_SINE.R +++ b/R/ta_HT_SINE.R @@ -131,6 +131,8 @@ sine_wave.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( sine_wave.default( x = x, diff --git a/R/ta_HT_TRENDLINE.R b/R/ta_HT_TRENDLINE.R index e1b1df2f9..0b75780ae 100644 --- a/R/ta_HT_TRENDLINE.R +++ b/R/ta_HT_TRENDLINE.R @@ -124,6 +124,8 @@ trendline.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( trendline.default( x = x, diff --git a/R/ta_HT_TRENDMODE.R b/R/ta_HT_TRENDMODE.R index d18a90b72..eaf94357e 100644 --- a/R/ta_HT_TRENDMODE.R +++ b/R/ta_HT_TRENDMODE.R @@ -131,6 +131,8 @@ trend_cycle_mode.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( trend_cycle_mode.default( x = x, diff --git a/R/ta_IMI.R b/R/ta_IMI.R index 2578261b4..0622c0a71 100644 --- a/R/ta_IMI.R +++ b/R/ta_IMI.R @@ -140,6 +140,8 @@ intraday_movement_index.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( intraday_movement_index.default( x = x, diff --git a/R/ta_KAMA.R b/R/ta_KAMA.R index 8aefd482d..d2ff67a3e 100644 --- a/R/ta_KAMA.R +++ b/R/ta_KAMA.R @@ -165,6 +165,8 @@ kaufman_adaptive_moving_average.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( kaufman_adaptive_moving_average.default( x = x, diff --git a/R/ta_MACD.R b/R/ta_MACD.R index 78f00b070..e9643528a 100644 --- a/R/ta_MACD.R +++ b/R/ta_MACD.R @@ -157,6 +157,8 @@ moving_average_convergence_divergence.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( moving_average_convergence_divergence.default( x = x, diff --git a/R/ta_MACDEXT.R b/R/ta_MACDEXT.R index 8a9e7e8e3..3616e31a9 100644 --- a/R/ta_MACDEXT.R +++ b/R/ta_MACDEXT.R @@ -184,6 +184,8 @@ extended_moving_average_convergence_divergence.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( extended_moving_average_convergence_divergence.default( x = x, diff --git a/R/ta_MACDFIX.R b/R/ta_MACDFIX.R index d0c1a4d76..8ee2216e9 100644 --- a/R/ta_MACDFIX.R +++ b/R/ta_MACDFIX.R @@ -139,6 +139,8 @@ fixed_moving_average_convergence_divergence.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( fixed_moving_average_convergence_divergence.default( x = x, diff --git a/R/ta_MAMA.R b/R/ta_MAMA.R index 69e260b47..9b9c618b0 100644 --- a/R/ta_MAMA.R +++ b/R/ta_MAMA.R @@ -191,6 +191,8 @@ mesa_adaptive_moving_average.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( mesa_adaptive_moving_average.default( x = x, diff --git a/R/ta_MAVP.R b/R/ta_MAVP.R index 5df31be42..501b18a55 100644 --- a/R/ta_MAVP.R +++ b/R/ta_MAVP.R @@ -168,6 +168,8 @@ variable_moving_average_period.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( variable_moving_average_period.default( x = x, diff --git a/R/ta_MEDPRICE.R b/R/ta_MEDPRICE.R index e8760cb69..298af37eb 100644 --- a/R/ta_MEDPRICE.R +++ b/R/ta_MEDPRICE.R @@ -132,6 +132,8 @@ median_price.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( median_price.default( x = x, diff --git a/R/ta_MFI.R b/R/ta_MFI.R index 31c3d455d..de5bf14f8 100644 --- a/R/ta_MFI.R +++ b/R/ta_MFI.R @@ -142,6 +142,8 @@ money_flow_index.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( money_flow_index.default( x = x, diff --git a/R/ta_MIDPOINT.R b/R/ta_MIDPOINT.R index 0f66b6efb..4108ef627 100644 --- a/R/ta_MIDPOINT.R +++ b/R/ta_MIDPOINT.R @@ -139,6 +139,8 @@ midpoint_period.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( midpoint_period.default( x = x, diff --git a/R/ta_MIDPRICE.R b/R/ta_MIDPRICE.R index 7274b60cc..73d5d36fc 100644 --- a/R/ta_MIDPRICE.R +++ b/R/ta_MIDPRICE.R @@ -140,6 +140,8 @@ midpoint_price.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( midpoint_price.default( x = x, diff --git a/R/ta_MINUS_DI.R b/R/ta_MINUS_DI.R index 9025487f0..d8556565a 100644 --- a/R/ta_MINUS_DI.R +++ b/R/ta_MINUS_DI.R @@ -141,6 +141,8 @@ minus_directional_indicator.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( minus_directional_indicator.default( x = x, diff --git a/R/ta_MINUS_DM.R b/R/ta_MINUS_DM.R index 917c0ada6..7f076e457 100644 --- a/R/ta_MINUS_DM.R +++ b/R/ta_MINUS_DM.R @@ -140,6 +140,8 @@ minus_directional_movement.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( minus_directional_movement.default( x = x, diff --git a/R/ta_MOM.R b/R/ta_MOM.R index 189b55f7b..4615ff0d5 100644 --- a/R/ta_MOM.R +++ b/R/ta_MOM.R @@ -132,6 +132,8 @@ momentum.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( momentum.default( x = x, diff --git a/R/ta_NATR.R b/R/ta_NATR.R index 389096501..ca2332d46 100644 --- a/R/ta_NATR.R +++ b/R/ta_NATR.R @@ -141,6 +141,8 @@ normalized_average_true_range.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( normalized_average_true_range.default( x = x, diff --git a/R/ta_NVI.R b/R/ta_NVI.R index ad9509803..3cd74a09c 100644 --- a/R/ta_NVI.R +++ b/R/ta_NVI.R @@ -132,6 +132,8 @@ negative_volume_index.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( negative_volume_index.default( x = x, diff --git a/R/ta_OBV.R b/R/ta_OBV.R index faea3c87e..bb83fc91c 100644 --- a/R/ta_OBV.R +++ b/R/ta_OBV.R @@ -132,6 +132,8 @@ on_balance_volume.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( on_balance_volume.default( x = x, diff --git a/R/ta_PLUS_DI.R b/R/ta_PLUS_DI.R index 64f1749e8..8a61e0eba 100644 --- a/R/ta_PLUS_DI.R +++ b/R/ta_PLUS_DI.R @@ -141,6 +141,8 @@ plus_directional_indicator.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( plus_directional_indicator.default( x = x, diff --git a/R/ta_PLUS_DM.R b/R/ta_PLUS_DM.R index 2eb9d6550..1948d1424 100644 --- a/R/ta_PLUS_DM.R +++ b/R/ta_PLUS_DM.R @@ -140,6 +140,8 @@ plus_directional_movement.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( plus_directional_movement.default( x = x, diff --git a/R/ta_PPO.R b/R/ta_PPO.R index afdc5815d..02bcb9bd8 100644 --- a/R/ta_PPO.R +++ b/R/ta_PPO.R @@ -157,6 +157,8 @@ percentage_price_oscillator.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( percentage_price_oscillator.default( x = x, diff --git a/R/ta_PVI.R b/R/ta_PVI.R index eb31c8d8f..fb48b083d 100644 --- a/R/ta_PVI.R +++ b/R/ta_PVI.R @@ -132,6 +132,8 @@ positive_volume_index.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( positive_volume_index.default( x = x, diff --git a/R/ta_PVO.R b/R/ta_PVO.R index ce2336e1c..33dc2b31b 100644 --- a/R/ta_PVO.R +++ b/R/ta_PVO.R @@ -157,6 +157,8 @@ percentage_volume_oscillator.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( percentage_volume_oscillator.default( x = x, diff --git a/R/ta_ROCR.R b/R/ta_ROCR.R index c2f5579f0..1b6ecde8c 100644 --- a/R/ta_ROCR.R +++ b/R/ta_ROCR.R @@ -139,6 +139,8 @@ ratio_of_change.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( ratio_of_change.default( x = x, diff --git a/R/ta_RSI.R b/R/ta_RSI.R index 4e2163266..179c4f065 100644 --- a/R/ta_RSI.R +++ b/R/ta_RSI.R @@ -139,6 +139,8 @@ relative_strength_index.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( relative_strength_index.default( x = x, diff --git a/R/ta_SAR.R b/R/ta_SAR.R index e3a2045f1..fb4565b3b 100644 --- a/R/ta_SAR.R +++ b/R/ta_SAR.R @@ -149,6 +149,8 @@ parabolic_stop_and_reverse.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( parabolic_stop_and_reverse.default( x = x, diff --git a/R/ta_SAREXT.R b/R/ta_SAREXT.R index a1a74a610..a64c2ef23 100644 --- a/R/ta_SAREXT.R +++ b/R/ta_SAREXT.R @@ -203,6 +203,8 @@ extended_parabolic_stop_and_reverse.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( extended_parabolic_stop_and_reverse.default( x = x, diff --git a/R/ta_SMA.R b/R/ta_SMA.R index 8c45ccbc8..4e3a8d94f 100644 --- a/R/ta_SMA.R +++ b/R/ta_SMA.R @@ -165,6 +165,8 @@ simple_moving_average.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( simple_moving_average.default( x = x, diff --git a/R/ta_STOCH.R b/R/ta_STOCH.R index c43e1d12a..aba28d837 100644 --- a/R/ta_STOCH.R +++ b/R/ta_STOCH.R @@ -170,6 +170,8 @@ stochastic.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( stochastic.default( x = x, diff --git a/R/ta_STOCHF.R b/R/ta_STOCHF.R index cbb18bfb1..8c01ef110 100644 --- a/R/ta_STOCHF.R +++ b/R/ta_STOCHF.R @@ -159,6 +159,8 @@ fast_stochastic.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( fast_stochastic.default( x = x, diff --git a/R/ta_STOCHRSI.R b/R/ta_STOCHRSI.R index a0f0545c7..fd2251d5e 100644 --- a/R/ta_STOCHRSI.R +++ b/R/ta_STOCHRSI.R @@ -165,6 +165,8 @@ stochastic_relative_strength_index.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( stochastic_relative_strength_index.default( x = x, diff --git a/R/ta_T3.R b/R/ta_T3.R index 1c5b4e1fd..9299171f7 100644 --- a/R/ta_T3.R +++ b/R/ta_T3.R @@ -178,6 +178,8 @@ t3_exponential_moving_average.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( t3_exponential_moving_average.default( x = x, diff --git a/R/ta_TEMA.R b/R/ta_TEMA.R index bb291e705..01ed0eb5f 100644 --- a/R/ta_TEMA.R +++ b/R/ta_TEMA.R @@ -165,6 +165,8 @@ triple_exponential_moving_average.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( triple_exponential_moving_average.default( x = x, diff --git a/R/ta_TRANGE.R b/R/ta_TRANGE.R index 02ffd07de..4ac16895e 100644 --- a/R/ta_TRANGE.R +++ b/R/ta_TRANGE.R @@ -133,6 +133,8 @@ true_range.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( true_range.default( x = x, diff --git a/R/ta_TRIMA.R b/R/ta_TRIMA.R index ab269cc26..394cf615a 100644 --- a/R/ta_TRIMA.R +++ b/R/ta_TRIMA.R @@ -165,6 +165,8 @@ triangular_moving_average.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( triangular_moving_average.default( x = x, diff --git a/R/ta_TRIX.R b/R/ta_TRIX.R index 79ffbae67..aa87e8b4c 100644 --- a/R/ta_TRIX.R +++ b/R/ta_TRIX.R @@ -139,6 +139,8 @@ triple_exponential_average.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( triple_exponential_average.default( x = x, diff --git a/R/ta_TYPPRICE.R b/R/ta_TYPPRICE.R index fe52e093a..6378e3e4e 100644 --- a/R/ta_TYPPRICE.R +++ b/R/ta_TYPPRICE.R @@ -133,6 +133,8 @@ typical_price.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( typical_price.default( x = x, diff --git a/R/ta_ULTOSC.R b/R/ta_ULTOSC.R index 0c2055968..bb31b6449 100644 --- a/R/ta_ULTOSC.R +++ b/R/ta_ULTOSC.R @@ -159,6 +159,8 @@ ultimate_oscillator.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( ultimate_oscillator.default( x = x, diff --git a/R/ta_VOLUME.R b/R/ta_VOLUME.R index 655f82451..fbc70e796 100644 --- a/R/ta_VOLUME.R +++ b/R/ta_VOLUME.R @@ -66,7 +66,7 @@ trading_volume.default <- function( ## extract rownames ## for later attachment - x_names <- rownames(constructed_series) + x_names <- index(constructed_series) ## calculate indicator and ## return as data.frame @@ -87,7 +87,7 @@ trading_volume.default <- function( ) ## readd rownames - set_rownames(x, x_names) + set_index(x, x_names) ## return indicator x @@ -126,12 +126,38 @@ trading_volume.matrix <- function( na.bridge = FALSE, ... ) { - trading_volume.default( - x = x, - cols = cols, - maType = maType, - na.bridge = na.bridge, - ... + as.matrix( + trading_volume.default( + x = x, + cols = cols, + maType = maType, + na.bridge = na.bridge, + ... + ) + ) +} + +#' @usage NULL +#' @aliases trading_volume +#' +#' @export +trading_volume.xts <- function( + x, + cols, + maType = list(SMA(timePeriod = 7), SMA(timePeriod = 15)), + na.bridge = FALSE, + ... +) { + assert_xts() + + as.xts( + trading_volume.default( + x = x, + cols = cols, + maType = maType, + na.bridge = na.bridge, + ... + ) ) } diff --git a/R/ta_VWMA.R b/R/ta_VWMA.R index 59e0059f2..026936909 100644 --- a/R/ta_VWMA.R +++ b/R/ta_VWMA.R @@ -166,6 +166,8 @@ volume_weighted_moving_average.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( volume_weighted_moving_average.default( x = x, diff --git a/R/ta_WCLPRICE.R b/R/ta_WCLPRICE.R index cb07fccc1..89da79e79 100644 --- a/R/ta_WCLPRICE.R +++ b/R/ta_WCLPRICE.R @@ -133,6 +133,8 @@ weighted_close_price.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( weighted_close_price.default( x = x, diff --git a/R/ta_WILLR.R b/R/ta_WILLR.R index 8fe6970e9..489fbdc22 100644 --- a/R/ta_WILLR.R +++ b/R/ta_WILLR.R @@ -141,6 +141,8 @@ williams_oscillator.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( williams_oscillator.default( x = x, diff --git a/R/ta_WMA.R b/R/ta_WMA.R index bb8899d4c..884f74b9b 100644 --- a/R/ta_WMA.R +++ b/R/ta_WMA.R @@ -165,6 +165,8 @@ weighted_moving_average.xts <- function( na.bridge = FALSE, ... ) { + assert_xts() + as.xts( weighted_moving_average.default( x = x, diff --git a/R/utils.R b/R/utils.R index 83594d9df..0de3025a0 100644 --- a/R/utils.R +++ b/R/utils.R @@ -67,6 +67,20 @@ assert_plotly_object <- function(x) { ) } +## assert_xts(): assert that the xts PACKAGE is installed, and load +## its namespace so the [.xts / index machinery is registered even in +## sessions that never attached xts (deserialized objects, LazyData +## fixtures like GOOGL). Mirrors assert_plotly_pkg()/assert_ggplot2(). +assert_xts <- function() { + if (!requireNamespace("xts", quietly = TRUE)) { + stop( + "Package 'xts' is required for input. ", + "Install it with install.packages('xts').", + call. = FALSE + ) + } +} + assert_column_names <- function(formula, available_variables) { ## this assert function will give an error ## if the variables are not found. If it finds @@ -320,6 +334,16 @@ set_index <- function(x, value) { UseMethod("set_index", object = value) } +#' @export +set_index.default <- function(x, value) { + stop( + "Cannot set the index from <", + class(value)[1L], + ">. Expected rownames or a -index.", + call. = FALSE + ) +} + #' @export set_index.character <- function(x, value) { if (is.matrix(x)) { diff --git a/codegen/templates/candlestick_template.R b/codegen/templates/candlestick_template.R index fe8e4832f..1daea598c 100644 --- a/codegen/templates/candlestick_template.R +++ b/codegen/templates/candlestick_template.R @@ -163,6 +163,8 @@ ${FUN}.xts <- function( na.bridge = FALSE, ...) { + assert_xts() + as.xts( ${FUN}.default( x = x, diff --git a/codegen/templates/indicator_template.R b/codegen/templates/indicator_template.R index 016244674..74f7298e2 100644 --- a/codegen/templates/indicator_template.R +++ b/codegen/templates/indicator_template.R @@ -138,6 +138,8 @@ ${FUN}.xts <- function( na.bridge = FALSE, ...) { + assert_xts() + as.xts( ${FUN}.default( x = x, diff --git a/codegen/templates/moving_average_template.R b/codegen/templates/moving_average_template.R index bce1d569d..612fd3080 100644 --- a/codegen/templates/moving_average_template.R +++ b/codegen/templates/moving_average_template.R @@ -161,6 +161,8 @@ ${FUN}.xts <- function( na.bridge = FALSE, ...) { + assert_xts() + as.xts( ${FUN}.default( x = x, diff --git a/src/volume.c b/src/volume.c index 5f4dd1987..8505fe31f 100644 --- a/src/volume.c +++ b/src/volume.c @@ -192,6 +192,14 @@ SEXP impl_ta_VOLUME( set_colnames(out, colname, n_cols); set_attribute(out, LOOKBACK, Rf_ScalarInteger(lookback), &protection_counter); + /* Attach classes to output so its easier to work with downstream */ + SEXP TA_CLASS = PROTECT(Rf_allocVector(STRSXP, 3)); + protection_counter++; + SET_STRING_ELT(TA_CLASS, 0, Rf_mkChar("ta_object")); + SET_STRING_ELT(TA_CLASS, 1, Rf_mkChar("matrix")); + SET_STRING_ELT(TA_CLASS, 2, Rf_mkChar("array")); + Rf_setAttrib(out, R_ClassSymbol, TA_CLASS); + UNPROTECT(protection_counter); return out; } From 4f8e654890ed10c7265847b1b47217f8ed02a868 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 16:00:49 +0200 Subject: [PATCH 14/22] :sparkles: rolling statistics + univariate guards * All seven rolling generics (rolling_maximum, rolling_minimum, rolling_sum, rolling_standard_deviation, rolling_variance, rolling_beta, rolling_correlation) gained an .xts method: a single-column in, an out carrying the input's index and the statistic's column name (MAX, BETA, ...), with values identical to the vector path. For the bivariate pair, 'y' may be a vector or a single-column ; pairing is positional. * Multi-column input is now rejected with a clear error ('Expected 'x' to be univariate.') instead of being silently flattened column-major into one concatenated series - the guard is generated per series argument into .default and .xts, covering xts and matrix input alike. This matches TTR::runMax's univariate contract, and runMax/MAX now agree exactly on identical input. * Vector returns from the rolling family drop the stale c('ta_object','matrix','array') class alongside the dim-strip - a dimensionless vector no longer claims inherits(., 'matrix') - while keeping the lookback attribute. * Wiring: ${SERIES_GUARD} placeholder in render.rs, rolling_template.R .xts block, generated xts value-parity and multivariate-error test blocks in testthat.rs (guarded by skip_if_not_installed('xts')), and the rolling man-roxygen templates now document the xts contract. Also corrected the template's fresh-render call site (${C_NUMERIC},,, -> ${C_NUMERIC},), a latent syntax bug masked by splice preservation. --- NAMESPACE | 7 +++ R/ta_BETA.R | 69 ++++++++++++++++++++++++++++ R/ta_CORREL.R | 69 ++++++++++++++++++++++++++++ R/ta_MAX.R | 53 +++++++++++++++++++++ R/ta_MIN.R | 53 +++++++++++++++++++++ R/ta_STDDEV.R | 55 ++++++++++++++++++++++ R/ta_SUM.R | 53 +++++++++++++++++++++ R/ta_VAR.R | 55 ++++++++++++++++++++++ codegen/src/render.rs | 14 ++++++ codegen/src/testthat.rs | 49 +++++++++++++++++++- codegen/templates/rolling_template.R | 43 ++++++++++++++++- man-roxygen/rolling_description.R | 7 +-- man-roxygen/rolling_returns.R | 2 +- tests/testthat/test-ta_BETA.R | 26 +++++++++++ tests/testthat/test-ta_CORREL.R | 26 +++++++++++ tests/testthat/test-ta_MAX.R | 23 ++++++++++ tests/testthat/test-ta_MIN.R | 23 ++++++++++ tests/testthat/test-ta_STDDEV.R | 25 ++++++++++ tests/testthat/test-ta_SUM.R | 23 ++++++++++ tests/testthat/test-ta_VAR.R | 23 ++++++++++ 20 files changed, 691 insertions(+), 7 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index b8aff3592..1aa5d6416 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -573,18 +573,25 @@ S3method(rise_fall_3_methods,plotly) S3method(rise_fall_3_methods,xts) S3method(rolling_beta,default) S3method(rolling_beta,numeric) +S3method(rolling_beta,xts) S3method(rolling_correlation,default) S3method(rolling_correlation,numeric) +S3method(rolling_correlation,xts) S3method(rolling_maximum,default) S3method(rolling_maximum,numeric) +S3method(rolling_maximum,xts) S3method(rolling_minimum,default) S3method(rolling_minimum,numeric) +S3method(rolling_minimum,xts) S3method(rolling_standard_deviation,default) S3method(rolling_standard_deviation,numeric) +S3method(rolling_standard_deviation,xts) S3method(rolling_sum,default) S3method(rolling_sum,numeric) +S3method(rolling_sum,xts) S3method(rolling_variance,default) S3method(rolling_variance,numeric) +S3method(rolling_variance,xts) S3method(separating_lines,data.frame) S3method(separating_lines,default) S3method(separating_lines,ggplot) diff --git a/R/ta_BETA.R b/R/ta_BETA.R index ad2bf57b9..a6a1da5d3 100644 --- a/R/ta_BETA.R +++ b/R/ta_BETA.R @@ -47,6 +47,23 @@ rolling_beta.default <- function( na.bridge = FALSE, ... ) { + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + assert( + x = NCOL(x) == 1L, + call = sys.call(sys.parent()), + "Expected 'x' to be univariate.", + paste0("Got ", NCOL(x), " columns.") + ) + + assert( + x = NCOL(y) == 1L, + call = sys.call(sys.parent()), + "Expected 'y' to be univariate.", + paste0("Got ", NCOL(y), " columns.") + ) + ## calculate indicator and ## return as data.frame x <- .Call( @@ -63,6 +80,7 @@ rolling_beta.default <- function( ## while preserving ## attributes dim(x) <- NULL + class(x) <- NULL ## return indicator x @@ -97,6 +115,57 @@ rolling_beta.numeric <- function( x } +#' @usage NULL +#' @aliases rolling_beta +#' +#' @export +rolling_beta.xts <- function( + x, + y, + timePeriod = 5, + na.bridge = FALSE, + ... +) { + assert_xts() + + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + assert( + x = NCOL(x) == 1L, + call = sys.call(sys.parent()), + "Expected 'x' to be univariate.", + paste0("Got ", NCOL(x), " columns.") + ) + + assert( + x = NCOL(y) == 1L, + call = sys.call(sys.parent()), + "Expected 'y' to be univariate.", + paste0("Got ", NCOL(y), " columns.") + ) + + ## extract the index + ## for later attachment + x_names <- index(x) + + ## calculate indicator and + ## return as + x <- .Call( + C_impl_ta_BETA, + as.double(x), + as.double(y), + as.integer(timePeriod), + as.logical(na.bridge) + ) + + ## readd the index + set_index(x, x_names) + + ## return indicator + as.xts(x) +} + #' @usage NULL BETA_lookback <- rollingBeta_lookback <- rolling_beta_lookback <- function( x, diff --git a/R/ta_CORREL.R b/R/ta_CORREL.R index 2f2aa1a1e..ffda17a8d 100644 --- a/R/ta_CORREL.R +++ b/R/ta_CORREL.R @@ -47,6 +47,23 @@ rolling_correlation.default <- function( na.bridge = FALSE, ... ) { + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + assert( + x = NCOL(x) == 1L, + call = sys.call(sys.parent()), + "Expected 'x' to be univariate.", + paste0("Got ", NCOL(x), " columns.") + ) + + assert( + x = NCOL(y) == 1L, + call = sys.call(sys.parent()), + "Expected 'y' to be univariate.", + paste0("Got ", NCOL(y), " columns.") + ) + ## calculate indicator and ## return as data.frame x <- .Call( @@ -63,6 +80,7 @@ rolling_correlation.default <- function( ## while preserving ## attributes dim(x) <- NULL + class(x) <- NULL ## return indicator x @@ -97,6 +115,57 @@ rolling_correlation.numeric <- function( x } +#' @usage NULL +#' @aliases rolling_correlation +#' +#' @export +rolling_correlation.xts <- function( + x, + y, + timePeriod = 30, + na.bridge = FALSE, + ... +) { + assert_xts() + + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + assert( + x = NCOL(x) == 1L, + call = sys.call(sys.parent()), + "Expected 'x' to be univariate.", + paste0("Got ", NCOL(x), " columns.") + ) + + assert( + x = NCOL(y) == 1L, + call = sys.call(sys.parent()), + "Expected 'y' to be univariate.", + paste0("Got ", NCOL(y), " columns.") + ) + + ## extract the index + ## for later attachment + x_names <- index(x) + + ## calculate indicator and + ## return as + x <- .Call( + C_impl_ta_CORREL, + as.double(x), + as.double(y), + as.integer(timePeriod), + as.logical(na.bridge) + ) + + ## readd the index + set_index(x, x_names) + + ## return indicator + as.xts(x) +} + #' @usage NULL CORREL_lookback <- rollingCorrelation_lookback <- rolling_correlation_lookback <- function( x, diff --git a/R/ta_MAX.R b/R/ta_MAX.R index c76d35519..c9986b3e2 100644 --- a/R/ta_MAX.R +++ b/R/ta_MAX.R @@ -45,6 +45,16 @@ rolling_maximum.default <- function( na.bridge = FALSE, ... ) { + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + assert( + x = NCOL(x) == 1L, + call = sys.call(sys.parent()), + "Expected 'x' to be univariate.", + paste0("Got ", NCOL(x), " columns.") + ) + ## calculate indicator and ## return as data.frame x <- .Call( @@ -60,6 +70,7 @@ rolling_maximum.default <- function( ## while preserving ## attributes dim(x) <- NULL + class(x) <- NULL ## return indicator x @@ -92,6 +103,48 @@ rolling_maximum.numeric <- function( x } +#' @usage NULL +#' @aliases rolling_maximum +#' +#' @export +rolling_maximum.xts <- function( + x, + timePeriod = 30, + na.bridge = FALSE, + ... +) { + assert_xts() + + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + assert( + x = NCOL(x) == 1L, + call = sys.call(sys.parent()), + "Expected 'x' to be univariate.", + paste0("Got ", NCOL(x), " columns.") + ) + + ## extract the index + ## for later attachment + x_names <- index(x) + + ## calculate indicator and + ## return as + x <- .Call( + C_impl_ta_MAX, + as.double(x), + as.integer(timePeriod), + as.logical(na.bridge) + ) + + ## readd the index + set_index(x, x_names) + + ## return indicator + as.xts(x) +} + #' @usage NULL MAX_lookback <- rollingMaximum_lookback <- rolling_maximum_lookback <- function( x, diff --git a/R/ta_MIN.R b/R/ta_MIN.R index 52d0d4db2..f66cbfc13 100644 --- a/R/ta_MIN.R +++ b/R/ta_MIN.R @@ -45,6 +45,16 @@ rolling_minimum.default <- function( na.bridge = FALSE, ... ) { + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + assert( + x = NCOL(x) == 1L, + call = sys.call(sys.parent()), + "Expected 'x' to be univariate.", + paste0("Got ", NCOL(x), " columns.") + ) + ## calculate indicator and ## return as data.frame x <- .Call( @@ -60,6 +70,7 @@ rolling_minimum.default <- function( ## while preserving ## attributes dim(x) <- NULL + class(x) <- NULL ## return indicator x @@ -92,6 +103,48 @@ rolling_minimum.numeric <- function( x } +#' @usage NULL +#' @aliases rolling_minimum +#' +#' @export +rolling_minimum.xts <- function( + x, + timePeriod = 30, + na.bridge = FALSE, + ... +) { + assert_xts() + + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + assert( + x = NCOL(x) == 1L, + call = sys.call(sys.parent()), + "Expected 'x' to be univariate.", + paste0("Got ", NCOL(x), " columns.") + ) + + ## extract the index + ## for later attachment + x_names <- index(x) + + ## calculate indicator and + ## return as + x <- .Call( + C_impl_ta_MIN, + as.double(x), + as.integer(timePeriod), + as.logical(na.bridge) + ) + + ## readd the index + set_index(x, x_names) + + ## return indicator + as.xts(x) +} + #' @usage NULL MIN_lookback <- rollingMinimum_lookback <- rolling_minimum_lookback <- function( x, diff --git a/R/ta_STDDEV.R b/R/ta_STDDEV.R index 611bed189..084463d71 100644 --- a/R/ta_STDDEV.R +++ b/R/ta_STDDEV.R @@ -47,6 +47,16 @@ rolling_standard_deviation.default <- function( na.bridge = FALSE, ... ) { + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + assert( + x = NCOL(x) == 1L, + call = sys.call(sys.parent()), + "Expected 'x' to be univariate.", + paste0("Got ", NCOL(x), " columns.") + ) + ## calculate indicator and ## return as data.frame x <- .Call( @@ -63,6 +73,7 @@ rolling_standard_deviation.default <- function( ## while preserving ## attributes dim(x) <- NULL + class(x) <- NULL ## return indicator x @@ -97,6 +108,50 @@ rolling_standard_deviation.numeric <- function( x } +#' @usage NULL +#' @aliases rolling_standard_deviation +#' +#' @export +rolling_standard_deviation.xts <- function( + x, + timePeriod = 5, + deviations = 1, + na.bridge = FALSE, + ... +) { + assert_xts() + + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + assert( + x = NCOL(x) == 1L, + call = sys.call(sys.parent()), + "Expected 'x' to be univariate.", + paste0("Got ", NCOL(x), " columns.") + ) + + ## extract the index + ## for later attachment + x_names <- index(x) + + ## calculate indicator and + ## return as + x <- .Call( + C_impl_ta_STDDEV, + as.double(x), + as.integer(timePeriod), + as.double(deviations), + as.logical(na.bridge) + ) + + ## readd the index + set_index(x, x_names) + + ## return indicator + as.xts(x) +} + #' @usage NULL STDDEV_lookback <- rollingStandardDeviation_lookback <- rolling_standard_deviation_lookback <- function( x, diff --git a/R/ta_SUM.R b/R/ta_SUM.R index ab4ea9813..603f5b56a 100644 --- a/R/ta_SUM.R +++ b/R/ta_SUM.R @@ -45,6 +45,16 @@ rolling_sum.default <- function( na.bridge = FALSE, ... ) { + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + assert( + x = NCOL(x) == 1L, + call = sys.call(sys.parent()), + "Expected 'x' to be univariate.", + paste0("Got ", NCOL(x), " columns.") + ) + ## calculate indicator and ## return as data.frame x <- .Call( @@ -60,6 +70,7 @@ rolling_sum.default <- function( ## while preserving ## attributes dim(x) <- NULL + class(x) <- NULL ## return indicator x @@ -92,6 +103,48 @@ rolling_sum.numeric <- function( x } +#' @usage NULL +#' @aliases rolling_sum +#' +#' @export +rolling_sum.xts <- function( + x, + timePeriod = 30, + na.bridge = FALSE, + ... +) { + assert_xts() + + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + assert( + x = NCOL(x) == 1L, + call = sys.call(sys.parent()), + "Expected 'x' to be univariate.", + paste0("Got ", NCOL(x), " columns.") + ) + + ## extract the index + ## for later attachment + x_names <- index(x) + + ## calculate indicator and + ## return as + x <- .Call( + C_impl_ta_SUM, + as.double(x), + as.integer(timePeriod), + as.logical(na.bridge) + ) + + ## readd the index + set_index(x, x_names) + + ## return indicator + as.xts(x) +} + #' @usage NULL SUM_lookback <- rollingSum_lookback <- rolling_sum_lookback <- function( x, diff --git a/R/ta_VAR.R b/R/ta_VAR.R index 43d77c849..11d09c4f0 100644 --- a/R/ta_VAR.R +++ b/R/ta_VAR.R @@ -47,6 +47,16 @@ rolling_variance.default <- function( na.bridge = FALSE, ... ) { + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + assert( + x = NCOL(x) == 1L, + call = sys.call(sys.parent()), + "Expected 'x' to be univariate.", + paste0("Got ", NCOL(x), " columns.") + ) + ## calculate indicator and ## return as data.frame x <- .Call( @@ -63,6 +73,7 @@ rolling_variance.default <- function( ## while preserving ## attributes dim(x) <- NULL + class(x) <- NULL ## return indicator x @@ -97,6 +108,50 @@ rolling_variance.numeric <- function( x } +#' @usage NULL +#' @aliases rolling_variance +#' +#' @export +rolling_variance.xts <- function( + x, + timePeriod = 5, + deviations = 1, + na.bridge = FALSE, + ... +) { + assert_xts() + + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + assert( + x = NCOL(x) == 1L, + call = sys.call(sys.parent()), + "Expected 'x' to be univariate.", + paste0("Got ", NCOL(x), " columns.") + ) + + ## extract the index + ## for later attachment + x_names <- index(x) + + ## calculate indicator and + ## return as + x <- .Call( + C_impl_ta_VAR, + as.double(x), + as.integer(timePeriod), + as.double(deviations), + as.logical(na.bridge) + ) + + ## readd the index + set_index(x, x_names) + + ## return indicator + as.xts(x) +} + #' @usage NULL VAR_lookback <- rollingVariance_lookback <- rolling_variance_lookback <- function( x, diff --git a/codegen/src/render.rs b/codegen/src/render.rs index 761db2116..26db9ec0a 100644 --- a/codegen/src/render.rs +++ b/codegen/src/render.rs @@ -360,6 +360,19 @@ pub fn render_indicator(f: &MetaData, t: &Templates) -> String { .collect::>() .join("\n\t\t"); + // the univariate guard of the rolling .default/.xts methods: + // one assert per input series, rejecting multi-column input + // instead of flattening it column-major + let series_guard = series + .iter() + .map(|s| { + format!( + "assert(\n\t\tx = NCOL({s}) == 1L,\n\t\tcall = sys.call(sys.parent()),\n\t\t\"Expected '{s}' to be univariate.\",\n\t\tpaste0(\"Got \", NCOL({s}), \" columns.\")\n\t)" + ) + }) + .collect::>() + .join("\n\n\t"); + let c_numeric = series .iter() .map(|s| format!("as.double({s})")) @@ -412,6 +425,7 @@ pub fn render_indicator(f: &MetaData, t: &Templates) -> String { .replace("${C_SIGNATURE}", &c_signature) .replace("${C_NUMERIC}", &c_numeric) .replace("${SERIES}", &series_args) + .replace("${SERIES_GUARD}", &series_guard) .replace("${PSERIES}", &pseries) .replace("${SPEC_FIELDS}", &spec_fields) .replace("${MA_TYPE}", ma_index.unwrap_or("-1L")) diff --git a/codegen/src/testthat.rs b/codegen/src/testthat.rs index d4f8246e2..85eddb451 100644 --- a/codegen/src/testthat.rs +++ b/codegen/src/testthat.rs @@ -86,6 +86,29 @@ testthat::expect_equal( } ) + +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + + output <- ${FUN}(x = GOOGL[, 1]${ADDITIONAL_XTS}) + + testthat::expect_true(inherits(output, "xts")) + testthat::expect_equal(zoo::index(output), zoo::index(GOOGL)) + testthat::expect_equal( + object = as.numeric(output), + expected = as.numeric(${FUN}(x = as.numeric(GOOGL[, 1])${ADDITIONAL_NUMERIC})) + ) +}) + +## multi-column input must error +## instead of being flattened +testthat::test_that(desc = 'Multivariate input errors', code = { + testthat::skip_if_not_installed("xts") + + testthat::expect_error(${FUN}(x = GOOGL${ADDITIONAL_XTS})) + testthat::expect_error(${FUN}(x = SPY${ADDITIONAL})) +}) "#; const STANDARD_TESTS: &str = r#" @@ -397,12 +420,23 @@ pub fn render_test(f: &MetaData) -> String { // rolling statistics fast-track: a short univariate file, // with the second input series of BETA/CORREL passed as 'y' if f.family == "Statistic Functions" || f.family == "Math Operators" { - let additional = if f.input.len() > 1 { ",y=SPY[,2]" } else { "" }; - + let bivariate = f.input.len() > 1; + let additional = if bivariate { ",y=SPY[,2]" } else { "" }; + let additional_xts = if bivariate { ", y = GOOGL[, 2]" } else { "" }; + let additional_numeric = if bivariate { + ", y = as.numeric(GOOGL[, 2])" + } else { + "" + }; + + // ${ADDITIONAL} is a prefix of the two variants: + // replace the longer placeholders first return format!( "{HEADER}{}", ROLLING_TESTS .replace("${FUN}", fun) + .replace("${ADDITIONAL_XTS}", additional_xts) + .replace("${ADDITIONAL_NUMERIC}", additional_numeric) .replace("${ADDITIONAL}", additional) ); } @@ -535,9 +569,20 @@ mod tests { assert!(!rendered.contains("y=SPY[,2]")); assert!(!rendered.contains("Alias and function similarity")); + // the xts blocks: class round-trip with value parity + // against the vector path, and the multivariate guard + assert!(rendered.contains("Class in, class out ()")); + assert!(rendered.contains("Multivariate input errors")); + assert!(rendered.contains("x = GOOGL[, 1])")); + assert!(!rendered.contains("y = GOOGL[, 2]")); + assert!(!rendered.contains("${"), "unreplaced placeholder"); + // the bivariate rolling statistics pass // the second column as 'y' let rendered = render_test(&meta("BETA", "Statistic Functions", &["close", "close"])); assert!(rendered.contains("x = SPY[,1],y=SPY[,2]")); + assert!(rendered.contains("x = GOOGL[, 1], y = GOOGL[, 2]")); + assert!(rendered.contains("y = as.numeric(GOOGL[, 2])")); + assert!(!rendered.contains("${"), "unreplaced placeholder"); } } diff --git a/codegen/templates/rolling_template.R b/codegen/templates/rolling_template.R index 3ba503292..7abbbe66f 100644 --- a/codegen/templates/rolling_template.R +++ b/codegen/templates/rolling_template.R @@ -42,12 +42,17 @@ ${FUN}.default <- function( ${ARGS} na.bridge = FALSE, ...) { + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + ${SERIES_GUARD} + ## calculate indicator and ## return as data.frame x <- .Call( C_impl_ta_${ALIAS}, ## splice:call:start - ${C_NUMERIC},,, + ${C_NUMERIC}, ## splice:call:end as.logical(na.bridge) ) @@ -56,6 +61,7 @@ ${FUN}.default <- function( ## while preserving ## attributes dim(x) <- NULL + class(x) <- NULL ## return indicator x @@ -87,6 +93,41 @@ ${FUN}.numeric <- function( x } +#' @usage NULL +#' @aliases ${FUN} +#' +#' @export +${FUN}.xts <- function( + ${SERIES} + ${ARGS} + na.bridge = FALSE, ...) { + + assert_xts() + + ## rolling statistics are univariate - + ## multi-column input is rejected instead + ## of being flattened column-major + ${SERIES_GUARD} + + ## extract the index + ## for later attachment + x_names <- index(x) + + ## calculate indicator and + ## return as + x <- .Call( + C_impl_ta_${ALIAS}, + ${C_NUMERIC}, + as.logical(na.bridge) + ) + + ## readd the index + set_index(x, x_names) + + ## return indicator + as.xts(x) +} + #' @usage NULL ${ALIAS}_lookback <- ${CAMEL_LOOKBACK}${FUN}_lookback <- function( x,${ARGS} diff --git a/man-roxygen/rolling_description.R b/man-roxygen/rolling_description.R index 5143c256e..a3fcd1315 100644 --- a/man-roxygen/rolling_description.R +++ b/man-roxygen/rolling_description.R @@ -1,6 +1,7 @@ #' @description #' `<%= tolower(.fun) %>()` is a generic S3 function that preserves -#' the input [class]: [double] vector in, [double] vector out. +#' the input [class]: [double] vector in, [double] vector out; +#' single-column `xts` in, `xts` out. #' #' ## Handling of `NA` values #' @@ -24,9 +25,9 @@ <% if (all(c("x","y") %in% names(formals(.fun)))) { %> -#' @param x,y (([double]), ([double])). A pair of [double] vectors of equal [length]. +#' @param x,y (([double]), ([double])). A pair of [double] vectors of equal [length], or single-column `xts` objects. <% } else { %> -#' @param x ([double]). A [double] vector. +#' @param x ([double]). A [double] vector, or a single-column `xts`. #' <% } %> <% fun_args <- names(formals(.fun)) %> diff --git a/man-roxygen/rolling_returns.R b/man-roxygen/rolling_returns.R index 751b34ec8..c25177306 100644 --- a/man-roxygen/rolling_returns.R +++ b/man-roxygen/rolling_returns.R @@ -1,3 +1,3 @@ #' @returns #' -#' A [double] vector with the same [length] of `x` +#' A [double] vector (or single-column `xts`) with the same [length] of `x` diff --git a/tests/testthat/test-ta_BETA.R b/tests/testthat/test-ta_BETA.R index fa89c86c5..9408fce70 100644 --- a/tests/testthat/test-ta_BETA.R +++ b/tests/testthat/test-ta_BETA.R @@ -60,3 +60,29 @@ testthat::test_that(desc = 'Lookback equivalence', code = { expected = lookback(FUN = rolling_beta, x = SPY[, 1]) ) }) + +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + + output <- rolling_beta(x = GOOGL[, 1], y = GOOGL[, 2]) + + testthat::expect_true(inherits(output, "xts")) + testthat::expect_equal(zoo::index(output), zoo::index(GOOGL)) + testthat::expect_equal( + object = as.numeric(output), + expected = as.numeric(rolling_beta( + x = as.numeric(GOOGL[, 1]), + y = as.numeric(GOOGL[, 2]) + )) + ) +}) + +## multi-column input must error +## instead of being flattened +testthat::test_that(desc = 'Multivariate input errors', code = { + testthat::skip_if_not_installed("xts") + + testthat::expect_error(rolling_beta(x = GOOGL, y = GOOGL[, 2])) + testthat::expect_error(rolling_beta(x = SPY, y = SPY[, 2])) +}) diff --git a/tests/testthat/test-ta_CORREL.R b/tests/testthat/test-ta_CORREL.R index 1eac60c59..f24354978 100644 --- a/tests/testthat/test-ta_CORREL.R +++ b/tests/testthat/test-ta_CORREL.R @@ -60,3 +60,29 @@ testthat::test_that(desc = 'Lookback equivalence', code = { expected = lookback(FUN = rolling_correlation, x = SPY[, 1]) ) }) + +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + + output <- rolling_correlation(x = GOOGL[, 1], y = GOOGL[, 2]) + + testthat::expect_true(inherits(output, "xts")) + testthat::expect_equal(zoo::index(output), zoo::index(GOOGL)) + testthat::expect_equal( + object = as.numeric(output), + expected = as.numeric(rolling_correlation( + x = as.numeric(GOOGL[, 1]), + y = as.numeric(GOOGL[, 2]) + )) + ) +}) + +## multi-column input must error +## instead of being flattened +testthat::test_that(desc = 'Multivariate input errors', code = { + testthat::skip_if_not_installed("xts") + + testthat::expect_error(rolling_correlation(x = GOOGL, y = GOOGL[, 2])) + testthat::expect_error(rolling_correlation(x = SPY, y = SPY[, 2])) +}) diff --git a/tests/testthat/test-ta_MAX.R b/tests/testthat/test-ta_MAX.R index 4e502374c..02fb591c4 100644 --- a/tests/testthat/test-ta_MAX.R +++ b/tests/testthat/test-ta_MAX.R @@ -57,3 +57,26 @@ testthat::test_that(desc = 'Lookback equivalence', code = { expected = lookback(FUN = rolling_maximum, x = SPY[, 1]) ) }) + +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + + output <- rolling_maximum(x = GOOGL[, 1]) + + testthat::expect_true(inherits(output, "xts")) + testthat::expect_equal(zoo::index(output), zoo::index(GOOGL)) + testthat::expect_equal( + object = as.numeric(output), + expected = as.numeric(rolling_maximum(x = as.numeric(GOOGL[, 1]))) + ) +}) + +## multi-column input must error +## instead of being flattened +testthat::test_that(desc = 'Multivariate input errors', code = { + testthat::skip_if_not_installed("xts") + + testthat::expect_error(rolling_maximum(x = GOOGL)) + testthat::expect_error(rolling_maximum(x = SPY)) +}) diff --git a/tests/testthat/test-ta_MIN.R b/tests/testthat/test-ta_MIN.R index e1f5194fb..2ab68c186 100644 --- a/tests/testthat/test-ta_MIN.R +++ b/tests/testthat/test-ta_MIN.R @@ -57,3 +57,26 @@ testthat::test_that(desc = 'Lookback equivalence', code = { expected = lookback(FUN = rolling_minimum, x = SPY[, 1]) ) }) + +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + + output <- rolling_minimum(x = GOOGL[, 1]) + + testthat::expect_true(inherits(output, "xts")) + testthat::expect_equal(zoo::index(output), zoo::index(GOOGL)) + testthat::expect_equal( + object = as.numeric(output), + expected = as.numeric(rolling_minimum(x = as.numeric(GOOGL[, 1]))) + ) +}) + +## multi-column input must error +## instead of being flattened +testthat::test_that(desc = 'Multivariate input errors', code = { + testthat::skip_if_not_installed("xts") + + testthat::expect_error(rolling_minimum(x = GOOGL)) + testthat::expect_error(rolling_minimum(x = SPY)) +}) diff --git a/tests/testthat/test-ta_STDDEV.R b/tests/testthat/test-ta_STDDEV.R index 8b80c8c90..df82e8630 100644 --- a/tests/testthat/test-ta_STDDEV.R +++ b/tests/testthat/test-ta_STDDEV.R @@ -57,3 +57,28 @@ testthat::test_that(desc = 'Lookback equivalence', code = { expected = lookback(FUN = rolling_standard_deviation, x = SPY[, 1]) ) }) + +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + + output <- rolling_standard_deviation(x = GOOGL[, 1]) + + testthat::expect_true(inherits(output, "xts")) + testthat::expect_equal(zoo::index(output), zoo::index(GOOGL)) + testthat::expect_equal( + object = as.numeric(output), + expected = as.numeric(rolling_standard_deviation( + x = as.numeric(GOOGL[, 1]) + )) + ) +}) + +## multi-column input must error +## instead of being flattened +testthat::test_that(desc = 'Multivariate input errors', code = { + testthat::skip_if_not_installed("xts") + + testthat::expect_error(rolling_standard_deviation(x = GOOGL)) + testthat::expect_error(rolling_standard_deviation(x = SPY)) +}) diff --git a/tests/testthat/test-ta_SUM.R b/tests/testthat/test-ta_SUM.R index de8da4cd8..5b384f76a 100644 --- a/tests/testthat/test-ta_SUM.R +++ b/tests/testthat/test-ta_SUM.R @@ -57,3 +57,26 @@ testthat::test_that(desc = 'Lookback equivalence', code = { expected = lookback(FUN = rolling_sum, x = SPY[, 1]) ) }) + +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + + output <- rolling_sum(x = GOOGL[, 1]) + + testthat::expect_true(inherits(output, "xts")) + testthat::expect_equal(zoo::index(output), zoo::index(GOOGL)) + testthat::expect_equal( + object = as.numeric(output), + expected = as.numeric(rolling_sum(x = as.numeric(GOOGL[, 1]))) + ) +}) + +## multi-column input must error +## instead of being flattened +testthat::test_that(desc = 'Multivariate input errors', code = { + testthat::skip_if_not_installed("xts") + + testthat::expect_error(rolling_sum(x = GOOGL)) + testthat::expect_error(rolling_sum(x = SPY)) +}) diff --git a/tests/testthat/test-ta_VAR.R b/tests/testthat/test-ta_VAR.R index 5bb9ca692..5d35077b8 100644 --- a/tests/testthat/test-ta_VAR.R +++ b/tests/testthat/test-ta_VAR.R @@ -57,3 +57,26 @@ testthat::test_that(desc = 'Lookback equivalence', code = { expected = lookback(FUN = rolling_variance, x = SPY[, 1]) ) }) + +## object +testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + + output <- rolling_variance(x = GOOGL[, 1]) + + testthat::expect_true(inherits(output, "xts")) + testthat::expect_equal(zoo::index(output), zoo::index(GOOGL)) + testthat::expect_equal( + object = as.numeric(output), + expected = as.numeric(rolling_variance(x = as.numeric(GOOGL[, 1]))) + ) +}) + +## multi-column input must error +## instead of being flattened +testthat::test_that(desc = 'Multivariate input errors', code = { + testthat::skip_if_not_installed("xts") + + testthat::expect_error(rolling_variance(x = GOOGL)) + testthat::expect_error(rolling_variance(x = SPY)) +}) From 242803e0867aa59aac685275a78772abc4c6a817 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 16:38:58 +0200 Subject: [PATCH 15/22] :bug: Base types from the .numeric fast path * The .numeric methods strip the internal class unconditionally: single-output results are plain double vectors (dim and class dropped), multi-output results are plain matrices carrying the implicit c('matrix','array') class - the C-stamped c('ta_object','matrix','array') tag no longer leaks out of the vector fast path. Column names and the lookback attribute are kept, inherits(x, 'matrix') finally agrees with is.matrix(x), and base as.matrix()/as.data.frame() coerce the results correctly. * Unknown arguments landing in '...' on the numeric path now warn ("'...' is passed but is unused for vectors.") instead of being silently swallowed - the only signal a case-typo'd parameter name (timeperiod = 10) will ever produce. Passing 'cols' keeps its existing warn-and-compute behavior. * Generated numeric tests lock the new shapes: expect_false(inherits(x, 'matrix')) for single-output, expect_identical(class(x), c('matrix', 'array')) for multi-output. --- R/ta_APO.R | 5 +++++ R/ta_AVGDEV.R | 5 +++++ R/ta_BBANDS.R | 5 +++++ R/ta_CMO.R | 5 +++++ R/ta_CMOU.R | 5 +++++ R/ta_DEMA.R | 5 +++++ R/ta_EMA.R | 5 +++++ R/ta_HMA.R | 5 +++++ R/ta_HT_DCPERIOD.R | 5 +++++ R/ta_HT_DCPHASE.R | 5 +++++ R/ta_HT_PHASOR.R | 5 +++++ R/ta_HT_SINE.R | 5 +++++ R/ta_HT_TRENDLINE.R | 5 +++++ R/ta_HT_TRENDMODE.R | 5 +++++ R/ta_KAMA.R | 5 +++++ R/ta_MACD.R | 5 +++++ R/ta_MACDEXT.R | 5 +++++ R/ta_MACDFIX.R | 5 +++++ R/ta_MAMA.R | 5 +++++ R/ta_MAVP.R | 5 +++++ R/ta_MIDPOINT.R | 5 +++++ R/ta_MOM.R | 5 +++++ R/ta_PPO.R | 5 +++++ R/ta_PVO.R | 5 +++++ R/ta_ROCR.R | 5 +++++ R/ta_RSI.R | 5 +++++ R/ta_SMA.R | 5 +++++ R/ta_STOCHRSI.R | 5 +++++ R/ta_T3.R | 5 +++++ R/ta_TEMA.R | 5 +++++ R/ta_TRIMA.R | 5 +++++ R/ta_TRIX.R | 5 +++++ R/ta_VOLUME.R | 5 +++++ R/ta_VWMA.R | 5 +++++ R/ta_WMA.R | 5 +++++ codegen/src/testthat.rs | 2 ++ codegen/templates/moving_average_template.R | 5 +++++ codegen/templates/numeric_template.R | 5 +++++ tests/testthat/test-ta_APO.R | 2 ++ tests/testthat/test-ta_AVGDEV.R | 2 ++ tests/testthat/test-ta_BBANDS.R | 2 ++ tests/testthat/test-ta_CMO.R | 2 ++ tests/testthat/test-ta_CMOU.R | 2 ++ tests/testthat/test-ta_DEMA.R | 2 ++ tests/testthat/test-ta_EMA.R | 2 ++ tests/testthat/test-ta_HMA.R | 2 ++ tests/testthat/test-ta_HT_DCPERIOD.R | 2 ++ tests/testthat/test-ta_HT_DCPHASE.R | 2 ++ tests/testthat/test-ta_HT_PHASOR.R | 2 ++ tests/testthat/test-ta_HT_SINE.R | 2 ++ tests/testthat/test-ta_HT_TRENDLINE.R | 2 ++ tests/testthat/test-ta_HT_TRENDMODE.R | 2 ++ tests/testthat/test-ta_KAMA.R | 2 ++ tests/testthat/test-ta_MACD.R | 2 ++ tests/testthat/test-ta_MACDEXT.R | 2 ++ tests/testthat/test-ta_MACDFIX.R | 2 ++ tests/testthat/test-ta_MAMA.R | 2 ++ tests/testthat/test-ta_MAVP.R | 2 ++ tests/testthat/test-ta_MIDPOINT.R | 2 ++ tests/testthat/test-ta_MOM.R | 2 ++ tests/testthat/test-ta_PPO.R | 2 ++ tests/testthat/test-ta_PVO.R | 2 ++ tests/testthat/test-ta_ROCR.R | 2 ++ tests/testthat/test-ta_RSI.R | 2 ++ tests/testthat/test-ta_SMA.R | 2 ++ tests/testthat/test-ta_STOCHRSI.R | 2 ++ tests/testthat/test-ta_T3.R | 2 ++ tests/testthat/test-ta_TEMA.R | 2 ++ tests/testthat/test-ta_TRIMA.R | 2 ++ tests/testthat/test-ta_TRIX.R | 2 ++ tests/testthat/test-ta_WMA.R | 2 ++ 71 files changed, 253 insertions(+) diff --git a/R/ta_APO.R b/R/ta_APO.R index d4c20ba90..1f01e1484 100644 --- a/R/ta_APO.R +++ b/R/ta_APO.R @@ -211,6 +211,10 @@ absolute_price_oscillator.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -225,6 +229,7 @@ absolute_price_oscillator.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_AVGDEV.R b/R/ta_AVGDEV.R index 62c661c43..206bbef4f 100644 --- a/R/ta_AVGDEV.R +++ b/R/ta_AVGDEV.R @@ -185,6 +185,10 @@ average_deviation.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -197,6 +201,7 @@ average_deviation.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_BBANDS.R b/R/ta_BBANDS.R index b3ba9b067..afac0833c 100644 --- a/R/ta_BBANDS.R +++ b/R/ta_BBANDS.R @@ -223,6 +223,10 @@ bollinger_bands.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -238,6 +242,7 @@ bollinger_bands.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_CMO.R b/R/ta_CMO.R index d17320dcf..b1cabeb13 100644 --- a/R/ta_CMO.R +++ b/R/ta_CMO.R @@ -185,6 +185,10 @@ chande_momentum_oscillator.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -197,6 +201,7 @@ chande_momentum_oscillator.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_CMOU.R b/R/ta_CMOU.R index 43aa0f9d6..1acb9f126 100644 --- a/R/ta_CMOU.R +++ b/R/ta_CMOU.R @@ -185,6 +185,10 @@ unsmoothed_chande_momentum_oscillator.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -197,6 +201,7 @@ unsmoothed_chande_momentum_oscillator.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_DEMA.R b/R/ta_DEMA.R index fc7b9d30f..30b99cc7e 100644 --- a/R/ta_DEMA.R +++ b/R/ta_DEMA.R @@ -198,6 +198,10 @@ double_exponential_moving_average.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass to 'C' directly ## with the input vector x <- .Call( @@ -210,6 +214,7 @@ double_exponential_moving_average.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_EMA.R b/R/ta_EMA.R index 99a8e11dd..a54df086d 100644 --- a/R/ta_EMA.R +++ b/R/ta_EMA.R @@ -198,6 +198,10 @@ exponential_moving_average.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass to 'C' directly ## with the input vector x <- .Call( @@ -210,6 +214,7 @@ exponential_moving_average.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_HMA.R b/R/ta_HMA.R index 687b5ba91..0cec151d8 100644 --- a/R/ta_HMA.R +++ b/R/ta_HMA.R @@ -198,6 +198,10 @@ hull_moving_average.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass to 'C' directly ## with the input vector x <- .Call( @@ -210,6 +214,7 @@ hull_moving_average.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_HT_DCPERIOD.R b/R/ta_HT_DCPERIOD.R index fc6b093e3..346b8f8fd 100644 --- a/R/ta_HT_DCPERIOD.R +++ b/R/ta_HT_DCPERIOD.R @@ -173,6 +173,10 @@ dominant_cycle_period.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -184,6 +188,7 @@ dominant_cycle_period.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_HT_DCPHASE.R b/R/ta_HT_DCPHASE.R index 606290b91..177d2a31d 100644 --- a/R/ta_HT_DCPHASE.R +++ b/R/ta_HT_DCPHASE.R @@ -173,6 +173,10 @@ dominant_cycle_phase.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -184,6 +188,7 @@ dominant_cycle_phase.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_HT_PHASOR.R b/R/ta_HT_PHASOR.R index f3fe09cda..91bd1f712 100644 --- a/R/ta_HT_PHASOR.R +++ b/R/ta_HT_PHASOR.R @@ -173,6 +173,10 @@ phasor_components.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -184,6 +188,7 @@ phasor_components.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_HT_SINE.R b/R/ta_HT_SINE.R index 1f902a412..f79ee6e7b 100644 --- a/R/ta_HT_SINE.R +++ b/R/ta_HT_SINE.R @@ -173,6 +173,10 @@ sine_wave.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -184,6 +188,7 @@ sine_wave.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_HT_TRENDLINE.R b/R/ta_HT_TRENDLINE.R index 0b75780ae..dff115933 100644 --- a/R/ta_HT_TRENDLINE.R +++ b/R/ta_HT_TRENDLINE.R @@ -166,6 +166,10 @@ trendline.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -177,6 +181,7 @@ trendline.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_HT_TRENDMODE.R b/R/ta_HT_TRENDMODE.R index eaf94357e..d5e7f9cbc 100644 --- a/R/ta_HT_TRENDMODE.R +++ b/R/ta_HT_TRENDMODE.R @@ -173,6 +173,10 @@ trend_cycle_mode.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -184,6 +188,7 @@ trend_cycle_mode.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_KAMA.R b/R/ta_KAMA.R index d2ff67a3e..99fa17322 100644 --- a/R/ta_KAMA.R +++ b/R/ta_KAMA.R @@ -198,6 +198,10 @@ kaufman_adaptive_moving_average.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass to 'C' directly ## with the input vector x <- .Call( @@ -210,6 +214,7 @@ kaufman_adaptive_moving_average.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_MACD.R b/R/ta_MACD.R index e9643528a..07b44fdd1 100644 --- a/R/ta_MACD.R +++ b/R/ta_MACD.R @@ -211,6 +211,10 @@ moving_average_convergence_divergence.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -225,6 +229,7 @@ moving_average_convergence_divergence.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_MACDEXT.R b/R/ta_MACDEXT.R index 3616e31a9..2964a874a 100644 --- a/R/ta_MACDEXT.R +++ b/R/ta_MACDEXT.R @@ -250,6 +250,10 @@ extended_moving_average_convergence_divergence.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -267,6 +271,7 @@ extended_moving_average_convergence_divergence.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_MACDFIX.R b/R/ta_MACDFIX.R index 8ee2216e9..283a23a5a 100644 --- a/R/ta_MACDFIX.R +++ b/R/ta_MACDFIX.R @@ -185,6 +185,10 @@ fixed_moving_average_convergence_divergence.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -197,6 +201,7 @@ fixed_moving_average_convergence_divergence.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_MAMA.R b/R/ta_MAMA.R index 9b9c618b0..bca143804 100644 --- a/R/ta_MAMA.R +++ b/R/ta_MAMA.R @@ -228,6 +228,10 @@ mesa_adaptive_moving_average.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass to 'C' directly ## with the input vector x <- .Call( @@ -241,6 +245,7 @@ mesa_adaptive_moving_average.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_MAVP.R b/R/ta_MAVP.R index 501b18a55..884e70da8 100644 --- a/R/ta_MAVP.R +++ b/R/ta_MAVP.R @@ -225,6 +225,10 @@ variable_moving_average_period.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -240,6 +244,7 @@ variable_moving_average_period.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_MIDPOINT.R b/R/ta_MIDPOINT.R index 4108ef627..f096fa783 100644 --- a/R/ta_MIDPOINT.R +++ b/R/ta_MIDPOINT.R @@ -185,6 +185,10 @@ midpoint_period.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -197,6 +201,7 @@ midpoint_period.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_MOM.R b/R/ta_MOM.R index 4615ff0d5..8ba525ea2 100644 --- a/R/ta_MOM.R +++ b/R/ta_MOM.R @@ -178,6 +178,10 @@ momentum.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -190,6 +194,7 @@ momentum.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_PPO.R b/R/ta_PPO.R index 02bcb9bd8..a3447630b 100644 --- a/R/ta_PPO.R +++ b/R/ta_PPO.R @@ -211,6 +211,10 @@ percentage_price_oscillator.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -225,6 +229,7 @@ percentage_price_oscillator.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_PVO.R b/R/ta_PVO.R index 33dc2b31b..b048354e8 100644 --- a/R/ta_PVO.R +++ b/R/ta_PVO.R @@ -211,6 +211,10 @@ percentage_volume_oscillator.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -225,6 +229,7 @@ percentage_volume_oscillator.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_ROCR.R b/R/ta_ROCR.R index 1b6ecde8c..af813def6 100644 --- a/R/ta_ROCR.R +++ b/R/ta_ROCR.R @@ -185,6 +185,10 @@ ratio_of_change.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -197,6 +201,7 @@ ratio_of_change.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_RSI.R b/R/ta_RSI.R index 179c4f065..f2634ae38 100644 --- a/R/ta_RSI.R +++ b/R/ta_RSI.R @@ -185,6 +185,10 @@ relative_strength_index.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -197,6 +201,7 @@ relative_strength_index.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_SMA.R b/R/ta_SMA.R index 4e3a8d94f..14e111017 100644 --- a/R/ta_SMA.R +++ b/R/ta_SMA.R @@ -198,6 +198,10 @@ simple_moving_average.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass to 'C' directly ## with the input vector x <- .Call( @@ -210,6 +214,7 @@ simple_moving_average.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_STOCHRSI.R b/R/ta_STOCHRSI.R index fd2251d5e..f2a51f7e7 100644 --- a/R/ta_STOCHRSI.R +++ b/R/ta_STOCHRSI.R @@ -223,6 +223,10 @@ stochastic_relative_strength_index.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -238,6 +242,7 @@ stochastic_relative_strength_index.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_T3.R b/R/ta_T3.R index 9299171f7..5c365bac5 100644 --- a/R/ta_T3.R +++ b/R/ta_T3.R @@ -213,6 +213,10 @@ t3_exponential_moving_average.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass to 'C' directly ## with the input vector x <- .Call( @@ -226,6 +230,7 @@ t3_exponential_moving_average.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_TEMA.R b/R/ta_TEMA.R index 01ed0eb5f..b39fdf272 100644 --- a/R/ta_TEMA.R +++ b/R/ta_TEMA.R @@ -198,6 +198,10 @@ triple_exponential_moving_average.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass to 'C' directly ## with the input vector x <- .Call( @@ -210,6 +214,7 @@ triple_exponential_moving_average.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_TRIMA.R b/R/ta_TRIMA.R index 394cf615a..c70940f6b 100644 --- a/R/ta_TRIMA.R +++ b/R/ta_TRIMA.R @@ -198,6 +198,10 @@ triangular_moving_average.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass to 'C' directly ## with the input vector x <- .Call( @@ -210,6 +214,7 @@ triangular_moving_average.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_TRIX.R b/R/ta_TRIX.R index aa87e8b4c..a72511251 100644 --- a/R/ta_TRIX.R +++ b/R/ta_TRIX.R @@ -185,6 +185,10 @@ triple_exponential_average.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -197,6 +201,7 @@ triple_exponential_average.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_VOLUME.R b/R/ta_VOLUME.R index fbc70e796..13031e80f 100644 --- a/R/ta_VOLUME.R +++ b/R/ta_VOLUME.R @@ -181,6 +181,10 @@ trading_volume.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -195,6 +199,7 @@ trading_volume.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_VWMA.R b/R/ta_VWMA.R index 026936909..79598c003 100644 --- a/R/ta_VWMA.R +++ b/R/ta_VWMA.R @@ -199,6 +199,10 @@ volume_weighted_moving_average.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass to 'C' directly ## with the input vector x <- .Call( @@ -211,6 +215,7 @@ volume_weighted_moving_average.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/R/ta_WMA.R b/R/ta_WMA.R index 884f74b9b..abbc429f3 100644 --- a/R/ta_WMA.R +++ b/R/ta_WMA.R @@ -198,6 +198,10 @@ weighted_moving_average.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass to 'C' directly ## with the input vector x <- .Call( @@ -210,6 +214,7 @@ weighted_moving_average.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/codegen/src/testthat.rs b/codegen/src/testthat.rs index 85eddb451..dc6f12cb4 100644 --- a/codegen/src/testthat.rs +++ b/codegen/src/testthat.rs @@ -405,9 +405,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/codegen/templates/moving_average_template.R b/codegen/templates/moving_average_template.R index 612fd3080..e8c4995ef 100644 --- a/codegen/templates/moving_average_template.R +++ b/codegen/templates/moving_average_template.R @@ -195,6 +195,10 @@ ${FUN}.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass to 'C' directly ## with the input vector x <- .Call( @@ -206,6 +210,7 @@ ${FUN}.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/codegen/templates/numeric_template.R b/codegen/templates/numeric_template.R index f96709b0d..8285ff769 100644 --- a/codegen/templates/numeric_template.R +++ b/codegen/templates/numeric_template.R @@ -17,6 +17,10 @@ ${FUN}.numeric <- function( warning("'cols' is passed but is unused for vectors.") } + if (...length()) { + warning("'...' is passed but is unused for vectors.") + } + ## pass the argument directly ## to 'C' x <- .Call( @@ -28,6 +32,7 @@ ${FUN}.numeric <- function( if (dim(x)[2] == 1L) { dim(x) <- NULL } + class(x) <- NULL x } diff --git a/tests/testthat/test-ta_APO.R b/tests/testthat/test-ta_APO.R index 95a9c5044..31673ef61 100644 --- a/tests/testthat/test-ta_APO.R +++ b/tests/testthat/test-ta_APO.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_AVGDEV.R b/tests/testthat/test-ta_AVGDEV.R index c7df0d498..645d89413 100644 --- a/tests/testthat/test-ta_AVGDEV.R +++ b/tests/testthat/test-ta_AVGDEV.R @@ -199,9 +199,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_BBANDS.R b/tests/testthat/test-ta_BBANDS.R index 36d821479..d0f0a61ca 100644 --- a/tests/testthat/test-ta_BBANDS.R +++ b/tests/testthat/test-ta_BBANDS.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_CMO.R b/tests/testthat/test-ta_CMO.R index f73ef8a7e..ff7730fdd 100644 --- a/tests/testthat/test-ta_CMO.R +++ b/tests/testthat/test-ta_CMO.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_CMOU.R b/tests/testthat/test-ta_CMOU.R index ec9d25da3..3ca44cdae 100644 --- a/tests/testthat/test-ta_CMOU.R +++ b/tests/testthat/test-ta_CMOU.R @@ -288,9 +288,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_DEMA.R b/tests/testthat/test-ta_DEMA.R index fcba06a7a..c56a1a313 100644 --- a/tests/testthat/test-ta_DEMA.R +++ b/tests/testthat/test-ta_DEMA.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_EMA.R b/tests/testthat/test-ta_EMA.R index d6273f620..a8efaf744 100644 --- a/tests/testthat/test-ta_EMA.R +++ b/tests/testthat/test-ta_EMA.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_HMA.R b/tests/testthat/test-ta_HMA.R index 451540a64..787aa8d62 100644 --- a/tests/testthat/test-ta_HMA.R +++ b/tests/testthat/test-ta_HMA.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_HT_DCPERIOD.R b/tests/testthat/test-ta_HT_DCPERIOD.R index fa5bf1f0a..87b1b7563 100644 --- a/tests/testthat/test-ta_HT_DCPERIOD.R +++ b/tests/testthat/test-ta_HT_DCPERIOD.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_HT_DCPHASE.R b/tests/testthat/test-ta_HT_DCPHASE.R index 1dc664ddc..060443c1d 100644 --- a/tests/testthat/test-ta_HT_DCPHASE.R +++ b/tests/testthat/test-ta_HT_DCPHASE.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_HT_PHASOR.R b/tests/testthat/test-ta_HT_PHASOR.R index d774875b2..e82b7fe08 100644 --- a/tests/testthat/test-ta_HT_PHASOR.R +++ b/tests/testthat/test-ta_HT_PHASOR.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_HT_SINE.R b/tests/testthat/test-ta_HT_SINE.R index 92af5848c..eead27cff 100644 --- a/tests/testthat/test-ta_HT_SINE.R +++ b/tests/testthat/test-ta_HT_SINE.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_HT_TRENDLINE.R b/tests/testthat/test-ta_HT_TRENDLINE.R index a32fb84ad..a20f68dec 100644 --- a/tests/testthat/test-ta_HT_TRENDLINE.R +++ b/tests/testthat/test-ta_HT_TRENDLINE.R @@ -267,9 +267,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_HT_TRENDMODE.R b/tests/testthat/test-ta_HT_TRENDMODE.R index b42877523..7e6857c86 100644 --- a/tests/testthat/test-ta_HT_TRENDMODE.R +++ b/tests/testthat/test-ta_HT_TRENDMODE.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_KAMA.R b/tests/testthat/test-ta_KAMA.R index e501b2fde..bbf471fc0 100644 --- a/tests/testthat/test-ta_KAMA.R +++ b/tests/testthat/test-ta_KAMA.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_MACD.R b/tests/testthat/test-ta_MACD.R index f1286795c..147870651 100644 --- a/tests/testthat/test-ta_MACD.R +++ b/tests/testthat/test-ta_MACD.R @@ -288,9 +288,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_MACDEXT.R b/tests/testthat/test-ta_MACDEXT.R index 51864364f..65e513470 100644 --- a/tests/testthat/test-ta_MACDEXT.R +++ b/tests/testthat/test-ta_MACDEXT.R @@ -300,9 +300,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_MACDFIX.R b/tests/testthat/test-ta_MACDFIX.R index 29fdcf6d6..1c429ed13 100644 --- a/tests/testthat/test-ta_MACDFIX.R +++ b/tests/testthat/test-ta_MACDFIX.R @@ -294,9 +294,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_MAMA.R b/tests/testthat/test-ta_MAMA.R index 1c9c005d8..1ba23fe2a 100644 --- a/tests/testthat/test-ta_MAMA.R +++ b/tests/testthat/test-ta_MAMA.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_MAVP.R b/tests/testthat/test-ta_MAVP.R index 909bb8e76..395adbe4f 100644 --- a/tests/testthat/test-ta_MAVP.R +++ b/tests/testthat/test-ta_MAVP.R @@ -328,9 +328,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_MIDPOINT.R b/tests/testthat/test-ta_MIDPOINT.R index b3d237ced..ad7ff77da 100644 --- a/tests/testthat/test-ta_MIDPOINT.R +++ b/tests/testthat/test-ta_MIDPOINT.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_MOM.R b/tests/testthat/test-ta_MOM.R index 558e63016..e63949294 100644 --- a/tests/testthat/test-ta_MOM.R +++ b/tests/testthat/test-ta_MOM.R @@ -267,9 +267,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_PPO.R b/tests/testthat/test-ta_PPO.R index 2839a0f77..ac71ce66a 100644 --- a/tests/testthat/test-ta_PPO.R +++ b/tests/testthat/test-ta_PPO.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_PVO.R b/tests/testthat/test-ta_PVO.R index 348e09fad..d3256e1bf 100644 --- a/tests/testthat/test-ta_PVO.R +++ b/tests/testthat/test-ta_PVO.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_ROCR.R b/tests/testthat/test-ta_ROCR.R index 3a52c25de..89894efd5 100644 --- a/tests/testthat/test-ta_ROCR.R +++ b/tests/testthat/test-ta_ROCR.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_RSI.R b/tests/testthat/test-ta_RSI.R index 38c61e729..1f5100835 100644 --- a/tests/testthat/test-ta_RSI.R +++ b/tests/testthat/test-ta_RSI.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_SMA.R b/tests/testthat/test-ta_SMA.R index 1a18d6994..4a576ec0e 100644 --- a/tests/testthat/test-ta_SMA.R +++ b/tests/testthat/test-ta_SMA.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_STOCHRSI.R b/tests/testthat/test-ta_STOCHRSI.R index bfa5693e5..de778c8fa 100644 --- a/tests/testthat/test-ta_STOCHRSI.R +++ b/tests/testthat/test-ta_STOCHRSI.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_T3.R b/tests/testthat/test-ta_T3.R index 90618f2d3..d61aa5432 100644 --- a/tests/testthat/test-ta_T3.R +++ b/tests/testthat/test-ta_T3.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_TEMA.R b/tests/testthat/test-ta_TEMA.R index 098b9e1db..2d7750a40 100644 --- a/tests/testthat/test-ta_TEMA.R +++ b/tests/testthat/test-ta_TEMA.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_TRIMA.R b/tests/testthat/test-ta_TRIMA.R index 8b782824a..556d53374 100644 --- a/tests/testthat/test-ta_TRIMA.R +++ b/tests/testthat/test-ta_TRIMA.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_TRIX.R b/tests/testthat/test-ta_TRIX.R index bd8ff0e67..cf9f5ad44 100644 --- a/tests/testthat/test-ta_TRIX.R +++ b/tests/testthat/test-ta_TRIX.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) diff --git a/tests/testthat/test-ta_WMA.R b/tests/testthat/test-ta_WMA.R index d7e631177..4a09165ea 100644 --- a/tests/testthat/test-ta_WMA.R +++ b/tests/testthat/test-ta_WMA.R @@ -285,9 +285,11 @@ testthat::test_that(desc = ' methods', code = { if (NCOL(x) == 1L) { testthat::expect_true(is.double(x) || is.integer(x)) testthat::expect_false(is.matrix(x)) + testthat::expect_false(inherits(x, "matrix")) testthat::expect_equal(length(x), target_length) } else { testthat::expect_true(is.matrix(x)) + testthat::expect_identical(class(x), c("matrix", "array")) testthat::expect_equal(nrow(x), target_length) } }) From c54cc4628dbaf7a7c1f9c328c70acd709d4b1914 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 20:02:46 +0200 Subject: [PATCH 16/22] :white_check_mark: Hardened the test suite around * tests/testthat/helper-library.R attaches {xts} only when it is installed, and every generated test block carries skip_if_not_installed('xts') - the suite no longer hard-depends on a Suggests package (verified against a library with xts/zoo hidden: everything loads, the xts blocks skip cleanly, zero failures). * Every generated test file gained a 'Value parity with ()' block: the result must equal the lowercase reference numerically, both on the GOOGL fixture and on an alphabetically sorted copy that places 'Adjusted' before the OHLCV columns - locking the column-resolution contract (formula order, suffix matching, no substring collisions) for all 129 indicators. * test-series.R gained unit tests for the resolution layer itself: formula-order selection, quantmod-style suffix matches, lowercase names, explicit 'cols =' order, and the error/warning contracts (no match, ambiguity, short formula, unused 'subset'); plus a vanilla-session subprocess regression (skip_on_cran) proving RSI(GOOGL) works without {xts} attached. --- codegen/src/testthat.rs | 31 ++++- tests/testthat/helper-library.R | 4 +- tests/testthat/test-series.R | 123 +++++++++++++++++++ tests/testthat/test-ta_ACCBANDS.R | 31 ++++- tests/testthat/test-ta_AD.R | 35 +++++- tests/testthat/test-ta_ADOSC.R | 35 +++++- tests/testthat/test-ta_ADX.R | 35 +++++- tests/testthat/test-ta_ADXR.R | 35 +++++- tests/testthat/test-ta_APO.R | 31 ++++- tests/testthat/test-ta_AROON.R | 29 ++++- tests/testthat/test-ta_AROONOSC.R | 31 ++++- tests/testthat/test-ta_ATR.R | 31 ++++- tests/testthat/test-ta_AVGDEV.R | 31 ++++- tests/testthat/test-ta_AVGPRICE.R | 31 ++++- tests/testthat/test-ta_BBANDS.R | 31 ++++- tests/testthat/test-ta_BOP.R | 31 ++++- tests/testthat/test-ta_CCI.R | 31 ++++- tests/testthat/test-ta_CDL2CROWS.R | 31 ++++- tests/testthat/test-ta_CDL3BLACKCROWS.R | 31 ++++- tests/testthat/test-ta_CDL3INSIDE.R | 31 ++++- tests/testthat/test-ta_CDL3LINESTRIKE.R | 31 ++++- tests/testthat/test-ta_CDL3OUTSIDE.R | 31 ++++- tests/testthat/test-ta_CDL3STARSINSOUTH.R | 31 ++++- tests/testthat/test-ta_CDL3WHITESOLDIERS.R | 31 ++++- tests/testthat/test-ta_CDLABANDONEDBABY.R | 31 ++++- tests/testthat/test-ta_CDLADVANCEBLOCK.R | 31 ++++- tests/testthat/test-ta_CDLBELTHOLD.R | 31 ++++- tests/testthat/test-ta_CDLBREAKAWAY.R | 31 ++++- tests/testthat/test-ta_CDLCLOSINGMARUBOZU.R | 31 ++++- tests/testthat/test-ta_CDLCONCEALBABYSWALL.R | 31 ++++- tests/testthat/test-ta_CDLCOUNTERATTACK.R | 31 ++++- tests/testthat/test-ta_CDLDARKCLOUDCOVER.R | 31 ++++- tests/testthat/test-ta_CDLDOJI.R | 29 ++++- tests/testthat/test-ta_CDLDOJISTAR.R | 31 ++++- tests/testthat/test-ta_CDLDRAGONFLYDOJI.R | 31 ++++- tests/testthat/test-ta_CDLENGULFING.R | 31 ++++- tests/testthat/test-ta_CDLEVENINGDOJISTAR.R | 31 ++++- tests/testthat/test-ta_CDLEVENINGSTAR.R | 31 ++++- tests/testthat/test-ta_CDLGAPSIDESIDEWHITE.R | 31 ++++- tests/testthat/test-ta_CDLGRAVESTONEDOJI.R | 31 ++++- tests/testthat/test-ta_CDLHAMMER.R | 29 ++++- tests/testthat/test-ta_CDLHANGINGMAN.R | 31 ++++- tests/testthat/test-ta_CDLHARAMI.R | 29 ++++- tests/testthat/test-ta_CDLHARAMICROSS.R | 31 ++++- tests/testthat/test-ta_CDLHIGHWAVE.R | 31 ++++- tests/testthat/test-ta_CDLHIKKAKE.R | 29 ++++- tests/testthat/test-ta_CDLHIKKAKEMOD.R | 31 ++++- tests/testthat/test-ta_CDLHOMINGPIGEON.R | 31 ++++- tests/testthat/test-ta_CDLIDENTICAL3CROWS.R | 31 ++++- tests/testthat/test-ta_CDLINNECK.R | 29 ++++- tests/testthat/test-ta_CDLINVERTEDHAMMER.R | 31 ++++- tests/testthat/test-ta_CDLKICKING.R | 29 ++++- tests/testthat/test-ta_CDLKICKINGBYLENGTH.R | 31 ++++- tests/testthat/test-ta_CDLLADDERBOTTOM.R | 31 ++++- tests/testthat/test-ta_CDLLONGLEGGEDDOJI.R | 31 ++++- tests/testthat/test-ta_CDLLONGLINE.R | 31 ++++- tests/testthat/test-ta_CDLMARUBOZU.R | 31 ++++- tests/testthat/test-ta_CDLMATCHINGLOW.R | 31 ++++- tests/testthat/test-ta_CDLMATHOLD.R | 31 ++++- tests/testthat/test-ta_CDLMORNINGDOJISTAR.R | 31 ++++- tests/testthat/test-ta_CDLMORNINGSTAR.R | 31 ++++- tests/testthat/test-ta_CDLONNECK.R | 29 ++++- tests/testthat/test-ta_CDLPIERCING.R | 31 ++++- tests/testthat/test-ta_CDLRICKSHAWMAN.R | 31 ++++- tests/testthat/test-ta_CDLRISEFALL3METHODS.R | 31 ++++- tests/testthat/test-ta_CDLSEPARATINGLINES.R | 31 ++++- tests/testthat/test-ta_CDLSHOOTINGSTAR.R | 31 ++++- tests/testthat/test-ta_CDLSHORTLINE.R | 31 ++++- tests/testthat/test-ta_CDLSPINNINGTOP.R | 31 ++++- tests/testthat/test-ta_CDLSTALLEDPATTERN.R | 31 ++++- tests/testthat/test-ta_CDLSTICKSANDWICH.R | 31 ++++- tests/testthat/test-ta_CDLTAKURI.R | 29 ++++- tests/testthat/test-ta_CDLTASUKIGAP.R | 31 ++++- tests/testthat/test-ta_CDLTHRUSTING.R | 31 ++++- tests/testthat/test-ta_CDLTRISTAR.R | 29 ++++- tests/testthat/test-ta_CDLUNIQUE3RIVER.R | 31 ++++- tests/testthat/test-ta_CDLUPSIDEGAP2CROWS.R | 31 ++++- tests/testthat/test-ta_CDLXSIDEGAP3METHODS.R | 31 ++++- tests/testthat/test-ta_CMF.R | 31 ++++- tests/testthat/test-ta_CMO.R | 31 ++++- tests/testthat/test-ta_CMOU.R | 35 +++++- tests/testthat/test-ta_DEMA.R | 33 ++++- tests/testthat/test-ta_DX.R | 31 ++++- tests/testthat/test-ta_EMA.R | 31 ++++- tests/testthat/test-ta_HMA.R | 31 ++++- tests/testthat/test-ta_HT_DCPERIOD.R | 31 ++++- tests/testthat/test-ta_HT_DCPHASE.R | 31 ++++- tests/testthat/test-ta_HT_PHASOR.R | 31 ++++- tests/testthat/test-ta_HT_SINE.R | 31 ++++- tests/testthat/test-ta_HT_TRENDLINE.R | 31 ++++- tests/testthat/test-ta_HT_TRENDMODE.R | 31 ++++- tests/testthat/test-ta_IMI.R | 31 ++++- tests/testthat/test-ta_KAMA.R | 31 ++++- tests/testthat/test-ta_MACD.R | 35 +++++- tests/testthat/test-ta_MACDEXT.R | 35 +++++- tests/testthat/test-ta_MACDFIX.R | 35 +++++- tests/testthat/test-ta_MAMA.R | 31 ++++- tests/testthat/test-ta_MAVP.R | 38 +++++- tests/testthat/test-ta_MEDPRICE.R | 31 ++++- tests/testthat/test-ta_MFI.R | 31 ++++- tests/testthat/test-ta_MIDPOINT.R | 31 ++++- tests/testthat/test-ta_MIDPRICE.R | 31 ++++- tests/testthat/test-ta_MINUS_DI.R | 31 ++++- tests/testthat/test-ta_MINUS_DM.R | 31 ++++- tests/testthat/test-ta_MOM.R | 31 ++++- tests/testthat/test-ta_NATR.R | 31 ++++- tests/testthat/test-ta_NVI.R | 31 ++++- tests/testthat/test-ta_OBV.R | 31 ++++- tests/testthat/test-ta_PLUS_DI.R | 31 ++++- tests/testthat/test-ta_PLUS_DM.R | 31 ++++- tests/testthat/test-ta_PPO.R | 31 ++++- tests/testthat/test-ta_PVI.R | 31 ++++- tests/testthat/test-ta_PVO.R | 31 ++++- tests/testthat/test-ta_ROCR.R | 31 ++++- tests/testthat/test-ta_RSI.R | 31 ++++- tests/testthat/test-ta_SAR.R | 31 ++++- tests/testthat/test-ta_SAREXT.R | 35 +++++- tests/testthat/test-ta_SMA.R | 31 ++++- tests/testthat/test-ta_STOCH.R | 31 ++++- tests/testthat/test-ta_STOCHF.R | 31 ++++- tests/testthat/test-ta_STOCHRSI.R | 35 +++++- tests/testthat/test-ta_T3.R | 31 ++++- tests/testthat/test-ta_TEMA.R | 33 ++++- tests/testthat/test-ta_TRANGE.R | 31 ++++- tests/testthat/test-ta_TRIMA.R | 31 ++++- tests/testthat/test-ta_TRIX.R | 31 ++++- tests/testthat/test-ta_TYPPRICE.R | 31 ++++- tests/testthat/test-ta_ULTOSC.R | 31 ++++- tests/testthat/test-ta_VWMA.R | 31 ++++- tests/testthat/test-ta_WCLPRICE.R | 31 ++++- tests/testthat/test-ta_WILLR.R | 31 ++++- tests/testthat/test-ta_WMA.R | 31 ++++- 132 files changed, 4057 insertions(+), 131 deletions(-) diff --git a/codegen/src/testthat.rs b/codegen/src/testthat.rs index dc6f12cb4..e5fcbf89c 100644 --- a/codegen/src/testthat.rs +++ b/codegen/src/testthat.rs @@ -164,8 +164,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -173,6 +175,31 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(${FUN}(reference${PASS_GOOGL}))) + + testthat::expect_equal( + object = unname(zoo::coredata(${FUN}(GOOGL${PASS_GOOGL}))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(${FUN}(GOOGL[, sort(colnames(GOOGL))]${PASS_GOOGL}))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. @@ -517,6 +544,8 @@ mod tests { assert!(rendered.contains("-methods for ")); assert!(rendered.contains("-methods for ")); assert!(rendered.contains(" methods")); + assert!(rendered.contains("Value parity with ()")); + assert!(rendered.contains(r#"skip_if_not_installed("xts")"#)); assert!(!rendered.contains("${"), "unreplaced placeholder"); } diff --git a/tests/testthat/helper-library.R b/tests/testthat/helper-library.R index 34b61000a..f3d1c9161 100644 --- a/tests/testthat/helper-library.R +++ b/tests/testthat/helper-library.R @@ -1 +1,3 @@ -library(xts) +if (requireNamespace("xts", quietly = TRUE)) { + library(xts) +} diff --git a/tests/testthat/test-series.R b/tests/testthat/test-series.R index 2e45b2282..2bd14b0da 100644 --- a/tests/testthat/test-series.R +++ b/tests/testthat/test-series.R @@ -94,3 +94,126 @@ testthat::test_that(desc = "Attributes are respected", code = { SPY ) }) + +## tests for the column-resolution path: +## columns resolve per formula variable, in formula +## order - never by physical layout +testthat::test_that(desc = " columns resolve in formula order", code = { + testthat::skip_if_not_installed("xts") + + idx <- as.Date("2024-01-01") + 0:9 + + ## physical order must not dictate + ## the selection order + x <- xts::xts( + cbind(Low = 0:9, Close = 1:10, High = 2:11), + order.by = idx + ) + + testthat::expect_equal( + colnames(talib:::series(x = x, formula.default = ~ high + low + close)), + c("High", "Low", "Close") + ) + + ## quantmod-style names resolve + ## by suffix + colnames(x) <- paste0("GOOGL.", c("Low", "Close", "High")) + + testthat::expect_equal( + colnames(talib:::series(x = x, formula.default = ~ high + low + close)), + paste0("GOOGL.", c("High", "Low", "Close")) + ) + + ## lowercase names resolve exactly + colnames(x) <- c("low", "close", "high") + + testthat::expect_equal( + colnames(talib:::series(x = x, formula.default = ~ high + low + close)), + c("high", "low", "close") + ) + + ## an explicit formula is selected + ## exactly as passed + testthat::expect_equal( + colnames(talib:::series( + x = x, + formula = ~ low + high + close, + formula.default = ~ high + low + close + )), + c("low", "high", "close") + ) +}) + +testthat::test_that(desc = " column-resolution failures", code = { + testthat::skip_if_not_installed("xts") + + idx <- as.Date("2024-01-01") + 0:9 + x <- xts::xts( + cbind(high = 2:11, low = 0:9, close = 1:10), + order.by = idx + ) + + ## no matching columns + testthat::expect_error( + talib:::series( + x = xts::xts(cbind(a = 1:10, b = 1:10), order.by = idx), + formula.default = ~close + ) + ) + + ## ambiguous matches + ambiguous <- xts::xts(cbind(1:10, 1:10), order.by = idx) + colnames(ambiguous) <- c("Close", "close") + + testthat::expect_error( + talib:::series( + x = ambiguous, + formula.default = ~close + ) + ) + + ## an explicit formula shorter than + ## the default + testthat::expect_error( + talib:::series( + x = x, + formula = ~close, + formula.default = ~ high + low + close + ) + ) + + ## 'subset' and the remaining + ## model.frame-arguments are unused + testthat::expect_warning( + talib:::series( + x = x, + formula.default = ~ high + low + close, + subset = 1:5 + ) + ) +}) + +## the methods must work without {xts} attached: +## assert_xts() loads the namespace on demand +testthat::test_that(desc = " input works without {xts} attached", code = { + testthat::skip_if_not_installed("xts") + testthat::skip_on_cran() + + script <- paste0( + ".libPaths(", + paste(deparse(.libPaths()), collapse = ""), + "); library(talib); ", + "x <- relative_strength_index(GOOGL); ", + "stopifnot(inherits(x, 'xts'), !all(is.na(x))); ", + "cat('vanilla-ok')" + ) + + output <- suppressWarnings(system2( + file.path(R.home("bin"), "Rscript"), + args = c("--vanilla", "-e", shQuote(script)), + stdout = TRUE, + stderr = TRUE + )) + + testthat::expect_true(any(grepl("vanilla-ok", output))) +}) diff --git a/tests/testthat/test-ta_ACCBANDS.R b/tests/testthat/test-ta_ACCBANDS.R index 95ab588c3..10ad1cd57 100644 --- a/tests/testthat/test-ta_ACCBANDS.R +++ b/tests/testthat/test-ta_ACCBANDS.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(acceleration_bands(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(acceleration_bands(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(acceleration_bands(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_AD.R b/tests/testthat/test-ta_AD.R index f6b06c98b..bd57acec7 100644 --- a/tests/testthat/test-ta_AD.R +++ b/tests/testthat/test-ta_AD.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,37 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(chaikin_accumulation_distribution_line( + reference + ))) + + testthat::expect_equal( + object = unname(zoo::coredata(chaikin_accumulation_distribution_line( + GOOGL + ))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(chaikin_accumulation_distribution_line(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_ADOSC.R b/tests/testthat/test-ta_ADOSC.R index d4a54b127..c6cc476ed 100644 --- a/tests/testthat/test-ta_ADOSC.R +++ b/tests/testthat/test-ta_ADOSC.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -65,6 +67,37 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(chaikin_accumulation_distribution_oscillator( + reference + ))) + + testthat::expect_equal( + object = unname(zoo::coredata(chaikin_accumulation_distribution_oscillator( + GOOGL + ))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(chaikin_accumulation_distribution_oscillator(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_ADX.R b/tests/testthat/test-ta_ADX.R index 9b68643d8..0a7574c59 100644 --- a/tests/testthat/test-ta_ADX.R +++ b/tests/testthat/test-ta_ADX.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,37 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(average_directional_movement_index( + reference + ))) + + testthat::expect_equal( + object = unname(zoo::coredata(average_directional_movement_index( + GOOGL + ))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(average_directional_movement_index(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_ADXR.R b/tests/testthat/test-ta_ADXR.R index f2b4390db..a9229af28 100644 --- a/tests/testthat/test-ta_ADXR.R +++ b/tests/testthat/test-ta_ADXR.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,37 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(average_directional_movement_index_rating( + reference + ))) + + testthat::expect_equal( + object = unname(zoo::coredata(average_directional_movement_index_rating( + GOOGL + ))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(average_directional_movement_index_rating(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_APO.R b/tests/testthat/test-ta_APO.R index 31673ef61..1c95c14b0 100644 --- a/tests/testthat/test-ta_APO.R +++ b/tests/testthat/test-ta_APO.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(absolute_price_oscillator(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(absolute_price_oscillator(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(absolute_price_oscillator(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_AROON.R b/tests/testthat/test-ta_AROON.R index ef266d873..cfb74d299 100644 --- a/tests/testthat/test-ta_AROON.R +++ b/tests/testthat/test-ta_AROON.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,31 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(aroon(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(aroon(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(aroon(GOOGL[, sort(colnames(GOOGL))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_AROONOSC.R b/tests/testthat/test-ta_AROONOSC.R index 25638d23d..80bfe7370 100644 --- a/tests/testthat/test-ta_AROONOSC.R +++ b/tests/testthat/test-ta_AROONOSC.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(aroon_oscillator(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(aroon_oscillator(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(aroon_oscillator(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_ATR.R b/tests/testthat/test-ta_ATR.R index 8436d8b0b..b3679a27b 100644 --- a/tests/testthat/test-ta_ATR.R +++ b/tests/testthat/test-ta_ATR.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(average_true_range(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(average_true_range(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(average_true_range(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_AVGDEV.R b/tests/testthat/test-ta_AVGDEV.R index 645d89413..a7a7b33bd 100644 --- a/tests/testthat/test-ta_AVGDEV.R +++ b/tests/testthat/test-ta_AVGDEV.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(average_deviation(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(average_deviation(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(average_deviation(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_AVGPRICE.R b/tests/testthat/test-ta_AVGPRICE.R index 69b58c96f..6649346b2 100644 --- a/tests/testthat/test-ta_AVGPRICE.R +++ b/tests/testthat/test-ta_AVGPRICE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(average_price(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(average_price(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(average_price(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_BBANDS.R b/tests/testthat/test-ta_BBANDS.R index d0f0a61ca..04a8c99b7 100644 --- a/tests/testthat/test-ta_BBANDS.R +++ b/tests/testthat/test-ta_BBANDS.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(bollinger_bands(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(bollinger_bands(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(bollinger_bands(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_BOP.R b/tests/testthat/test-ta_BOP.R index cab304dc9..ea1245015 100644 --- a/tests/testthat/test-ta_BOP.R +++ b/tests/testthat/test-ta_BOP.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(balance_of_power(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(balance_of_power(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(balance_of_power(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CCI.R b/tests/testthat/test-ta_CCI.R index 06d040c17..2bd29db97 100644 --- a/tests/testthat/test-ta_CCI.R +++ b/tests/testthat/test-ta_CCI.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(commodity_channel_index(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(commodity_channel_index(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(commodity_channel_index(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDL2CROWS.R b/tests/testthat/test-ta_CDL2CROWS.R index ac63e3303..10ef53790 100644 --- a/tests/testthat/test-ta_CDL2CROWS.R +++ b/tests/testthat/test-ta_CDL2CROWS.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(two_crows(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(two_crows(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(two_crows(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDL3BLACKCROWS.R b/tests/testthat/test-ta_CDL3BLACKCROWS.R index c20127cf9..35cdd01a9 100644 --- a/tests/testthat/test-ta_CDL3BLACKCROWS.R +++ b/tests/testthat/test-ta_CDL3BLACKCROWS.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(three_black_crows(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(three_black_crows(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(three_black_crows(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDL3INSIDE.R b/tests/testthat/test-ta_CDL3INSIDE.R index f3f0e20ad..ebd9c32ab 100644 --- a/tests/testthat/test-ta_CDL3INSIDE.R +++ b/tests/testthat/test-ta_CDL3INSIDE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(three_inside(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(three_inside(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(three_inside(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDL3LINESTRIKE.R b/tests/testthat/test-ta_CDL3LINESTRIKE.R index b11804eed..8334a6e4c 100644 --- a/tests/testthat/test-ta_CDL3LINESTRIKE.R +++ b/tests/testthat/test-ta_CDL3LINESTRIKE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(three_line_strike(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(three_line_strike(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(three_line_strike(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDL3OUTSIDE.R b/tests/testthat/test-ta_CDL3OUTSIDE.R index 0b1f8c1d2..5aff111ce 100644 --- a/tests/testthat/test-ta_CDL3OUTSIDE.R +++ b/tests/testthat/test-ta_CDL3OUTSIDE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(three_outside(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(three_outside(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(three_outside(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDL3STARSINSOUTH.R b/tests/testthat/test-ta_CDL3STARSINSOUTH.R index 01f367995..e7648ccf3 100644 --- a/tests/testthat/test-ta_CDL3STARSINSOUTH.R +++ b/tests/testthat/test-ta_CDL3STARSINSOUTH.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(three_stars_in_the_south(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(three_stars_in_the_south(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(three_stars_in_the_south(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDL3WHITESOLDIERS.R b/tests/testthat/test-ta_CDL3WHITESOLDIERS.R index b5ef8c5b2..e031dfe1d 100644 --- a/tests/testthat/test-ta_CDL3WHITESOLDIERS.R +++ b/tests/testthat/test-ta_CDL3WHITESOLDIERS.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(three_white_soldiers(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(three_white_soldiers(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(three_white_soldiers(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLABANDONEDBABY.R b/tests/testthat/test-ta_CDLABANDONEDBABY.R index c85a96ce7..56b9414fe 100644 --- a/tests/testthat/test-ta_CDLABANDONEDBABY.R +++ b/tests/testthat/test-ta_CDLABANDONEDBABY.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(abandoned_baby(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(abandoned_baby(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(abandoned_baby(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLADVANCEBLOCK.R b/tests/testthat/test-ta_CDLADVANCEBLOCK.R index cdf3feaf3..e1a5e6dde 100644 --- a/tests/testthat/test-ta_CDLADVANCEBLOCK.R +++ b/tests/testthat/test-ta_CDLADVANCEBLOCK.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(advance_block(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(advance_block(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(advance_block(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLBELTHOLD.R b/tests/testthat/test-ta_CDLBELTHOLD.R index 77f95a5bc..b08bf62a1 100644 --- a/tests/testthat/test-ta_CDLBELTHOLD.R +++ b/tests/testthat/test-ta_CDLBELTHOLD.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(belt_hold(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(belt_hold(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(belt_hold(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLBREAKAWAY.R b/tests/testthat/test-ta_CDLBREAKAWAY.R index 7c8611d21..2f1b20f2f 100644 --- a/tests/testthat/test-ta_CDLBREAKAWAY.R +++ b/tests/testthat/test-ta_CDLBREAKAWAY.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(break_away(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(break_away(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(break_away(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLCLOSINGMARUBOZU.R b/tests/testthat/test-ta_CDLCLOSINGMARUBOZU.R index 73dd60c7b..017cf11d9 100644 --- a/tests/testthat/test-ta_CDLCLOSINGMARUBOZU.R +++ b/tests/testthat/test-ta_CDLCLOSINGMARUBOZU.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(closing_marubozu(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(closing_marubozu(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(closing_marubozu(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLCONCEALBABYSWALL.R b/tests/testthat/test-ta_CDLCONCEALBABYSWALL.R index 4ee002f8f..4d9ecaaaf 100644 --- a/tests/testthat/test-ta_CDLCONCEALBABYSWALL.R +++ b/tests/testthat/test-ta_CDLCONCEALBABYSWALL.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(concealing_baby_swallow(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(concealing_baby_swallow(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(concealing_baby_swallow(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLCOUNTERATTACK.R b/tests/testthat/test-ta_CDLCOUNTERATTACK.R index c334da4b0..ff3994d7d 100644 --- a/tests/testthat/test-ta_CDLCOUNTERATTACK.R +++ b/tests/testthat/test-ta_CDLCOUNTERATTACK.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(counter_attack(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(counter_attack(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(counter_attack(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLDARKCLOUDCOVER.R b/tests/testthat/test-ta_CDLDARKCLOUDCOVER.R index c5ea7142f..6844c542a 100644 --- a/tests/testthat/test-ta_CDLDARKCLOUDCOVER.R +++ b/tests/testthat/test-ta_CDLDARKCLOUDCOVER.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(dark_cloud_cover(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(dark_cloud_cover(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(dark_cloud_cover(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLDOJI.R b/tests/testthat/test-ta_CDLDOJI.R index 57333d26f..3ef3278b7 100644 --- a/tests/testthat/test-ta_CDLDOJI.R +++ b/tests/testthat/test-ta_CDLDOJI.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,31 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(doji(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(doji(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(doji(GOOGL[, sort(colnames(GOOGL))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLDOJISTAR.R b/tests/testthat/test-ta_CDLDOJISTAR.R index 7a40d41e1..f7bb6fb76 100644 --- a/tests/testthat/test-ta_CDLDOJISTAR.R +++ b/tests/testthat/test-ta_CDLDOJISTAR.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(doji_star(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(doji_star(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(doji_star(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLDRAGONFLYDOJI.R b/tests/testthat/test-ta_CDLDRAGONFLYDOJI.R index c4deaf290..23f6631a7 100644 --- a/tests/testthat/test-ta_CDLDRAGONFLYDOJI.R +++ b/tests/testthat/test-ta_CDLDRAGONFLYDOJI.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(dragonfly_doji(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(dragonfly_doji(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(dragonfly_doji(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLENGULFING.R b/tests/testthat/test-ta_CDLENGULFING.R index 9078ee51d..9aa21a322 100644 --- a/tests/testthat/test-ta_CDLENGULFING.R +++ b/tests/testthat/test-ta_CDLENGULFING.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(engulfing(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(engulfing(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(engulfing(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLEVENINGDOJISTAR.R b/tests/testthat/test-ta_CDLEVENINGDOJISTAR.R index f80a09cc4..f8068a280 100644 --- a/tests/testthat/test-ta_CDLEVENINGDOJISTAR.R +++ b/tests/testthat/test-ta_CDLEVENINGDOJISTAR.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(evening_doji_star(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(evening_doji_star(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(evening_doji_star(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLEVENINGSTAR.R b/tests/testthat/test-ta_CDLEVENINGSTAR.R index 0f4c5f0ec..465f7f2b7 100644 --- a/tests/testthat/test-ta_CDLEVENINGSTAR.R +++ b/tests/testthat/test-ta_CDLEVENINGSTAR.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(evening_star(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(evening_star(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(evening_star(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLGAPSIDESIDEWHITE.R b/tests/testthat/test-ta_CDLGAPSIDESIDEWHITE.R index f306e66ef..94e03e848 100644 --- a/tests/testthat/test-ta_CDLGAPSIDESIDEWHITE.R +++ b/tests/testthat/test-ta_CDLGAPSIDESIDEWHITE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(gaps_side_white(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(gaps_side_white(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(gaps_side_white(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLGRAVESTONEDOJI.R b/tests/testthat/test-ta_CDLGRAVESTONEDOJI.R index 7dd52d7ed..a045684f1 100644 --- a/tests/testthat/test-ta_CDLGRAVESTONEDOJI.R +++ b/tests/testthat/test-ta_CDLGRAVESTONEDOJI.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(gravestone_doji(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(gravestone_doji(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(gravestone_doji(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLHAMMER.R b/tests/testthat/test-ta_CDLHAMMER.R index 2eb9e25e8..f446da3b9 100644 --- a/tests/testthat/test-ta_CDLHAMMER.R +++ b/tests/testthat/test-ta_CDLHAMMER.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,31 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(hammer(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(hammer(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(hammer(GOOGL[, sort(colnames(GOOGL))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLHANGINGMAN.R b/tests/testthat/test-ta_CDLHANGINGMAN.R index bfccec440..dc948e0b6 100644 --- a/tests/testthat/test-ta_CDLHANGINGMAN.R +++ b/tests/testthat/test-ta_CDLHANGINGMAN.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(hanging_man(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(hanging_man(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(hanging_man(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLHARAMI.R b/tests/testthat/test-ta_CDLHARAMI.R index 1e71490a8..378402f97 100644 --- a/tests/testthat/test-ta_CDLHARAMI.R +++ b/tests/testthat/test-ta_CDLHARAMI.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,31 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(harami(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(harami(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(harami(GOOGL[, sort(colnames(GOOGL))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLHARAMICROSS.R b/tests/testthat/test-ta_CDLHARAMICROSS.R index 30b6e4a3f..4cb1d3fbe 100644 --- a/tests/testthat/test-ta_CDLHARAMICROSS.R +++ b/tests/testthat/test-ta_CDLHARAMICROSS.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(harami_cross(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(harami_cross(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(harami_cross(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLHIGHWAVE.R b/tests/testthat/test-ta_CDLHIGHWAVE.R index f5c5b9ee3..be80ddfa3 100644 --- a/tests/testthat/test-ta_CDLHIGHWAVE.R +++ b/tests/testthat/test-ta_CDLHIGHWAVE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(high_wave(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(high_wave(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(high_wave(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLHIKKAKE.R b/tests/testthat/test-ta_CDLHIKKAKE.R index ff424a4ba..2b6da6949 100644 --- a/tests/testthat/test-ta_CDLHIKKAKE.R +++ b/tests/testthat/test-ta_CDLHIKKAKE.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,31 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(hikakke(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(hikakke(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(hikakke(GOOGL[, sort(colnames(GOOGL))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLHIKKAKEMOD.R b/tests/testthat/test-ta_CDLHIKKAKEMOD.R index e3f6663dc..0f9c63630 100644 --- a/tests/testthat/test-ta_CDLHIKKAKEMOD.R +++ b/tests/testthat/test-ta_CDLHIKKAKEMOD.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(hikakke_mod(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(hikakke_mod(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(hikakke_mod(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLHOMINGPIGEON.R b/tests/testthat/test-ta_CDLHOMINGPIGEON.R index 2b93bd828..ae9771f17 100644 --- a/tests/testthat/test-ta_CDLHOMINGPIGEON.R +++ b/tests/testthat/test-ta_CDLHOMINGPIGEON.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(homing_pigeon(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(homing_pigeon(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(homing_pigeon(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLIDENTICAL3CROWS.R b/tests/testthat/test-ta_CDLIDENTICAL3CROWS.R index 4b8bc3eef..ce63ddabb 100644 --- a/tests/testthat/test-ta_CDLIDENTICAL3CROWS.R +++ b/tests/testthat/test-ta_CDLIDENTICAL3CROWS.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(three_identical_crows(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(three_identical_crows(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(three_identical_crows(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLINNECK.R b/tests/testthat/test-ta_CDLINNECK.R index ce6085526..949b315d4 100644 --- a/tests/testthat/test-ta_CDLINNECK.R +++ b/tests/testthat/test-ta_CDLINNECK.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,31 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(in_neck(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(in_neck(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(in_neck(GOOGL[, sort(colnames(GOOGL))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLINVERTEDHAMMER.R b/tests/testthat/test-ta_CDLINVERTEDHAMMER.R index 90e8d2176..90e371ae5 100644 --- a/tests/testthat/test-ta_CDLINVERTEDHAMMER.R +++ b/tests/testthat/test-ta_CDLINVERTEDHAMMER.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(inverted_hammer(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(inverted_hammer(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(inverted_hammer(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLKICKING.R b/tests/testthat/test-ta_CDLKICKING.R index d5b551457..c3e91824f 100644 --- a/tests/testthat/test-ta_CDLKICKING.R +++ b/tests/testthat/test-ta_CDLKICKING.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,31 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(kicking(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(kicking(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(kicking(GOOGL[, sort(colnames(GOOGL))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLKICKINGBYLENGTH.R b/tests/testthat/test-ta_CDLKICKINGBYLENGTH.R index 278164e80..f62f245d1 100644 --- a/tests/testthat/test-ta_CDLKICKINGBYLENGTH.R +++ b/tests/testthat/test-ta_CDLKICKINGBYLENGTH.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(kicking_baby_length(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(kicking_baby_length(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(kicking_baby_length(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLLADDERBOTTOM.R b/tests/testthat/test-ta_CDLLADDERBOTTOM.R index c60c6e2b6..89eb4172a 100644 --- a/tests/testthat/test-ta_CDLLADDERBOTTOM.R +++ b/tests/testthat/test-ta_CDLLADDERBOTTOM.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(ladder_bottom(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(ladder_bottom(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(ladder_bottom(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLLONGLEGGEDDOJI.R b/tests/testthat/test-ta_CDLLONGLEGGEDDOJI.R index 4eb159c6a..d0386c24e 100644 --- a/tests/testthat/test-ta_CDLLONGLEGGEDDOJI.R +++ b/tests/testthat/test-ta_CDLLONGLEGGEDDOJI.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(long_legged_doji(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(long_legged_doji(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(long_legged_doji(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLLONGLINE.R b/tests/testthat/test-ta_CDLLONGLINE.R index 26d2ba49e..93ddbd778 100644 --- a/tests/testthat/test-ta_CDLLONGLINE.R +++ b/tests/testthat/test-ta_CDLLONGLINE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(long_line(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(long_line(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(long_line(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLMARUBOZU.R b/tests/testthat/test-ta_CDLMARUBOZU.R index bcc7dd068..b5ec8d0fd 100644 --- a/tests/testthat/test-ta_CDLMARUBOZU.R +++ b/tests/testthat/test-ta_CDLMARUBOZU.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(marubozu(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(marubozu(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(marubozu(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLMATCHINGLOW.R b/tests/testthat/test-ta_CDLMATCHINGLOW.R index af0b78c6a..da7baadfb 100644 --- a/tests/testthat/test-ta_CDLMATCHINGLOW.R +++ b/tests/testthat/test-ta_CDLMATCHINGLOW.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(matching_low(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(matching_low(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(matching_low(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLMATHOLD.R b/tests/testthat/test-ta_CDLMATHOLD.R index 78ec4b36c..98b527833 100644 --- a/tests/testthat/test-ta_CDLMATHOLD.R +++ b/tests/testthat/test-ta_CDLMATHOLD.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(mat_hold(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(mat_hold(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(mat_hold(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLMORNINGDOJISTAR.R b/tests/testthat/test-ta_CDLMORNINGDOJISTAR.R index ea697a3fa..fbd4aac66 100644 --- a/tests/testthat/test-ta_CDLMORNINGDOJISTAR.R +++ b/tests/testthat/test-ta_CDLMORNINGDOJISTAR.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(morning_doji_star(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(morning_doji_star(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(morning_doji_star(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLMORNINGSTAR.R b/tests/testthat/test-ta_CDLMORNINGSTAR.R index d6e0be244..ed659b905 100644 --- a/tests/testthat/test-ta_CDLMORNINGSTAR.R +++ b/tests/testthat/test-ta_CDLMORNINGSTAR.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(morning_star(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(morning_star(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(morning_star(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLONNECK.R b/tests/testthat/test-ta_CDLONNECK.R index dd2819cc4..5e70fc40f 100644 --- a/tests/testthat/test-ta_CDLONNECK.R +++ b/tests/testthat/test-ta_CDLONNECK.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,31 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(on_neck(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(on_neck(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(on_neck(GOOGL[, sort(colnames(GOOGL))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLPIERCING.R b/tests/testthat/test-ta_CDLPIERCING.R index 644a76a0a..118b86898 100644 --- a/tests/testthat/test-ta_CDLPIERCING.R +++ b/tests/testthat/test-ta_CDLPIERCING.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(piercing(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(piercing(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(piercing(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLRICKSHAWMAN.R b/tests/testthat/test-ta_CDLRICKSHAWMAN.R index a322329b8..e58e0885a 100644 --- a/tests/testthat/test-ta_CDLRICKSHAWMAN.R +++ b/tests/testthat/test-ta_CDLRICKSHAWMAN.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(rickshaw_man(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(rickshaw_man(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(rickshaw_man(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLRISEFALL3METHODS.R b/tests/testthat/test-ta_CDLRISEFALL3METHODS.R index e97d1fd61..95a6be488 100644 --- a/tests/testthat/test-ta_CDLRISEFALL3METHODS.R +++ b/tests/testthat/test-ta_CDLRISEFALL3METHODS.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(rise_fall_3_methods(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(rise_fall_3_methods(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(rise_fall_3_methods(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLSEPARATINGLINES.R b/tests/testthat/test-ta_CDLSEPARATINGLINES.R index e19d3e2fe..d9c0c20ae 100644 --- a/tests/testthat/test-ta_CDLSEPARATINGLINES.R +++ b/tests/testthat/test-ta_CDLSEPARATINGLINES.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(separating_lines(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(separating_lines(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(separating_lines(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLSHOOTINGSTAR.R b/tests/testthat/test-ta_CDLSHOOTINGSTAR.R index 37e6ed4a2..8ceebe291 100644 --- a/tests/testthat/test-ta_CDLSHOOTINGSTAR.R +++ b/tests/testthat/test-ta_CDLSHOOTINGSTAR.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(shooting_star(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(shooting_star(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(shooting_star(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLSHORTLINE.R b/tests/testthat/test-ta_CDLSHORTLINE.R index 479817782..cef700ae3 100644 --- a/tests/testthat/test-ta_CDLSHORTLINE.R +++ b/tests/testthat/test-ta_CDLSHORTLINE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(short_line(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(short_line(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(short_line(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLSPINNINGTOP.R b/tests/testthat/test-ta_CDLSPINNINGTOP.R index 74b33933e..a71b5ca11 100644 --- a/tests/testthat/test-ta_CDLSPINNINGTOP.R +++ b/tests/testthat/test-ta_CDLSPINNINGTOP.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(spinning_top(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(spinning_top(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(spinning_top(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLSTALLEDPATTERN.R b/tests/testthat/test-ta_CDLSTALLEDPATTERN.R index a3040514c..317b0770c 100644 --- a/tests/testthat/test-ta_CDLSTALLEDPATTERN.R +++ b/tests/testthat/test-ta_CDLSTALLEDPATTERN.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(stalled_pattern(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(stalled_pattern(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(stalled_pattern(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLSTICKSANDWICH.R b/tests/testthat/test-ta_CDLSTICKSANDWICH.R index 286301a41..6e7e2a9b1 100644 --- a/tests/testthat/test-ta_CDLSTICKSANDWICH.R +++ b/tests/testthat/test-ta_CDLSTICKSANDWICH.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(stick_sandwich(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(stick_sandwich(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(stick_sandwich(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLTAKURI.R b/tests/testthat/test-ta_CDLTAKURI.R index 41a2a81d0..1a1531ec4 100644 --- a/tests/testthat/test-ta_CDLTAKURI.R +++ b/tests/testthat/test-ta_CDLTAKURI.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,31 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(takuri(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(takuri(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(takuri(GOOGL[, sort(colnames(GOOGL))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLTASUKIGAP.R b/tests/testthat/test-ta_CDLTASUKIGAP.R index 6b90cbba8..5538e6107 100644 --- a/tests/testthat/test-ta_CDLTASUKIGAP.R +++ b/tests/testthat/test-ta_CDLTASUKIGAP.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(tasuki_gap(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(tasuki_gap(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(tasuki_gap(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLTHRUSTING.R b/tests/testthat/test-ta_CDLTHRUSTING.R index d5ad6e552..c95344adb 100644 --- a/tests/testthat/test-ta_CDLTHRUSTING.R +++ b/tests/testthat/test-ta_CDLTHRUSTING.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(thrusting(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(thrusting(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(thrusting(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLTRISTAR.R b/tests/testthat/test-ta_CDLTRISTAR.R index b09a137fb..46fc6b6b9 100644 --- a/tests/testthat/test-ta_CDLTRISTAR.R +++ b/tests/testthat/test-ta_CDLTRISTAR.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,31 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(tristar(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(tristar(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(tristar(GOOGL[, sort(colnames(GOOGL))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLUNIQUE3RIVER.R b/tests/testthat/test-ta_CDLUNIQUE3RIVER.R index 7993346d1..bcc60d889 100644 --- a/tests/testthat/test-ta_CDLUNIQUE3RIVER.R +++ b/tests/testthat/test-ta_CDLUNIQUE3RIVER.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(unique_3_river(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(unique_3_river(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(unique_3_river(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLUPSIDEGAP2CROWS.R b/tests/testthat/test-ta_CDLUPSIDEGAP2CROWS.R index 1514fb111..ee4c932d3 100644 --- a/tests/testthat/test-ta_CDLUPSIDEGAP2CROWS.R +++ b/tests/testthat/test-ta_CDLUPSIDEGAP2CROWS.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(upside_gap_2_crows(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(upside_gap_2_crows(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(upside_gap_2_crows(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CDLXSIDEGAP3METHODS.R b/tests/testthat/test-ta_CDLXSIDEGAP3METHODS.R index 57e112893..12444b18b 100644 --- a/tests/testthat/test-ta_CDLXSIDEGAP3METHODS.R +++ b/tests/testthat/test-ta_CDLXSIDEGAP3METHODS.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(xside_gap_3_methods(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(xside_gap_3_methods(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(xside_gap_3_methods(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CMF.R b/tests/testthat/test-ta_CMF.R index e78ab73bf..74c2aafe1 100644 --- a/tests/testthat/test-ta_CMF.R +++ b/tests/testthat/test-ta_CMF.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(chaikin_money_flow(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(chaikin_money_flow(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(chaikin_money_flow(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CMO.R b/tests/testthat/test-ta_CMO.R index ff7730fdd..b8656718f 100644 --- a/tests/testthat/test-ta_CMO.R +++ b/tests/testthat/test-ta_CMO.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(chande_momentum_oscillator(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(chande_momentum_oscillator(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(chande_momentum_oscillator(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_CMOU.R b/tests/testthat/test-ta_CMOU.R index 3ca44cdae..d2722bc67 100644 --- a/tests/testthat/test-ta_CMOU.R +++ b/tests/testthat/test-ta_CMOU.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,37 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(unsmoothed_chande_momentum_oscillator( + reference + ))) + + testthat::expect_equal( + object = unname(zoo::coredata(unsmoothed_chande_momentum_oscillator( + GOOGL + ))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(unsmoothed_chande_momentum_oscillator(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_DEMA.R b/tests/testthat/test-ta_DEMA.R index c56a1a313..743d6614a 100644 --- a/tests/testthat/test-ta_DEMA.R +++ b/tests/testthat/test-ta_DEMA.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,35 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(double_exponential_moving_average(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(double_exponential_moving_average( + GOOGL + ))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(double_exponential_moving_average(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_DX.R b/tests/testthat/test-ta_DX.R index 15c4e9061..70e599847 100644 --- a/tests/testthat/test-ta_DX.R +++ b/tests/testthat/test-ta_DX.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(directional_movement_index(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(directional_movement_index(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(directional_movement_index(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_EMA.R b/tests/testthat/test-ta_EMA.R index a8efaf744..32f97db53 100644 --- a/tests/testthat/test-ta_EMA.R +++ b/tests/testthat/test-ta_EMA.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(exponential_moving_average(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(exponential_moving_average(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(exponential_moving_average(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_HMA.R b/tests/testthat/test-ta_HMA.R index 787aa8d62..d54e10586 100644 --- a/tests/testthat/test-ta_HMA.R +++ b/tests/testthat/test-ta_HMA.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(hull_moving_average(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(hull_moving_average(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(hull_moving_average(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_HT_DCPERIOD.R b/tests/testthat/test-ta_HT_DCPERIOD.R index 87b1b7563..f4f1f98c6 100644 --- a/tests/testthat/test-ta_HT_DCPERIOD.R +++ b/tests/testthat/test-ta_HT_DCPERIOD.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(dominant_cycle_period(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(dominant_cycle_period(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(dominant_cycle_period(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_HT_DCPHASE.R b/tests/testthat/test-ta_HT_DCPHASE.R index 060443c1d..fabb65f53 100644 --- a/tests/testthat/test-ta_HT_DCPHASE.R +++ b/tests/testthat/test-ta_HT_DCPHASE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(dominant_cycle_phase(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(dominant_cycle_phase(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(dominant_cycle_phase(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_HT_PHASOR.R b/tests/testthat/test-ta_HT_PHASOR.R index e82b7fe08..fb24c915b 100644 --- a/tests/testthat/test-ta_HT_PHASOR.R +++ b/tests/testthat/test-ta_HT_PHASOR.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(phasor_components(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(phasor_components(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(phasor_components(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_HT_SINE.R b/tests/testthat/test-ta_HT_SINE.R index eead27cff..084576511 100644 --- a/tests/testthat/test-ta_HT_SINE.R +++ b/tests/testthat/test-ta_HT_SINE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(sine_wave(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(sine_wave(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(sine_wave(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_HT_TRENDLINE.R b/tests/testthat/test-ta_HT_TRENDLINE.R index a20f68dec..0c7fccfb4 100644 --- a/tests/testthat/test-ta_HT_TRENDLINE.R +++ b/tests/testthat/test-ta_HT_TRENDLINE.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(trendline(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(trendline(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(trendline(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_HT_TRENDMODE.R b/tests/testthat/test-ta_HT_TRENDMODE.R index 7e6857c86..449c2b64d 100644 --- a/tests/testthat/test-ta_HT_TRENDMODE.R +++ b/tests/testthat/test-ta_HT_TRENDMODE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(trend_cycle_mode(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(trend_cycle_mode(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(trend_cycle_mode(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_IMI.R b/tests/testthat/test-ta_IMI.R index ed3736758..36b3d34b2 100644 --- a/tests/testthat/test-ta_IMI.R +++ b/tests/testthat/test-ta_IMI.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(intraday_movement_index(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(intraday_movement_index(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(intraday_movement_index(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_KAMA.R b/tests/testthat/test-ta_KAMA.R index bbf471fc0..b23ac00fd 100644 --- a/tests/testthat/test-ta_KAMA.R +++ b/tests/testthat/test-ta_KAMA.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(kaufman_adaptive_moving_average(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(kaufman_adaptive_moving_average(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(kaufman_adaptive_moving_average(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_MACD.R b/tests/testthat/test-ta_MACD.R index 147870651..45258844c 100644 --- a/tests/testthat/test-ta_MACD.R +++ b/tests/testthat/test-ta_MACD.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,37 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(moving_average_convergence_divergence( + reference + ))) + + testthat::expect_equal( + object = unname(zoo::coredata(moving_average_convergence_divergence( + GOOGL + ))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(moving_average_convergence_divergence(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_MACDEXT.R b/tests/testthat/test-ta_MACDEXT.R index 65e513470..66462d163 100644 --- a/tests/testthat/test-ta_MACDEXT.R +++ b/tests/testthat/test-ta_MACDEXT.R @@ -59,8 +59,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -71,6 +73,37 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(extended_moving_average_convergence_divergence( + reference + ))) + + testthat::expect_equal( + object = unname(zoo::coredata(extended_moving_average_convergence_divergence( + GOOGL + ))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(extended_moving_average_convergence_divergence(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_MACDFIX.R b/tests/testthat/test-ta_MACDFIX.R index 1c429ed13..4adfa559f 100644 --- a/tests/testthat/test-ta_MACDFIX.R +++ b/tests/testthat/test-ta_MACDFIX.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -65,6 +67,37 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(fixed_moving_average_convergence_divergence( + reference + ))) + + testthat::expect_equal( + object = unname(zoo::coredata(fixed_moving_average_convergence_divergence( + GOOGL + ))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(fixed_moving_average_convergence_divergence(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_MAMA.R b/tests/testthat/test-ta_MAMA.R index 1ba23fe2a..6d3539a1a 100644 --- a/tests/testthat/test-ta_MAMA.R +++ b/tests/testthat/test-ta_MAMA.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(mesa_adaptive_moving_average(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(mesa_adaptive_moving_average(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(mesa_adaptive_moving_average(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_MAVP.R b/tests/testthat/test-ta_MAVP.R index 395adbe4f..4bba3dbc6 100644 --- a/tests/testthat/test-ta_MAVP.R +++ b/tests/testthat/test-ta_MAVP.R @@ -59,8 +59,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -74,6 +76,40 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(variable_moving_average_period( + reference, + periods = rep(5, nrow(GOOGL)) + ))) + + testthat::expect_equal( + object = unname(zoo::coredata(variable_moving_average_period( + GOOGL, + periods = rep(5, nrow(GOOGL)) + ))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(variable_moving_average_period( + GOOGL[, sort(colnames(GOOGL))], + periods = rep(5, nrow(GOOGL)) + ))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_MEDPRICE.R b/tests/testthat/test-ta_MEDPRICE.R index dfc32133c..2ac9b1158 100644 --- a/tests/testthat/test-ta_MEDPRICE.R +++ b/tests/testthat/test-ta_MEDPRICE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(median_price(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(median_price(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(median_price(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_MFI.R b/tests/testthat/test-ta_MFI.R index 2ac14a929..ea0c8ad43 100644 --- a/tests/testthat/test-ta_MFI.R +++ b/tests/testthat/test-ta_MFI.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(money_flow_index(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(money_flow_index(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(money_flow_index(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_MIDPOINT.R b/tests/testthat/test-ta_MIDPOINT.R index ad7ff77da..339b60a5c 100644 --- a/tests/testthat/test-ta_MIDPOINT.R +++ b/tests/testthat/test-ta_MIDPOINT.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(midpoint_period(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(midpoint_period(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(midpoint_period(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_MIDPRICE.R b/tests/testthat/test-ta_MIDPRICE.R index fa9132026..32f5e9672 100644 --- a/tests/testthat/test-ta_MIDPRICE.R +++ b/tests/testthat/test-ta_MIDPRICE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(midpoint_price(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(midpoint_price(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(midpoint_price(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_MINUS_DI.R b/tests/testthat/test-ta_MINUS_DI.R index 5bf06469b..f79e3ec44 100644 --- a/tests/testthat/test-ta_MINUS_DI.R +++ b/tests/testthat/test-ta_MINUS_DI.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(minus_directional_indicator(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(minus_directional_indicator(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(minus_directional_indicator(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_MINUS_DM.R b/tests/testthat/test-ta_MINUS_DM.R index 4eb52f96a..e2e9ed41c 100644 --- a/tests/testthat/test-ta_MINUS_DM.R +++ b/tests/testthat/test-ta_MINUS_DM.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(minus_directional_movement(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(minus_directional_movement(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(minus_directional_movement(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_MOM.R b/tests/testthat/test-ta_MOM.R index e63949294..c59d673be 100644 --- a/tests/testthat/test-ta_MOM.R +++ b/tests/testthat/test-ta_MOM.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(momentum(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(momentum(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(momentum(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_NATR.R b/tests/testthat/test-ta_NATR.R index 378f775aa..8aa50cf7e 100644 --- a/tests/testthat/test-ta_NATR.R +++ b/tests/testthat/test-ta_NATR.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(normalized_average_true_range(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(normalized_average_true_range(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(normalized_average_true_range(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_NVI.R b/tests/testthat/test-ta_NVI.R index 81bea7a26..c40ef30ae 100644 --- a/tests/testthat/test-ta_NVI.R +++ b/tests/testthat/test-ta_NVI.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(negative_volume_index(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(negative_volume_index(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(negative_volume_index(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_OBV.R b/tests/testthat/test-ta_OBV.R index 91f3869e6..cafc8d280 100644 --- a/tests/testthat/test-ta_OBV.R +++ b/tests/testthat/test-ta_OBV.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(on_balance_volume(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(on_balance_volume(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(on_balance_volume(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_PLUS_DI.R b/tests/testthat/test-ta_PLUS_DI.R index 19b085ae9..b5e6e25f9 100644 --- a/tests/testthat/test-ta_PLUS_DI.R +++ b/tests/testthat/test-ta_PLUS_DI.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(plus_directional_indicator(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(plus_directional_indicator(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(plus_directional_indicator(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_PLUS_DM.R b/tests/testthat/test-ta_PLUS_DM.R index 5a462177d..3f8fe322f 100644 --- a/tests/testthat/test-ta_PLUS_DM.R +++ b/tests/testthat/test-ta_PLUS_DM.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(plus_directional_movement(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(plus_directional_movement(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(plus_directional_movement(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_PPO.R b/tests/testthat/test-ta_PPO.R index ac71ce66a..50934477d 100644 --- a/tests/testthat/test-ta_PPO.R +++ b/tests/testthat/test-ta_PPO.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(percentage_price_oscillator(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(percentage_price_oscillator(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(percentage_price_oscillator(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_PVI.R b/tests/testthat/test-ta_PVI.R index dbeb17061..6cd99ace8 100644 --- a/tests/testthat/test-ta_PVI.R +++ b/tests/testthat/test-ta_PVI.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(positive_volume_index(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(positive_volume_index(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(positive_volume_index(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_PVO.R b/tests/testthat/test-ta_PVO.R index d3256e1bf..15bde42a7 100644 --- a/tests/testthat/test-ta_PVO.R +++ b/tests/testthat/test-ta_PVO.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(percentage_volume_oscillator(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(percentage_volume_oscillator(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(percentage_volume_oscillator(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_ROCR.R b/tests/testthat/test-ta_ROCR.R index 89894efd5..9d1c0c0fb 100644 --- a/tests/testthat/test-ta_ROCR.R +++ b/tests/testthat/test-ta_ROCR.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(ratio_of_change(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(ratio_of_change(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(ratio_of_change(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_RSI.R b/tests/testthat/test-ta_RSI.R index 1f5100835..bf405a7f9 100644 --- a/tests/testthat/test-ta_RSI.R +++ b/tests/testthat/test-ta_RSI.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(relative_strength_index(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(relative_strength_index(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(relative_strength_index(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_SAR.R b/tests/testthat/test-ta_SAR.R index 521416a58..0dcf06891 100644 --- a/tests/testthat/test-ta_SAR.R +++ b/tests/testthat/test-ta_SAR.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(parabolic_stop_and_reverse(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(parabolic_stop_and_reverse(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(parabolic_stop_and_reverse(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_SAREXT.R b/tests/testthat/test-ta_SAREXT.R index 14d17f644..36ebb88ef 100644 --- a/tests/testthat/test-ta_SAREXT.R +++ b/tests/testthat/test-ta_SAREXT.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,37 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(extended_parabolic_stop_and_reverse( + reference + ))) + + testthat::expect_equal( + object = unname(zoo::coredata(extended_parabolic_stop_and_reverse( + GOOGL + ))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(extended_parabolic_stop_and_reverse(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_SMA.R b/tests/testthat/test-ta_SMA.R index 4a576ec0e..047fe8d94 100644 --- a/tests/testthat/test-ta_SMA.R +++ b/tests/testthat/test-ta_SMA.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(simple_moving_average(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(simple_moving_average(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(simple_moving_average(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_STOCH.R b/tests/testthat/test-ta_STOCH.R index 27258422e..432531ee7 100644 --- a/tests/testthat/test-ta_STOCH.R +++ b/tests/testthat/test-ta_STOCH.R @@ -42,8 +42,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -51,6 +53,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(stochastic(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(stochastic(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(stochastic(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_STOCHF.R b/tests/testthat/test-ta_STOCHF.R index 7663422da..188e0f733 100644 --- a/tests/testthat/test-ta_STOCHF.R +++ b/tests/testthat/test-ta_STOCHF.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(fast_stochastic(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(fast_stochastic(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(fast_stochastic(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_STOCHRSI.R b/tests/testthat/test-ta_STOCHRSI.R index de778c8fa..94fb9b6c8 100644 --- a/tests/testthat/test-ta_STOCHRSI.R +++ b/tests/testthat/test-ta_STOCHRSI.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,37 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(stochastic_relative_strength_index( + reference + ))) + + testthat::expect_equal( + object = unname(zoo::coredata(stochastic_relative_strength_index( + GOOGL + ))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(stochastic_relative_strength_index(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_T3.R b/tests/testthat/test-ta_T3.R index d61aa5432..0fe8d4bbf 100644 --- a/tests/testthat/test-ta_T3.R +++ b/tests/testthat/test-ta_T3.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(t3_exponential_moving_average(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(t3_exponential_moving_average(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(t3_exponential_moving_average(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_TEMA.R b/tests/testthat/test-ta_TEMA.R index 2d7750a40..708ee252f 100644 --- a/tests/testthat/test-ta_TEMA.R +++ b/tests/testthat/test-ta_TEMA.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,35 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(triple_exponential_moving_average(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(triple_exponential_moving_average( + GOOGL + ))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(triple_exponential_moving_average(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_TRANGE.R b/tests/testthat/test-ta_TRANGE.R index 370abca74..2f668fabb 100644 --- a/tests/testthat/test-ta_TRANGE.R +++ b/tests/testthat/test-ta_TRANGE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(true_range(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(true_range(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(true_range(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_TRIMA.R b/tests/testthat/test-ta_TRIMA.R index 556d53374..8a10950ee 100644 --- a/tests/testthat/test-ta_TRIMA.R +++ b/tests/testthat/test-ta_TRIMA.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(triangular_moving_average(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(triangular_moving_average(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(triangular_moving_average(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_TRIX.R b/tests/testthat/test-ta_TRIX.R index cf9f5ad44..de2b682b4 100644 --- a/tests/testthat/test-ta_TRIX.R +++ b/tests/testthat/test-ta_TRIX.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(triple_exponential_average(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(triple_exponential_average(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(triple_exponential_average(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_TYPPRICE.R b/tests/testthat/test-ta_TYPPRICE.R index 3c7991d25..38bcfa5d9 100644 --- a/tests/testthat/test-ta_TYPPRICE.R +++ b/tests/testthat/test-ta_TYPPRICE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(typical_price(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(typical_price(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(typical_price(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_ULTOSC.R b/tests/testthat/test-ta_ULTOSC.R index 209d23bd5..878517742 100644 --- a/tests/testthat/test-ta_ULTOSC.R +++ b/tests/testthat/test-ta_ULTOSC.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(ultimate_oscillator(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(ultimate_oscillator(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(ultimate_oscillator(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_VWMA.R b/tests/testthat/test-ta_VWMA.R index 1b10cbd72..346b6218a 100644 --- a/tests/testthat/test-ta_VWMA.R +++ b/tests/testthat/test-ta_VWMA.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(volume_weighted_moving_average(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(volume_weighted_moving_average(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(volume_weighted_moving_average(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_WCLPRICE.R b/tests/testthat/test-ta_WCLPRICE.R index f55b489d8..a79a88719 100644 --- a/tests/testthat/test-ta_WCLPRICE.R +++ b/tests/testthat/test-ta_WCLPRICE.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(weighted_close_price(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(weighted_close_price(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(weighted_close_price(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_WILLR.R b/tests/testthat/test-ta_WILLR.R index c8d599381..ef51b5460 100644 --- a/tests/testthat/test-ta_WILLR.R +++ b/tests/testthat/test-ta_WILLR.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(williams_oscillator(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(williams_oscillator(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(williams_oscillator(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. diff --git a/tests/testthat/test-ta_WMA.R b/tests/testthat/test-ta_WMA.R index 4a09165ea..0be56fb32 100644 --- a/tests/testthat/test-ta_WMA.R +++ b/tests/testthat/test-ta_WMA.R @@ -53,8 +53,10 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) -## object +## object testthat::test_that(desc = 'Class in, class out ()', code = { + testthat::skip_if_not_installed("xts") + ## 1) check that the output class ## matches the input class testthat::expect_true( @@ -62,6 +64,33 @@ testthat::test_that(desc = 'Class in, class out ()', code = { ) }) +## the path must select the same columns in the +## same order as the reference, regardless +## of the physical column layout +testthat::test_that(desc = 'Value parity with ()', code = { + testthat::skip_if_not_installed("xts") + + ## lowercase reference + ## from the GOOGL fixture + reference <- as.data.frame(GOOGL) + colnames(reference) <- tolower(sub("^GOOGL\\.", "", colnames(reference))) + reference <- unname(as.matrix(weighted_moving_average(reference))) + + testthat::expect_equal( + object = unname(zoo::coredata(weighted_moving_average(GOOGL))), + expected = reference + ) + + ## alphabetically sorted columns place 'Adjusted' + ## first and must resolve identically + testthat::expect_equal( + object = unname(zoo::coredata(weighted_moving_average(GOOGL[, sort(colnames( + GOOGL + ))]))), + expected = reference + ) +}) + ## check that the default calls ## matches that of the constructed call ## with default values. From 570c5e36f79ba431b74410555b654e8156b876e6 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 20:24:27 +0200 Subject: [PATCH 17/22] :sparkles: Coercible inputs, honest docs and .Call hygiene * series() gained a default method that defers any classed input to as.data.frame() before column resolution - a multivariate zoo (or any data.frame-coercible object) now computes on the coerced frame with the index as rownames, instead of dying with the internal "no applicable method for 'series'" error. Uncoercible inputs fail with base R's own coercion message naming the class. * The indicator documentation now states the actual per-class contract: xts in, xts out alongside data.frame/matrix; coercible inputs computed on the coerced data.frame; the xts column resolution (exact matches first, then quantmod-style suffix matches, consumed in formula order) documented under 'cols'; and '...' marked unused for xts input. * index_data_frame(), index_matrix() and index_xts() in src/names.c now return SEXP (R_NilValue) as Writing R Extensions requires for .Call routines - previously void, an undefined-behavior read of the return register. A registration sweep confirms no other void .Call routines remain. --- NAMESPACE | 1 + R/series.R | 17 +++++++++++++++++ man-roxygen/description.R | 10 ++++++++-- src/names.c | 16 ++++++++-------- src/names.h | 6 +++--- tests/testthat/test-series.R | 25 +++++++++++++++++++++++++ 6 files changed, 62 insertions(+), 13 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 1aa5d6416..7f7450705 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -599,6 +599,7 @@ S3method(separating_lines,matrix) S3method(separating_lines,plotly) S3method(separating_lines,xts) S3method(series,data.frame) +S3method(series,default) S3method(series,ggplot) S3method(series,matrix) S3method(series,plotly) diff --git a/R/series.R b/R/series.R index 35e5d2587..2621fc6a7 100644 --- a/R/series.R +++ b/R/series.R @@ -35,6 +35,23 @@ series <- function( UseMethod("series", x) } +#' @export +series.default <- function( + x, + formula, + formula.default, + ... +) { + ## classed inputs (zoo, tibble-likes, ...) defer to + ## as.data.frame() for proper method dispatch + series( + x = as.data.frame(x), + formula = formula, + formula.default = formula.default, + ... + ) +} + #' Chart-pipeline entry for ggplot backends. Resolves `formula` against #' `formula.default` and delegates to [.series_chart_dispatch()]. #' diff --git a/man-roxygen/description.R b/man-roxygen/description.R index 06f0babbc..93830e6b0 100644 --- a/man-roxygen/description.R +++ b/man-roxygen/description.R @@ -1,7 +1,8 @@ #' @description #' `<%= tolower(.fun) %>()` is a generic S3 function that preserves #' the input [class]: [data.frame] in, [data.frame] out; [matrix] in, -#' [matrix] out. +#' [matrix] out; `xts` in, `xts` out. Other inputs coercible to +#' [data.frame] (e.g. `zoo`) are computed on the coerced [data.frame]. #' #' <% if (any(grepl(pattern = "cols", x = names(formals(.fun))))) { %> @@ -57,6 +58,10 @@ <% } %> #' #' @param cols ([formula]). An optional `<%= length(all.vars(as.formula(.formula))) %>`-variable [formula] selecting columns from `x` via [model.frame]. +#' For `xts` input each formula variable is matched against the column +#' names directly - exact matches first, then quantmod-style suffix +#' matches (`close` matches `TICKER.Close`), case-insensitively - and +#' columns are consumed in formula order. #' Defaults to `<%= deparse(as.formula(.formula)) %>`. #' <% } %> @@ -82,7 +87,8 @@ #' `NA` values** section above for the consequences. <% } %> <% if ("..." %in% fun_args) { %> -#' @param ... Additional parameters passed into [model.frame]. +#' @param ... Additional parameters passed into [model.frame]. Unused +#' for `xts` input (a warning is emitted when supplied). <% } %> #' #' @author <%= .author %> diff --git a/src/names.c b/src/names.c index abb71fec4..c32c21379 100644 --- a/src/names.c +++ b/src/names.c @@ -62,7 +62,7 @@ void set_colnames( // it will crash. // clang-format off -void index_data_frame( +SEXP index_data_frame( SEXP x, SEXP rownames ) @@ -70,13 +70,13 @@ void index_data_frame( { Rf_setAttrib(x, R_RowNamesSymbol, rownames); - return; + return R_NilValue; } // clang-format off -void index_matrix( - SEXP x, - SEXP rownames, +SEXP index_matrix( + SEXP x, + SEXP rownames, SEXP colnames ) // clang-format on @@ -94,7 +94,7 @@ void index_matrix( UNPROTECT(1); - return; + return R_NilValue; } // Index of the -object @@ -103,7 +103,7 @@ void index_matrix( // index of the input -object, i.e. zoo::index(x), // and is attached as-is. // clang-format off -void index_xts( +SEXP index_xts( SEXP x, SEXP index ) @@ -111,5 +111,5 @@ void index_xts( { Rf_setAttrib(x, Rf_install("index"), index); - return; + return R_NilValue; } \ No newline at end of file diff --git a/src/names.h b/src/names.h index da95b8440..cb8d0432e 100644 --- a/src/names.h +++ b/src/names.h @@ -4,8 +4,8 @@ #include void set_colnames(SEXP x, const char *const *names, int k); -void index_data_frame(SEXP x, SEXP rownames); -void index_matrix(SEXP x, SEXP rownames, SEXP colnames); -void index_xts(SEXP x, SEXP index); +SEXP index_data_frame(SEXP x, SEXP rownames); +SEXP index_matrix(SEXP x, SEXP rownames, SEXP colnames); +SEXP index_xts(SEXP x, SEXP index); #endif /* NAMES_H */ diff --git a/tests/testthat/test-series.R b/tests/testthat/test-series.R index 2bd14b0da..bb115ce94 100644 --- a/tests/testthat/test-series.R +++ b/tests/testthat/test-series.R @@ -217,3 +217,28 @@ testthat::test_that(desc = " input works without {xts} attached", code = { testthat::expect_true(any(grepl("vanilla-ok", output))) }) + +## coercible inputs (zoo, ...) defer to +## as.data.frame() via series.default +testthat::test_that(desc = "coercible inputs defer to as.data.frame()", code = { + testthat::skip_if_not_installed("zoo") + + idx <- as.Date("2024-01-01") + 0:9 + z <- zoo::zoo( + cbind(high = 2:11, low = 0:9, close = 1:10), + order.by = idx + ) + + output <- talib:::series(x = z, formula.default = ~ high + low + close) + + testthat::expect_s3_class(output, "data.frame") + testthat::expect_equal(colnames(output), c("high", "low", "close")) + testthat::expect_equal(rownames(output), as.character(idx)) + + ## the indicator path computes on the coerced + ## and matches its reference values + testthat::expect_equal( + as.data.frame(relative_strength_index(z)), + relative_strength_index(as.data.frame(z)) + ) +}) From 14527f5ee35715e740ada3145192336088a9cbed Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 20:35:26 +0200 Subject: [PATCH 18/22] :bug: Kept the R (>= 3.5) floor * The chart dispatch no longer calls ...names() (R >= 4.1): the argument names are already captured by the substitute() call one line above, so names(dots_quoted) carries the identical information. * nullfile() (R >= 4.0) is replaced by an internal .nullfile() in the small base-R replacements section of utils.R, returning the platform null device; the three render-path call sites in chart_indicator.R now use it. Verified against the single-panel print, the multi-panel grob alignment and the print-guard paths. * The pattern-marker data.frames in chart_pattern.R set stringsAsFactors = FALSE explicitly - the default flipped in R 4.0, and the declared floor predates the flip. **NOTE:** This was captured during an adversial review by Fable. --- R/chart_indicator.R | 6 +++--- R/chart_pattern.R | 8 ++++++-- R/series.R | 4 +++- R/utils.R | 5 +++++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/R/chart_indicator.R b/R/chart_indicator.R index 9496fe408..d2030c4d7 100644 --- a/R/chart_indicator.R +++ b/R/chart_indicator.R @@ -687,7 +687,7 @@ assemble_ggplot2 <- function() { ## convert to grobs and align column widths ## so that y-axes line up across panels ## use a null device to prevent Rplots.pdf - grDevices::pdf(nullfile()) + grDevices::pdf(.nullfile()) dev_null <- grDevices::dev.cur() on.exit(grDevices::dev.off(dev_null), add = TRUE) grobs <- lapply(panels, ggplot2::ggplotGrob) @@ -733,7 +733,7 @@ wrap_gg <- function(x) { #' @export print.talib_gg_chart <- function(x, ...) { if (grDevices::dev.cur() == 1L) { - grDevices::pdf(nullfile()) + grDevices::pdf(.nullfile()) on.exit(grDevices::dev.off(), add = TRUE) } NextMethod() @@ -746,7 +746,7 @@ print.talib_chart <- function(x, ...) { ## avoid Rplots.pdf when no device is open ## (e.g., R CMD check, tests, vignette knit) if (grDevices::dev.cur() == 1L) { - grDevices::pdf(nullfile()) + grDevices::pdf(.nullfile()) on.exit(grDevices::dev.off(), add = TRUE) } diff --git a/R/chart_pattern.R b/R/chart_pattern.R index fdadcb211..ccd645cf5 100644 --- a/R/chart_pattern.R +++ b/R/chart_pattern.R @@ -143,7 +143,9 @@ pattern_gg <- function( bear_data <- data.frame( .chart_pos = chart_pos[idx_bear], y = high[idx_bear] + offset[idx_bear], - label = pattern_name + label = pattern_name, + ## the default flipped in R 4.0; explicit for R >= 3.5 + stringsAsFactors = FALSE ) p <- p + @@ -183,7 +185,9 @@ pattern_gg <- function( } else { low[idx_bull] - offset[idx_bull] }, - label = pattern_name + label = pattern_name, + ## the default flipped in R 4.0; explicit for R >= 3.5 + stringsAsFactors = FALSE ) marker_color <- if (agnostic) { diff --git a/R/series.R b/R/series.R index 2621fc6a7..73e784140 100644 --- a/R/series.R +++ b/R/series.R @@ -138,7 +138,9 @@ series.plotly <- function( list(...) ) )[-1L] - dn <- ...names() + ## substitute() captures the argument names alongside the + ## expressions - base::...names() exists only from R 4.1 + dn <- names(dots_quoted) if (length(dots_quoted)) { if (is.null(dn)) { dn <- rep("", length(dots_quoted)) diff --git a/R/utils.R b/R/utils.R index 0de3025a0..f0cfb2db4 100644 --- a/R/utils.R +++ b/R/utils.R @@ -166,6 +166,11 @@ assert_column_names <- function(formula, available_variables) { x } +## base::nullfile() exists only from R 4.0 +.nullfile <- function() { + if (.Platform$OS.type == "windows") "nul:" else "/dev/null" +} + ## class related utility ## functions is.formula <- function(x) { From 820aacbd6a73c1b01b1e26356a4e7723697271f2 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 20:55:41 +0200 Subject: [PATCH 19/22] :bug:-fix: .numeric method in volume missing lapply() * trading_volume() on a vector no longer errors on the default maType: the numeric splice converts the specifications like .default does. --- R/ta_VOLUME.R | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/R/ta_VOLUME.R b/R/ta_VOLUME.R index 13031e80f..a2ce84d1e 100644 --- a/R/ta_VOLUME.R +++ b/R/ta_VOLUME.R @@ -191,7 +191,14 @@ trading_volume.numeric <- function( C_impl_ta_VOLUME, ## splice:numeric:start as.double(x), - maType, + lapply( + maType, + function(x) { + as.integer( + x + ) + } + ), ## splice:numeric:end as.logical(na.bridge) ) From 5c3966dd91fa58a3d181de53c5f556797265d54b Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 20:56:57 +0200 Subject: [PATCH 20/22] :hammer: Charting pipeline fixes and extension * 'subset' is evaluated exactly once, by model.frame(), identically on every route (direct data.frame call, wrapper-on-chart, indicator()): data-context expressions like subset = close > 60000 now work everywhere, columns of the data win over caller objects, and the caller's frame is the fallback. The internal re-evaluations that crashed data-context expressions - and evaluated side-effecting expressions up to three times - are gone; the subset attribute now records the row positions model.frame() actually kept. * Arguments on the chart path resolve in the caller's frame: data =/subset = referencing function-local objects work from inside function bodies. indicator() keeps 'subset' quoted and evaluates the wrapper call in the caller's frame, so all routes share one semantic. * The ggplot2 backend aligns indicator positions by axis label, mirroring plotly - indicators computed with subset = are drawn at the subset's own candles instead of positions 1..n. * indicator(FUN, data = y) no longer silently stamps the chart's dates onto a mismatched override: a length mismatch warns and the trace is labelled with the override's own rownames. * chart() normalizes quantmod-style OHLCV names (TICKER.Close, Close) to the lowercase names the backends consume - exact matches first, then dot-suffix matches, mirroring series.xts() - and fails fast with the package's own missing-columns message instead of an opaque backend error at render time. Standalone indicator() with data keeps its time axis. --- R/chart.R | 25 +++++++++++++++++++++++ R/chart_build.R | 18 +++++++++++------ R/chart_indicator.R | 36 +++++++++++++++++++++++++--------- R/helper.R | 31 +++++++++++++++++++---------- R/series.R | 35 +++++++++++++++++++++++++++------ tests/testthat/test-charting.R | 8 +++++--- 6 files changed, 119 insertions(+), 34 deletions(-) diff --git a/R/chart.R b/R/chart.R index 51de473c6..45512a7a0 100644 --- a/R/chart.R +++ b/R/chart.R @@ -169,6 +169,31 @@ chart.default <- function( ## convert input to data.frame and store in state x <- as.data.frame(x) + + ## normalize quantmod-style OHLCV names (TICKER.Close, Close) + ## to the lowercase names the chart backends consume - exact + ## matches win over dot-suffix matches, mirroring series.xts() + targets <- c("open", "high", "low", "close", "volume") + lowered <- tolower(colnames(x)) + exact_hits <- outer(targets, lowered, `==`) + suffix_hits <- outer( + paste0(".", targets), + lowered, + function(suffix, name) endsWith(name, suffix) + ) + suffix_hits[rowSums(exact_hits) > 0L, ] <- FALSE + hits <- exact_hits | suffix_hits + resolved <- rowSums(hits) == 1L + colnames(x)[max.col(hits, ties.method = "first")[resolved]] <- + targets[resolved] + + ## fail fast with the package's own message instead of a + ## deferred backend error at render time + assert_column_names( + formula = ~ open + high + low + close, + available_variables = colnames(x) + ) + x$idx <- if (is.null(idx)) { ## check if rownames can be ## converted to integer diff --git a/R/chart_build.R b/R/chart_build.R index b94aeb715..6375820d5 100644 --- a/R/chart_build.R +++ b/R/chart_build.R @@ -173,12 +173,18 @@ build_ggplot <- function( data <- data[-(1:lookback), , drop = FALSE] } - ## add position column aligned - ## with main chart x-axis - data$.chart_pos <- seq.int( - lookback + 1L, - lookback + nrow(data) - ) + ## add position column aligned with the main chart x-axis. + ## Aligning by label places subset indicators on their own + ## rows of the shared axis - mirroring the plotly backend, + ## which aligns by the idx labels themselves + chart_positions <- match(data$idx, .chart_state()$idx$label) + if (length(chart_positions) != nrow(data) || anyNA(chart_positions)) { + chart_positions <- seq.int( + lookback + 1L, + lookback + nrow(data) + ) + } + data$.chart_pos <- chart_positions ## replace missing name if (missing(name) || is.null(name)) { diff --git a/R/chart_indicator.R b/R/chart_indicator.R index d2030c4d7..4468a2faa 100644 --- a/R/chart_indicator.R +++ b/R/chart_indicator.R @@ -221,8 +221,11 @@ indicator.function <- function(FUN, ...) { match.call()[["idx"]] ) } else { + ## rownames of the coerced frame so index-bearing + ## classes (xts) keep their time axis - a bare + ## rownames(data) is NULL for those idx <- rownames( - data + as.data.frame(data) ) } @@ -235,14 +238,29 @@ indicator.function <- function(FUN, ...) { state$x <- as.data.frame(data) } - ## dispatch to the appropriate backend method - ## based on the class of 'plt' - outcome <- do.call( - what = FUN, - args = list( - x = plt, - ... - ) + ## dispatch to the appropriate backend method based on the + ## class of 'plt'. Everything except 'subset' is forced + ## through its own promise; 'subset' stays quoted and the + ## call evaluates in the caller's frame, so model.frame() + ## sees it once, data-first, with the caller's objects as + ## fallback - identical to a direct wrapper call + dots_expr <- as.list(substitute(list(...)))[-1L] + dots_names <- names(dots_expr) + if (is.null(dots_names)) { + dots_names <- rep("", length(dots_expr)) + } + + dots_expr[] <- lapply(seq_along(dots_expr), function(i) { + if (identical(dots_names[[i]], "subset")) { + dots_expr[[i]] + } else { + ...elt(i) + } + }) + + outcome <- eval( + as.call(c(list(FUN), list(x = plt), dots_expr)), + parent.frame() ) ## verify return type diff --git a/R/helper.R b/R/helper.R index 3bd0b83a6..5950039af 100644 --- a/R/helper.R +++ b/R/helper.R @@ -81,17 +81,28 @@ add_idx <- function(x) { ## by chart during initialization idx <- .chart_state()$idx$label - if (!is.null(idx)) { - idx[ - if (is.null(attributes(x)$subset)) { - 1:nrow(x) - } else { - attributes(x)$subset - } - ] - } else { - 1:nrow(x) + if (is.null(idx)) { + return(1:nrow(x)) + } + + subset <- attributes(x)$subset + + if (!is.null(subset)) { + return(idx[subset]) } + + ## a data-override can differ from the chart: surface the + ## mismatch and label the trace with its own rownames + ## instead of silently stamping the chart's dates onto it + if (nrow(x) != length(idx)) { + warning( + "'data' length differs from the chart; using its own labels.", + call. = FALSE + ) + return(rownames(x) %nn% 1:nrow(x)) + } + + idx[1:nrow(x)] } ## apply named overrides to every trace diff --git a/R/series.R b/R/series.R index 73e784140..52ac8f7a7 100644 --- a/R/series.R +++ b/R/series.R @@ -146,10 +146,29 @@ series.plotly <- function( dn <- rep("", length(dots_quoted)) } names(dots_quoted) <- dn + + ## force every argument except 'subset' through its own + ## promise so caller-local objects (data = my_local) + ## resolve in the caller's frame; 'subset' stays quoted + ## for the single model.frame() evaluation downstream + dots_quoted[] <- lapply(seq_along(dots_quoted), function(i) { + if (identical(dn[[i]], "subset")) { + dots_quoted[[i]] + } else { + ...elt(i) + } + }) } else { dots_quoted <- list() } + ## model.frame() falls back to the formula environment for + ## subset symbols that are not columns; re-parent it to the + ## frame that called the wrapper so caller-local objects + ## resolve (three frames up: series method -> wrapper method + ## -> the wrapper's caller) + environment(formula) <- parent.frame(3L) + ## Inject the chart's data only when the caller did NOT pass data ## explicitly. This preserves the per-indicator data override - ## e.g. chart(ETH); indicator(RSI, data = BTC) computes RSI on BTC @@ -172,7 +191,9 @@ series.plotly <- function( data_arg <- dots_quoted$data dots_quoted$data <- NULL - output <- as.data.frame( + ## the subset attribute travels on the series result - set + ## once by series.data.frame from what model.frame() kept + as.data.frame( do.call( series, c( @@ -186,9 +207,6 @@ series.plotly <- function( quote = FALSE ) ) - - attr(output, "subset") <- eval(dots_quoted$subset) - output } #' Formula method - the main column-resolution path. @@ -258,9 +276,14 @@ series.data.frame <- function( c(list(formula = formula, data = x), dots_quoted), quote = FALSE ) - } - attr(output, "subset") <- eval(dots_quoted$subset) + ## the rows model.frame() actually kept - evaluated once, + ## in the data context. Consumers (add_idx, the chart + ## builders) index the chart axis with these positions. + if ("subset" %in% names(dots_quoted)) { + attr(output, "subset") <- match(rownames(output), rownames(x)) + } + } output } diff --git a/tests/testthat/test-charting.R b/tests/testthat/test-charting.R index b6be91dab..9d498888f 100644 --- a/tests/testthat/test-charting.R +++ b/tests/testthat/test-charting.R @@ -23,8 +23,9 @@ testthat::test_that(desc = "Charting", code = { ## 2) test that indicators ## can be passed with custom - ## data - testthat::expect_no_error( + ## data - a length mismatch against the + ## chart is surfaced as a warning + testthat::expect_warning( { chart(SPY) indicator( @@ -32,7 +33,8 @@ testthat::test_that(desc = "Charting", code = { cols = ~open, data = BTC ) - } + }, + regexp = "differs from the chart" ) }) From ed7a53ed5088fa82aff31ca0cba76b37bb4b604a Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 21:10:34 +0200 Subject: [PATCH 21/22] :books: Added GOOGL to Financial Data section --- _pkgdown.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/_pkgdown.yml b/_pkgdown.yml index fbcda687d..ee8244ed4 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -90,4 +90,5 @@ reference: - SPY - NVDA - ATOM + - GOOGL From aae378f32b883faa3d0e0b6769836a769080a357 Mon Sep 17 00:00:00 2001 From: serkor1 <77464572+serkor1@users.noreply.github.com> Date: Tue, 4 Aug 2026 22:21:04 +0200 Subject: [PATCH 22/22] :books: Updated README * Added -method mention, and removed the minimal dependency argument - even though xts and zoo are suggested it is still a departure from the minimal dependency framework. * Replaced BTC with GOOGL to demonstrate compatibility with class in and class out condtion. --- README.md | 58 ++++++++++++---------- dev/README.Rmd | 35 +++++++------ man/figures/README-charting-example-1.png | Bin 106825 -> 105255 bytes 3 files changed, 53 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index eea0fdf6a..73da97bf3 100644 --- a/README.md +++ b/README.md @@ -63,28 +63,36 @@ pak::pak("serkor1/ta-lib-R") ## Quick start -All functions provide S3 methods for ``, ``, -and—where applicable—`` inputs. The general convention is -simple: the output uses the same container type as the input. +All functions provide S3 methods for ``, ``, +``, and—where applicable—`` inputs. The general +convention is simple: the output uses the same container type as the +input. ``` r ## calculate the ## relative strength index relative_strength_index <- talib::RSI( - talib::BTC + talib::GOOGL ) +## check class equivalence +inherits( + relative_strength_index, + class(talib::GOOGL) +) +#> [1] TRUE + ## display results tail( relative_strength_index ) -#> RSI -#> 2024-12-26 01:00:00 46.48851 -#> 2024-12-27 01:00:00 43.85488 -#> 2024-12-28 01:00:00 45.93888 -#> 2024-12-29 01:00:00 43.12301 -#> 2024-12-30 01:00:00 41.47686 -#> 2024-12-31 01:00:00 43.37358 +#> RSI +#> 2021-12-22 53.47421 +#> 2021-12-23 54.45979 +#> 2021-12-27 56.42226 +#> 2021-12-28 53.37121 +#> 2021-12-29 53.28979 +#> 2021-12-30 52.07450 ``` Indicator outputs preserve input length, which keeps results aligned @@ -94,19 +102,19 @@ with the original OHLCV rows. ## combine multiple ## indicators features <- cbind( - talib::relative_strength_index(talib::BTC), - talib::bollinger_bands(talib::BTC), - talib::engulfing(talib::BTC) + talib::relative_strength_index(talib::GOOGL), + talib::bollinger_bands(talib::GOOGL), + talib::engulfing(talib::GOOGL) ) tail(features) -#> RSI UpperBand MiddleBand LowerBand CDLENGULFING -#> 2024-12-26 01:00:00 46.48851 106053.7 99594.80 93135.86 -100 -#> 2024-12-27 01:00:00 43.85488 106179.5 99305.69 92431.90 0 -#> 2024-12-28 01:00:00 45.93888 106051.3 99002.74 91954.18 0 -#> 2024-12-29 01:00:00 43.12301 106223.8 98814.94 91406.11 -100 -#> 2024-12-30 01:00:00 41.47686 106452.7 98613.30 90773.93 0 -#> 2024-12-31 01:00:00 43.37358 106283.3 98223.05 90162.77 0 +#> RSI UpperBand MiddleBand LowerBand CDLENGULFING +#> 2021-12-22 53.47421 149.1432 144.4920 139.8408 0 +#> 2021-12-23 54.45979 149.2513 144.5318 139.8124 0 +#> 2021-12-27 56.42226 149.6263 144.8180 140.0097 0 +#> 2021-12-28 53.37121 149.7444 144.8758 140.0072 -100 +#> 2021-12-29 53.28979 149.8398 145.1137 140.3876 0 +#> 2021-12-30 52.07450 149.7308 145.3711 141.0115 -100 ``` ## Charting @@ -118,16 +126,16 @@ flexibility: ``` r ## subset data and -## store as 'BTC' -BTC <- talib::BTC[1:75, ] +## store as 'GOOGL' +GOOGL <- talib::GOOGL[1:75, ] ## construct chart in a brace block ## alternatively use `|>` { ## initialize main chart talib::chart( - x = BTC, - title = "Bitcoin" + x = GOOGL, + title = "Alphabet Inc." ) ## add Bollinger Bands to diff --git a/dev/README.Rmd b/dev/README.Rmd index ce73cb185..0089feea7 100644 --- a/dev/README.Rmd +++ b/dev/README.Rmd @@ -46,12 +46,11 @@ The API covers 150+ [TA-Lib](https://github.com/TA-Lib/ta-lib)-backed functions | Need | {talib}| |:----------------------|:-----------------------------------------------------------------------------------------| -| Technical indicators | TA-Lib-backed moving averages, momentum, volatility, volume, cycle, and overlap studies | -| Candlestick patterns | Built-in Japanese candlestick pattern recognition | -| OHLCV workflows | Works directly with open, high, low, close, and volume columns | -| Performance | Computation delegated to C routines through `.Call()` | -| Dependencies | Minimal required R dependencies; plotting packages are optional | -| Charts | Composable financial charts with optional `{plotly}` and `{ggplot2}` support | +| Technical indicators | TA-Lib-backed moving averages, momentum, volatility, volume, cycle, and overlap studies | +| Candlestick patterns | Built-in Japanese candlestick pattern recognition | +| OHLCV workflows | Works directly with open, high, low, close, and volume columns | +| Performance | Computation delegated to C routines through `.Call()` | +| Charts | Composable financial charts with optional `{plotly}` and `{ggplot2}` support | @@ -71,13 +70,19 @@ pak::pak("serkor1/ta-lib-R") ## Quick start -All functions provide S3 methods for ``, ``, and---where applicable---`` inputs. The general convention is simple: the output uses the same container type as the input. +All functions provide S3 methods for ``, ``, ``, and---where applicable---`` inputs. The general convention is simple: the output uses the same container type as the input. ```{r quick-start, echo=TRUE} ## calculate the ## relative strength index relative_strength_index <- talib::RSI( - talib::BTC + talib::GOOGL +) + +## check class equivalence +inherits( + relative_strength_index, + class(talib::GOOGL) ) ## display results @@ -93,9 +98,9 @@ original OHLCV rows. ## combine multiple ## indicators features <- cbind( - talib::relative_strength_index(talib::BTC), - talib::bollinger_bands(talib::BTC), - talib::engulfing(talib::BTC) + talib::relative_strength_index(talib::GOOGL), + talib::bollinger_bands(talib::GOOGL), + talib::engulfing(talib::GOOGL) ) tail(features) @@ -107,16 +112,16 @@ tail(features) ```{r charting-example, echo=TRUE} ## subset data and -## store as 'BTC' -BTC <- talib::BTC[1:75, ] +## store as 'GOOGL' +GOOGL <- talib::GOOGL[1:75, ] ## construct chart in a brace block ## alternatively use `|>` { ## initialize main chart talib::chart( - x = BTC, - title = "Bitcoin" + x = GOOGL, + title = "Alphabet Inc." ) ## add Bollinger Bands to diff --git a/man/figures/README-charting-example-1.png b/man/figures/README-charting-example-1.png index 3950d263376f9627366056c7941de8701b6cf3b7..0bb7e048c871869404d5204806f8e6485f22ee66 100644 GIT binary patch literal 105255 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%0D&g9_@r-^kyMcH!c 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

  • EgEw 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

    eB9vkMPzR8z5RfNFo*@Y$}}Cf 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