Batch API

Batch Execution API — run indicators on multiple series in a single call.

This module provides a 2-D batch API that accepts a 2-D numpy array (n_samples × n_series) and applies an indicator to every column, returning a 2-D output array of the same shape.

For the most common indicators — SMA, EMA, RSI — the 2-D path is handled entirely in Rust (a single GIL release for all columns). batch_apply also dispatches these indicators to Rust when possible; other indicators use the generic Python fallback path.

Functions

batch_sma — SMA on every column of a 2-D array (Rust fast path for 2-D) batch_ema — EMA on every column of a 2-D array (Rust fast path for 2-D) batch_rsi — RSI on every column of a 2-D array (Rust fast path for 2-D) batch_apply — Generic batch wrapper with Rust fast-path for SMA/EMA/RSI

Usage

>>> import numpy as np
>>> from ferro_ta.data.batch import batch_sma
>>> data = np.random.rand(100, 5)   # 100 bars, 5 symbols
>>> result = batch_sma(data, timeperiod=14)
>>> result.shape
(100, 5)
ferro_ta.batch.batch_apply(data, fn, **kwargs)[source]

Apply any single-series indicator fn to every column of data.

For recognized close-only indicators (SMA/EMA/RSI with default or timeperiod argument only), this function dispatches to the Rust batch kernels. Otherwise it falls back to a Python per-column loop.

Parameters:
  • data (array-like, shape (n_samples,) or (n_samples, n_series)) – Input data. If 1-D, the function is called directly on the array and the result is returned without adding a column dimension.

  • fn (callable) – Single-series indicator function (e.g. SMA, EMA, RSI). It must accept a 1-D array as first positional argument and return a 1-D array of the same length.

  • **kwargs – Extra keyword arguments forwarded to fn (e.g. timeperiod=14).

Returns:

Same shape as data. Leading values are NaN for the warm-up period, identical to calling fn on each column individually.

Return type:

numpy.ndarray

Examples

>>> import numpy as np
>>> from ferro_ta import SMA
>>> from ferro_ta.data.batch import batch_apply
>>> data = np.random.rand(50, 3)
>>> out = batch_apply(data, SMA, timeperiod=5)
>>> out.shape
(50, 3)
ferro_ta.batch.batch_ema(data, timeperiod=30, parallel=True)[source]

Exponential Moving Average on every column of data.

For 2-D inputs uses a Rust-side column loop (single GIL release). When parallel is True (default), columns are processed in parallel via Rayon across all available CPU cores.

Parameters:
  • data (array-like, shape (n_samples,) or (n_samples, n_series))

  • timeperiod (int, default 30)

  • parallel (bool, default True) – Enable multi-threaded parallel column processing via Rayon.

Return type:

numpy.ndarray — same shape as data.

ferro_ta.batch.batch_rsi(data, timeperiod=14, parallel=True)[source]

Relative Strength Index on every column of data.

For 2-D inputs uses a Rust-side column loop (single GIL release). When parallel is True (default), columns are processed in parallel via Rayon across all available CPU cores.

Parameters:
  • data (array-like, shape (n_samples,) or (n_samples, n_series))

  • timeperiod (int, default 14)

  • parallel (bool, default True) – Enable multi-threaded parallel column processing via Rayon.

Return type:

numpy.ndarray — same shape as data. Values in [0, 100].

ferro_ta.batch.batch_sma(data, timeperiod=30, parallel=True)[source]

Simple Moving Average on every column of data.

For 2-D inputs uses a Rust-side column loop (single GIL release). When parallel is True (default), columns are processed in parallel via Rayon across all available CPU cores. 1-D input is passed directly to the single-series SMA.

Parameters:
  • data (array-like, shape (n_samples,) or (n_samples, n_series))

  • timeperiod (int, default 30)

  • parallel (bool, default True) – Enable multi-threaded parallel column processing via Rayon. Set to False for small inputs where thread overhead dominates.

Return type:

numpy.ndarray — same shape as data.

Examples

>>> import numpy as np
>>> from ferro_ta.data.batch import batch_sma
>>> data = np.arange(1.0, 101.0).reshape(100, 1).repeat(3, axis=1)
>>> out = batch_sma(data, timeperiod=10)
>>> out.shape
(100, 3)
ferro_ta.batch.compute_many(indicators, *, close, high=None, low=None, volume=None, parallel=True)[source]

Compute multiple indicators over the same arrays with grouped Rust calls.

Supported single-output indicators are grouped into one Rust boundary crossing per input-shape family (close only or high/low/close). Unsupported specs fall back to the regular registry path, preserving behavior.

Parameters:
Return type:

list[object]