The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
Trading indicators comes in various forms. From the alignment of the
moon relative to the sun, to sophisticated trading rules based on neural
networks which incorporates classified features. It is not possible to
cover them all in an R
package.
In this vignette
an introduction to the construction of
charting indicators are given, and is recommended for those who would
want to chart indicators not otherwise found in the
cryptoQuotes
-package.
Note: Feel free to make a
PR
with your indicators that you wish to share with the rest of the community.
Below is a chart, with the indicators macd()
and
bollinger_bands()
. Each indicator is created using the
TTR
-package.
Each indicator is either a main chart- or
subchart-indicator, lets call them classes
for
consistency. The source code for each class
of indicator is
given below,
#> function (n = 20, sd = 2, maType = "SMA", color = "#4682b4",
#> ...)
#> {
#> check_indicator_call()
#> structure(.Data = {
#> args <- list(...)
#> linewidth <- 0.9
#> data <- indicator(x = args$data, columns = c("high",
#> "low", "close"), .f = TTR::BBands, n = n, sd = sd,
#> maType = maType)
#> layers <- list(list(type = "add_lines", params = list(showlegend = FALSE,
#> legendgroup = "bb", name = "Lower", inherit = FALSE,
#> data = data, x = ~index, y = ~dn, line = list(color = color,
#> width = linewidth))), list(type = "add_lines",
#> params = list(showlegend = FALSE, legendgroup = "bb",
#> name = "Upper", inherit = FALSE, data = data,
#> x = ~index, y = ~up, line = list(color = color,
#> width = linewidth))), list(type = "add_lines",
#> params = list(showlegend = FALSE, legendgroup = "bb",
#> name = paste(maType), inherit = FALSE, data = data,
#> x = ~index, y = ~mavg, line = list(color = color,
#> dash = "dot", width = linewidth))))
#> plot <- plotly::add_ribbons(showlegend = TRUE, legendgroup = "bb",
#> p = args$plot, inherit = FALSE, x = ~index, ymin = ~dn,
#> ymax = ~up, data = data, fillcolor = as_rgb(alpha = 0.1,
#> hex_color = color), line = list(color = "transparent"),
#> name = paste0("BB(", paste(c(n, sd, maType), collapse = ", "),
#> ")"))
#> plot <- build(plot = plot, layers = layers)
#> invisible(plot)
#> }, class = c("indicator", "plotly", "htmlwidget"))
#> }
#> <bytecode: 0x610985007230>
#> <environment: namespace:cryptoQuotes>
#> function (nFast = 12, nSlow = 26, nSig = 9, maType = "SMA", percent = TRUE,
#> ...)
#> {
#> check_indicator_call()
#> structure(.Data = {
#> args <- list(...)
#> linewidth <- 0.9
#> data <- indicator(x = args$data, columns = "close", .f = TTR::MACD,
#> nFast = nFast, nSlow = nSlow, nSig = nSig, maType = maType,
#> percent = percent)
#> data$direction <- as.logical(data$signal >= data$macd)
#> p <- plotly::plot_ly(data = data, showlegend = FALSE,
#> name = "MACD", x = ~index, y = ~(macd - signal),
#> color = ~direction, colors = c(args$candle_color$bullish,
#> args$candle_color$bearish), type = "bar", marker = list(line = list(color = "black",
#> width = 0.5)))
#> layers <- list(list(type = "add_lines", params = list(name = "MACD: Signal",
#> data = data, showlegend = FALSE, x = ~index, y = ~signal,
#> inherit = FALSE, line = list(width = linewidth))),
#> list(type = "add_lines", params = list(name = "MACD: MACD",
#> data = data, showlegend = FALSE, x = ~index,
#> y = ~macd, inherit = FALSE, line = list(width = linewidth))))
#> p <- build(plot = p, layers = layers, annotations = list(list(text = paste0("MACD(",
#> paste(c(nFast, nSlow, nSig), collapse = ", "), ")"),
#> x = 0, y = 1, font = list(size = 16), xref = "paper",
#> yref = "paper", showarrow = FALSE)), yaxis = list(title = NA))
#> p
#> }, class = c("subchart", "plotly", "htmlwidget"))
#> }
#> <bytecode: 0x6109828d68a0>
#> <environment: namespace:cryptoQuotes>
Common for both indicator classes
is that they are
wrapped in structure
, with
class = c("plotly", "htmlwidget")
,
What differentiates the two classes
of indicators, is
the addition of indicator
or subchart
in the
yourclass
-placeholder.
The indicator logic is important for the correct charting of your
custom indicator. As the cryptoQuotes
-package uses
plotly
as backend for charting, your class
of
indicator has to be consistent with the use of
plotly
-functions. More specifically;
subchart
-indicators uses
plotly::plot_ly()
-functions, while main chart
indicator
uses add_*
-functions.
When creating the custom indicators there is a couple of additional steps needed which will be covered in the examples.
Assume a trading strategy based on Donchian Channels
(TTR::DonchianChannel()
) is needed to optimize your
profits. This indicator is a main chart indicator, similar to that of
TTR::BBands()
,
tail(
TTR::DonchianChannel(
HL = BTC[,c("high", "low")]
)
)
#> high mid low
#> 2024-05-31 17:00:00 69006 68133.80 67261.6
#> 2024-05-31 18:00:00 69006 67849.15 66692.3
#> 2024-05-31 19:00:00 69006 67849.15 66692.3
#> 2024-05-31 20:00:00 69006 67849.15 66692.3
#> 2024-05-31 21:00:00 69006 67849.15 66692.3
#> 2024-05-31 22:00:00 69006 67849.15 66692.3
This indicator has three features; high
,
mid
and low
. To chart this indicator, we would
need to call the plotly::add_lines()
-function three times
to chart it properly. Each of these features are defined as
layers
in the cryptoQuotes
-package. All layers
get built with the cryptoQuotes:::build()
-function.
## define custom TA
## donchian_channel
donchian_channel <- function(
## these arguments are the
## available arguments in the TTR::DonchianChannel
## function
n = 10,
include.lag = FALSE,
## the ellipsis
## is needed to interact with
## the chart-function
...
) {
structure(
.Data = {
## 1) define args
## as a list from the ellipsis
## which is how the chart-function
## communicates with the indicators
args <- list(
...
)
## 2) define the data, which in this
## case is the indicator. The indicator
## function streamlines the data so it works
## with plotly
data <- cryptoQuotes:::indicator(
## this is just the ticker
## that is passed into the chart-function
x = args$data,
## columns are the columns of the ohlc
## which the indicator is calculated on
columns = c("high", "low"),
## the function itself
## can be a custom function
## too.
.f = TTR::DonchianChannel,
## all other arguments
## passed into .f
n = n,
include.lag = FALSE
)
## each layer represents
## each output from the indicator
## in this case we have
## high, mid and low.
##
## The lists represents a plotly-function
## and its associated parameters.
layers <- list(
## high
list(
type = "add_lines",
params = list(
showlegend = FALSE,
legendgroup = "DC",
name = "high",
inherit = FALSE,
data = data,
x = ~index,
y = ~high,
line = list(
color = "#d38b68",
width = 0.9
)
)
),
## mid
list(
type = "add_lines",
params = list(
showlegend = FALSE,
legendgroup = "DC",
name = "mid",
inherit = FALSE,
data = data,
x = ~index,
y = ~mid,
line = list(
color = "#d38b68",
dash ='dot',
width = 0.9
)
)
),
## low
list(
type = "add_lines",
params = list(
showlegend = FALSE,
legendgroup = "DC",
name = "low",
inherit = FALSE,
data = data,
x = ~index,
y = ~low,
line = list(
color = "#d38b68",
width = 0.9
)
)
)
)
## we can add ribbons
## to the main plot to give
## it a more structured look.
plot <- plotly::add_ribbons(
showlegend = TRUE,
legendgroup = 'DC',
p = args$plot,
inherit = FALSE,
x = ~index,
ymin = ~low,
ymax = ~high,
data = data,
fillcolor = cryptoQuotes:::as_rgb(alpha = 0.1, hex_color = "#d38b68"),
line = list(
color = "transparent"
),
name = paste0("DC(", paste(c(n), collapse = ", "), ")")
)
## the plot has to be build
## using the cryptoQuotes::build-function
invisible(
cryptoQuotes:::build(
plot,
layers = layers
)
)
}
)
}
The indicator function can be passed into the appropriate argument in
the chart()
-function, which will handle everything
else,
Assume a trading strategy based on Commodity Channel Indices
(TTR::CCI()
) is needed to optimize your profits. This
indicator is subchart indicator similar to that of
TTR::RSI()
,
tail(
TTR::CCI(
HLC = BTC[,c("high", "low", "close")]
)
)
#> cci
#> 2024-05-31 17:00:00 -290.27510
#> 2024-05-31 18:00:00 -266.68182
#> 2024-05-31 19:00:00 -160.89230
#> 2024-05-31 20:00:00 -127.22393
#> 2024-05-31 21:00:00 -66.20187
#> 2024-05-31 22:00:00 -50.50047
This indicator has a single feature; cci
. As this
indicator is a subchart indicator with a single feature, we only need a
single layer
built with plot_ly()
,
## define custom TA
## Commodity Channel Index (CCI)
cc_index <- function(
## these arguments are the
## available arguments in the TTR::CCI
## function
n = 20,
maType,
c = 0.015,
## the ellipsis
## is needed to interact with
## the chart-function
...
) {
structure(
.Data = {
## 1) define args
## as a list from the ellipsis
## which is how the chart-function
## communicates with the indicators
args <- list(
...
)
## 2) define the data, which in this
## case is the indicator. The indicator
## function streamlines the data so it works
## with plotly
data <- cryptoQuotes:::indicator(
## this is just the ticker
## that is passed into the chart-function
x = args$data,
## columns are the columns of the ohlc
## which the indicator is calculated on
columns = c("high", "low", "close"),
## the function itself
## can be a custom function
## too.
.f = TTR::CCI,
## all other arguments
## passed into .f
n = n,
maType = maType,
c = c
)
layer <- list(
list(
type = "plot_ly",
params = list(
name = paste0("CCI(", n,")"),
data = data,
showlegend = TRUE,
x = ~index,
y = ~cci,
type = "scatter",
mode = "lines",
line = list(
color = cryptoQuotes:::as_rgb(alpha = 1, hex_color = "#d38b68"),
width = 0.9
)
)
)
)
cryptoQuotes:::build(
plot = args$plot,
layers = layer,
annotations = list(
list(
text = "Commodity Channel Index",
x = 0,
y = 1,
font = list(
size = 18
),
xref = 'paper',
yref = 'paper',
showarrow = FALSE
)
)
)
}
)
}
Creating custom indicators for the chart()
-functions can
be daunting. Two examples of how these are developed in th e
cryptoQuotes
-packages have been covered.
Note: A full pipeline of charting indicators, custom and built-in, will be released sometime in the future.
To summarise the example,
indicator
-function (e.g
TTR::CCI()
)chart
-function for the indicator (e.g
cc_index()
)
indicator
-function in
cryptoQuotes:::indicator()
layers
according to features, and wether its
a subchart or main chart indicatorcryptoQuotes:::build()
chart
-function for the indicator in the
appropriate argument in the chart()
-functionThese binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.