# {talib}: R bindings to TA-Lib

{talib} is an R package for Technical Analysis (TA) and interactive financial charts. The package is a wrapper of TA-Lib and supports over 200 indicators, including candlestick patterns.

## Data format

All functions in {talib} expect the input `x` to be coercible to `data.frame` with columns named according to OHLC-V conventions. The package ships with several built-in datasets:

    str(talib::BTC)
    #> 'data.frame':    366 obs. of  5 variables:
    #>  $ open  : num  42274 44185 44966 42863 44191 ...
    #>  $ high  : num  44200 45918 45521 44799 44392 ...
    #>  $ low   : num  42181 44152 40555 42651 42362 ...
    #>  $ close : num  44185 44966 42863 44191 44179 ...
    #>  $ volume: num  831 2076 2225 1791 2483 ...

### Column names are case-sensitive

Column names must be lowercase: `open`, `high`, `low`, `close`, and `volume`. Names such as `Close`, `CLOSE`, or `Adj.Close` will not be recognized. If your data uses different names you have two options: rename the columns, or remap them with the `cols` argument (see Column selection with `cols`).

    ## rename columns to uppercase;
    ## this will fail
    x <- talib::BTC
    colnames(x) <- c("Open", "High", "Low", "Close", "Volume")

    talib::RSI(x)
    #> Error in `relative_strength_index.default()`:
    #> ! Expected to find columns 'close' similar columns found: 'Close'

### Not every column is always required

Different indicators use different subsets of the OHLC-V columns. The table below gives a rough guide:

Indicator type | Default columns | Example
--- | --- | ---
Univariate (most) | `close` | `RSI()`, `SMA()`, `EMA()`
High-Low based | `high + low` | `SAR()`, `AROON()`
High-Low-Close | `high + low + close` | `STOCH()`, `CCI()`, `ATR()`
Full OHLC | `open + high + low + close` | All candlestick patterns
Volume-based | `volume` (+ price columns) | `OBV()`, `AD()`, `MFI()`

A `data.frame` that only contains `high`, `low`, and `close` is perfectly valid input for `STOCH()` or `CCI()`—columns that are not needed are simply ignored.

## Computing indicators

### Basic usage

Pass an OHLC-V object directly to any indicator function:

    tail(
        talib::bollinger_bands(talib::BTC)
    )
    #>                     UpperBand MiddleBand LowerBand
    #> 2024-12-26 01:00:00 100487.38   96698.61  92909.83
    #> 2024-12-27 01:00:00 100670.65   96512.96  92355.27
    #> 2024-12-28 01:00:00 100632.13   96581.91  92531.69
    #> 2024-12-29 01:00:00  99628.77   95576.60  91524.43
    #> 2024-12-30 01:00:00  96403.53   94231.31  92059.09
    #> 2024-12-31 01:00:00  95441.13   93774.23  92107.34

All indicator functions follow the same S3 dispatch pattern, with methods for `data.frame`, `matrix`, `numeric`, and `plotly`. The return type matches the input type:

    ## data.frame in -> data.frame out
    class(
        talib::RSI(talib::BTC)
    )
    #> [1] "data.frame"

    ## matrix in -> matrix out
    class(
        talib::RSI(talib::SPY)
    )
    #> [1] "matrix" "array"

    ## numeric vector in -> numeric vector out
    is.double(
        talib::RSI(talib::BTC$close)
    )
    #> [1] TRUE

### Function naming

Every indicator has a descriptive snake_case name and an uppercase alias that mirrors the TA-Lib C function name. Both are interchangeable:

    ## these are equivalent
    identical(
        talib::relative_strength_index(talib::BTC, n = 14),
        talib::RSI(talib::BTC, n = 14)
    )
    #> [1] TRUE

### Lookback and `NA` values

Most indicators require a minimum number of observations before they can produce a value. This is called the lookback period. The first `lookback` rows of the result will be `NA`:

    ## SMA with n = 5 has a lookback of 4
    head(
        talib::SMA(talib::BTC, n = 5),
        n = 7
    )
    #>                          SMA
    #> 2024-01-01 01:00:00       NA
    #> 2024-01-02 01:00:00       NA
    #> 2024-01-03 01:00:00       NA
    #> 2024-01-04 01:00:00       NA
    #> 2024-01-05 01:00:00 44076.95
    #> 2024-01-06 01:00:00 44038.77
    #> 2024-01-07 01:00:00 43835.33

The lookback is stored as an attribute on the result:

    x <- talib::SMA(talib::BTC, n = 20)
    attr(x, "lookback")
    #> [1] 19

## Column selection with `cols`

The `cols` argument accepts a one-sided formula (`~`) that selects which columns to use for the calculation. Every indicator has a sensible default, but `cols` lets you override it.

### Univariate indicators

For indicators that operate on a single series (e.g., `RSI`, `SMA`), the default is `~close`. Pass a different column to calculate the indicator on that series instead:

    ## RSI on 'high' instead of 'close'
    tail(
        talib::RSI(talib::BTC, cols = ~high)
    )
    #>                          RSI
    #> 2024-12-26 01:00:00 50.88773
    #> 2024-12-27 01:00:00 45.83913
    #> 2024-12-28 01:00:00 42.51414
    #> 2024-12-29 01:00:00 41.80903
    #> 2024-12-30 01:00:00 41.33147
    #> 2024-12-31 01:00:00 44.58689

### Multivariate indicators

For indicators that require multiple columns, `cols` remaps which columns are used. The order in the formula must match the order expected by the indicator:

    ## Stochastic defaults to ~high + low + close;
    ## here we swap 'close' for 'open'
    tail(
        talib::STOCH(
            talib::BTC,
            cols = ~high + low + open
        )
    )
    #>                        SlowK    SlowD
    #> 2024-12-26 01:00:00 71.97751 51.79551
    #> 2024-12-27 01:00:00 74.68050 65.64619
    #> 2024-12-28 01:00:00 49.96515 65.54105
    #> 2024-12-29 01:00:00 29.80067 51.48210
    #> 2024-12-30 01:00:00 23.91322 34.55968
    #> 2024-12-31 01:00:00 26.81634 26.84341

### Extra arguments via `...`

Additional arguments are forwarded to `model.frame()`. This is useful for computing an indicator on a subset of the data:

    ## Bollinger Bands on the first 100 rows only
    tail(
        talib::BBANDS(
            talib::BTC,
            subset = 1:nrow(talib::BTC) %in% 1:100
        )
    )
    #>                     UpperBand MiddleBand LowerBand
    #> 2024-04-04 02:00:00  72605.20   68193.82  63782.44
    #> 2024-04-05 02:00:00  70646.91   67502.88  64358.84
    #> 2024-04-06 02:00:00  70087.36   67344.94  64602.52
    #> 2024-04-07 02:00:00  70475.41   68122.29  65769.16
    #> 2024-04-08 02:00:00  71820.87   69249.88  66678.89
    #> 2024-04-09 02:00:00  71848.20   69372.65  66897.09

## Handling missing values with `na.bridge`

Real-world data often contains missing values. By default (`na.bridge = FALSE`), any `NA` in the input propagates through the entire calculation, which can fill the result with `NA`s.

Setting `na.bridge = TRUE` strips `NA` rows before calculation, computes the indicator on the clean data, and then re-inserts `NA`s at their original positions:

    ## inject some NAs
    x <- talib::BTC
    x$close[c(10, 50, 100)] <- NA

    ## default: NAs propagate
    sum(is.na(
        talib::RSI(x)
    ))
    #> [1] 366

    ## na.bridge = TRUE: NAs are skipped
    sum(is.na(
        talib::RSI(x, na.bridge = TRUE)
    ))
    #> [1] 17

The stripped rows are restored in the output, so the result always has the same number of rows as the input:

    nrow(talib::RSI(x, na.bridge = TRUE)) == nrow(x)
    #> [1] TRUE

## Moving Average specifications

Several indicators accept a Moving Average specification for their smoothing component. MA functions such as `SMA()`, `EMA()`, `WMA()`, `DEMA()`, `TEMA()`, `TRIMA()`, `KAMA()`, and `T3()` serve a dual purpose:

- With `x`: compute the Moving Average on the data.
- Without `x`: return a specification (a named list) that other indicators use internally.

    ## SMA as a specification
    str(
        talib::SMA(n = 20)
    )
    #> List of 2
    #>  $ n     : int 20
    #>  $ maType: int 0

This specification can be passed to indicators like `bollinger_bands()` or `stochastic()` to control the type of smoothing:

    ## Bollinger Bands with an EMA(20) middle band
    tail(
        talib::bollinger_bands(
            talib::BTC,
            ma = talib::EMA(n = 20)
        )
    )
    #>                     UpperBand MiddleBand LowerBand
    #> 2024-12-26 01:00:00  104645.9   98186.94  91727.99
    #> 2024-12-27 01:00:00  104677.9   97804.16  90930.38
    #> 2024-12-28 01:00:00  104597.2   97548.60  90500.04
    #> 2024-12-29 01:00:00  104577.9   97169.11  89760.28
    #> 2024-12-30 01:00:00  104576.0   96736.62  88897.26
    #> 2024-12-31 01:00:00  104478.2   96417.96  88357.68

    ## Stochastic with WMA smoothing
    tail(
        talib::stochastic(
            talib::BTC,
            slowk = talib::WMA(n = 5),
            slowd = talib::EMA(n = 3)
        )
    )
    #>                        SlowK    SlowD
    #> 2024-12-26 01:00:00 62.93474 57.17934
    #> 2024-12-27 01:00:00 52.56693 54.87313
    #> 2024-12-28 01:00:00 43.17803 49.02558
    #> 2024-12-29 01:00:00 27.93503 38.48031
    #> 2024-12-30 01:00:00 19.49793 28.98912
    #> 2024-12-31 01:00:00 22.83957 25.91435

## Candlestick pattern recognition

Candlestick pattern functions return an integer `matrix`: `1` for bullish, `-1` for bearish, and `0` for no pattern. The encoding can be changed via `options(talib.normalize = FALSE)` to use `100`/`-100` instead.

    x <- talib::harami(talib::BTC)
    tail(x)
    #>                     CDLHARAMI
    #> 2024-12-26 01:00:00         0
    #> 2024-12-27 01:00:00         0
    #> 2024-12-28 01:00:00         0
    #> 2024-12-29 01:00:00         0
    #> 2024-12-30 01:00:00         0
    #> 2024-12-31 01:00:00         0

    ## find all bullish occurrences
    talib::BTC[which(x == 1), ]
    #>                         open     high      low    close    volume
    #> 2024-01-13 01:00:00 42770.74 43244.75 42417.54 42842.43 1389.8450
    #> 2024-01-19 01:00:00 41286.00 42144.29 40250.00 41622.00 2204.1180
    #> 2024-01-23 01:00:00 39521.03 40135.90 38508.01 39871.07 1691.9766
    #> 2024-03-06 01:00:00 63803.50 67655.97 62834.01 66112.32 2152.6899
    #> 2024-04-03 02:00:00 65477.34 66944.00 64500.00 65986.02  730.2592
    #> 2024-04-16 02:00:00 63449.24 64392.44 61641.34 63820.00  975.8047
    #> 2024-05-02 02:00:00 58267.89 59638.02 56893.92 59066.67 1608.7340
    #> 2024-06-27 02:00:00 60828.18 62346.00 60559.38 61629.99 1343.3199
    #> 2024-12-20 01:00:00 97385.63 98138.88 92129.00 97767.96 6001.8659

> Note: For a detailed treatment of candlestick lookback and sensitivity parameters, see `vignette("candlestick", package = "talib")`.

## Charting

The package includes interactive charting built on {plotly}. The two main functions are `chart()` and `indicator()`, which work like `plot()` and `lines()`:

    {
        ## main candlestick chart
        talib::chart(talib::BTC)

        ## add Bollinger Bands
        talib::indicator(talib::bollinger_bands)

        ## add identified Harami patterns
        talib::indicator(talib::harami)

        ## add MACD as a sub-chart
        talib::indicator(talib::MACD)
    }

`indicator()` automatically determines whether a given indicator belongs on the main price chart (e.g., Bollinger Bands, SAR) or as a sub-chart (e.g., RSI, MACD).

> Note: For themes, chart options, and advanced charting, see `vignette("charting", package = "talib")`.

## Contributing and bug reports

The underlying library, TA-Lib, is a long-standing and well-known library but this R wrapper is still in its early stage. All contributions, suggestions, and bug reports are welcome.