2026-03-23 23:34:28 +05:30
<div align="center">
# ⚡ ferro-ta
### The Python Technical Analysis Library That Beats TA-Lib — Everywhere
**Powered by Rust. Driven by O(n) algorithms. Designed for the speed that modern quantitative trading demands.**
[](https://mybinder.org/v2/gh/pratikbhadane24/ferro-ta/HEAD?labpath=examples%2Fquickstart.ipynb)
[](https://colab.research.google.com/github/pratikbhadane24/ferro-ta/blob/main/examples/quickstart.ipynb)
[](https://pratikbhadane24.github.io/ferro-ta/)
</div>
---
> **"Same API as TA-Lib. 3– 5× faster. No C compiler needed. Drop it in today."**
ferro-ta is a **Rust-powered, PyO3-compiled** technical analysis library that replaces TA-Lib with a pure-Rust core that runs **3× to 5× faster** on every major indicator. It runs as a pre-compiled Python wheel — no C toolchain, no system dependencies, no compilation headaches.
---
## 🚀 Why ferro-ta?
| | TA-Lib | ferro-ta |
|---|---|---|
| **Speed** | C extension, O(n× period) for STOCH/etc. | Rust + O(n) algorithms for most indicators |
| **Installation** | Requires C compiler + system libs | `pip install ferro-ta` — zero deps |
| **Platforms** | Linux-only on many CI systems | Windows / macOS (Intel + M-series) / Linux |
| **API** | `talib.SMA(close, 20)` | `ferro_ta.SMA(close, 20)` — identical |
| **Extra indicators** | — | VWAP, SUPERTREND, ICHIMOKU, DONCHIAN, and 10 more |
| **Streaming API** | — | Bar-by-bar stateful classes |
| **GPU acceleration** | — | Optional PyTorch backend (CUDA / MPS) |
| **WebAssembly** | — | Node.js / Browser via WASM |
| **Type stubs** | — | Full `.pyi` + `py.typed` (PEP 561) |
---
## ⚡ Performance vs TA-Lib
ferro-ta is optimized for high throughput and often competitive with TA-Lib, thanks to:
- **O(n) sliding max/min** (monotonic deque) for STOCH — was O(n× period) in TA-Lib
- **Fused TR loop** for ATR — no intermediate allocation, single pass
- **Branchless gain/loss** for RSI — `diff.max(0.0)` instead of `if/else`
- **O(n) rolling operators** for SMA/WMA/BBANDS — sliding window accumulators
- **Fused fast+slow EMA loop** for MACD — single pass for both EMAs
- **Zero-copy NumPy bridging** — input arrays read directly from buffer without copying
### 🏆 Reproducible benchmark workflow
We publish benchmark methodology and generated tables in [`benchmarks/README.md` ](benchmarks/README.md ).
- Cross-library speed suite (62 indicators × available libraries): `benchmarks/test_speed.py`
- Head-to-head TA-Lib comparison: `benchmarks/bench_vs_talib.py`
- Table generation from `results.json` : `benchmarks/benchmark_table.py`
```bash
# Reproduce these numbers yourself
pip install ferro-ta ta-lib
python benchmarks/bench_vs_talib.py --sizes 10000 100000 --json benchmark_vs_talib.json
# or with uv:
uv run python benchmarks/bench_vs_talib.py --sizes 10000 100000 --json benchmark_vs_talib.json
uv run python benchmarks/check_vs_talib_regression.py --input benchmark_vs_talib.json
# full cross-library speed suite (100k bars):
uv run pytest benchmarks/test_speed.py --benchmark-only --benchmark-json= benchmarks/results.json -v
# generate markdown table from results:
uv run python benchmarks/benchmark_table.py
```
---
## 🎯 Features
- **No C-compiler required** — pre-compiled wheels for Windows, macOS (Intel & Apple Silicon), and Linux
- **Drop-in API** compatible with TA-Lib (`SMA` , `EMA` , `RSI` , `MACD` , `BBANDS` , and 155+ more)
- **Extended Indicators** beyond TA-Lib: `VWAP` , `SUPERTREND` , `ICHIMOKU` , `DONCHIAN` , `PIVOT_POINTS` , `KELTNER_CHANNELS` , `HULL_MA` , `CHANDELIER_EXIT` , `VWMA` , `CHOPPINESS_INDEX`
- **Streaming / Live-Trading API** — bar-by-bar stateful classes (`StreamingSMA` , `StreamingRSI` , etc.)
- **NumPy integration** — accepts and returns NumPy arrays; reads input buffers without copying data
- **Pandas integration** — transparently accepts `pandas.Series` / `DataFrame` and returns `Series` with original index preserved
- **Polars integration** — transparently accepts `polars.Series` and returns `polars.Series` ; install with `pip install "ferro-ta[polars]"`
- **Indicator pipeline** — compose multiple indicators into a reusable pipeline (`ferro_ta.pipeline.Pipeline` )
- **Configuration defaults** — set global parameter defaults, per-indicator overrides, and temporary scopes (`ferro_ta.config` )
- **Optional GPU backend** — pass a PyTorch tensor to `ferro_ta.gpu.sma/ema/rsi` and get a tensor back (CUDA or MPS); install with `pip install "ferro-ta[gpu]"`
- **Type stubs** (`.pyi` ) + `py.typed` (PEP 561) for IDE auto-completion and `mypy` /`pyright` support
- **WebAssembly binding** — use ferro-ta in Node.js or the browser via `wasm/` (SMA, EMA, BBANDS, RSI, ATR, OBV, MACD, MOM, STOCHF)
- **Backtesting utilities** — minimal vectorized backtester (`ferro_ta.backtest` ) with RSI, SMA crossover, and MACD crossover strategies; optional commission and slippage
- **Plugin registry** — register and run custom or built-in indicators by name (`ferro_ta.registry` )
- **Error model** — custom exception hierarchy (`FerroTAError` , `FerroTAValueError` , `FerroTAInputError` ) with input validation helpers
- **Sphinx documentation** in `docs/` and Jupyter notebook examples in `examples/`
- **OHLCV resampling** — time-based and volume-bar resampling, multi-timeframe API (`ferro_ta.resampling` )
- **Tick aggregation** — tick/volume/time bar builders from raw trades (`ferro_ta.aggregation` )
- **Strategy DSL** — expression-based strategy evaluation (`ferro_ta.dsl` )
- **Signal composition** — weighted/rank composite scores and screening (`ferro_ta.signals` )
- **Portfolio analytics** — correlation, volatility, beta, drawdown (`ferro_ta.portfolio` )
- **Cross-asset analytics** — relative strength, spread, Z-score, rolling beta (`ferro_ta.cross_asset` )
- **Feature matrix** — multi-indicator DataFrame for ML pipelines (`ferro_ta.features` )
- **Charting API** — matplotlib and plotly charts with indicator subplots (`ferro_ta.viz` )
- **Data adapters** — pluggable adapter interface with CSV and in-memory implementations (`ferro_ta.adapters` )
2026-03-24 02:41:50 +05:30
- **Derivatives analytics** — IV rank/percentile/z-score, options pricing/Greeks/IV, futures basis/curve/roll, strategy schemas, and multi-leg payoff helpers (`ferro_ta.analysis.*` )
2026-03-23 23:34:28 +05:30
- **Agentic tools** — stable LangChain/agent tool wrappers (`ferro_ta.tools` ), end-to-end workflow orchestrator (`ferro_ta.workflow` )
- **MCP server** — Model Context Protocol server for Cursor/Claude integration; run with `python -m ferro_ta.mcp`
- **Observability / Logging** — `ferro_ta.enable_debug()` , `ferro_ta.log_call()` , `ferro_ta.benchmark()` and `ferro_ta.traced()` decorator for instrumentation
- **API discovery** — `ferro_ta.indicators(category=None)` lists all 160+ indicators with metadata; `ferro_ta.info(func)` returns full parameter docs
- **Structured error codes** — every `FerroTAError` exception now carries a code (`FTERR001` – `FTERR006` ) and an actionable `suggestion` hint
---
## 📦 Installation
```bash
pip install ferro-ta
```
Optional extras:
```bash
pip install "ferro-ta[pandas]" # transparent pandas.Series support
pip install "ferro-ta[polars]" # transparent polars.Series support
pip install "ferro-ta[gpu]" # GPU-accelerated SMA/EMA/RSI via PyTorch (CUDA/MPS)
2026-03-24 02:41:50 +05:30
pip install "ferro-ta[options]" # Derivatives analytics helpers
2026-03-23 23:34:28 +05:30
pip install "ferro-ta[mcp]" # MCP server for Cursor/Claude agent integration
pip install "ferro-ta[all]" # all optional extras (excluding gpu)
```
---
## ⚡ Quick Start
```python
import numpy as np
from ferro_ta import SMA , EMA , RSI , MACD , BBANDS
close = np . array ([ 44.34 , 44.09 , 44.15 , 43.61 , 44.33 , 44.83 , 45.10 , 45.15 ,
43.61 , 44.33 , 44.83 , 45.10 , 45.15 , 43.61 , 44.33 ])
# Simple Moving Average
sma = SMA ( close , timeperiod = 5 )
# Exponential Moving Average
ema = EMA ( close , timeperiod = 5 )
# Relative Strength Index
rsi = RSI ( close , timeperiod = 14 )
# MACD (returns macd_line, signal_line, histogram)
macd_line , signal , histogram = MACD ( close , fastperiod = 12 , slowperiod = 26 , signalperiod = 9 )
# Bollinger Bands (returns upper, middle, lower)
upper , middle , lower = BBANDS ( close , timeperiod = 5 , nbdevup = 2.0 , nbdevdn = 2.0 )
```
2026-03-24 02:41:50 +05:30
## Δ Derivatives Analytics
```python
from ferro_ta.analysis.options import greeks , implied_volatility , option_price
from ferro_ta.analysis.futures import basis , curve_summary
price = option_price ( 100.0 , 100.0 , 0.05 , 1.0 , 0.20 , option_type = "call" , model = "bsm" )
iv = implied_volatility ( price , 100.0 , 100.0 , 0.05 , 1.0 , option_type = "call" , model = "bsm" )
g = greeks ( 100.0 , 100.0 , 0.05 , 1.0 , 0.20 , option_type = "call" , model = "bsm" )
front_basis = basis ( 100.0 , 103.0 )
curve = curve_summary ( 100.0 , [ 0.1 , 0.5 , 1.0 ], [ 101.0 , 102.0 , 104.0 ])
```
The derivatives layer is analytics-only. It includes:
- options pricing under Black-Scholes-Merton and Black-76
- delta, gamma, vega, theta, and rho
- implied volatility inversion and smile metrics
- futures basis, carry, curve, and continuous-roll helpers
- typed strategy schemas and multi-leg payoff/Greeks aggregation
2026-03-23 23:34:28 +05:30
**Migrating from TA-Lib?** Just swap the import — the API is identical:
```python
# Before (TA-Lib)
import talib
sma = talib . SMA ( close , timeperiod = 20 )
rsi = talib . RSI ( close , timeperiod = 14 )
# After (ferro-ta — same call signature, faster result)
import ferro_ta
sma = ferro_ta . SMA ( close , timeperiod = 20 )
rsi = ferro_ta . RSI ( close , timeperiod = 14 )
```
---
## 🛠️ Development Setup
Requires Rust and **Python 3.10– 3.13** (PyO3 supports up to 3.13; for Python 3.14+ use a compatible interpreter or set `PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1` to attempt a build).
```bash
# Create a virtual environment
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
# Install build tool and dependencies
pip install maturin numpy pytest pandas
# Compile and install in editable mode
maturin develop --release
# Run tests
pytest tests/unit/ tests/integration/
# or: uv run pytest tests/unit/ tests/integration/
# Run TA-Lib comparison tests (requires ta-lib package)
pip install "ferro-ta[comparison]" # or: pip install ta-lib
pytest tests/integration/test_vs_talib.py -v
# Build Sphinx documentation (requires sphinx + sphinx-rtd-theme)
pip install "ferro-ta[docs]"
cd docs && make html
# Output: docs/_build/html/index.html
```
---
## 📊 Full TA-Lib Compatibility
ferro-ta covers **100% of TA-Lib's function set** (162+ indicators). The table below shows implementation status and numerical accuracy vs TA-Lib.
**Legend**
| Symbol | Meaning |
|--------|---------|
| ✅ Exact | Values match TA-Lib to floating-point precision |
| ✅ Close | Values match after a short convergence window (EMA-seed difference) |
| ⚠️ Corr | Strong correlation (> 0.95) but not numerically identical (Wilder smoothing seed or algorithm variant) |
| ⚠️ Shape | Same output shape / NaN structure; values differ due to algorithm variant |
| ❌ | Not yet implemented |
### Overlap Studies
| TA-Lib Function | ferro-ta | Accuracy | Notes |
|-----------------|---------|----------|-------|
| `BBANDS` | ✅ | ✅ Exact | Bollinger Bands |
| `DEMA` | ✅ | ✅ Close | Double EMA; converges after ~20 bars |
| `EMA` | ✅ | ✅ Close | Exponential Moving Average; converges after ~20 bars |
| `KAMA` | ✅ | ✅ Exact | Kaufman Adaptive MA (values match after seed bar) |
| `MA` | ✅ | ✅ Exact | Moving average (generic, type-selectable) |
| `MAMA` | ✅ | ⚠️ Corr | MESA Adaptive MA |
| `MAVP` | ✅ | ✅ Exact | MA with variable period |
| `MIDPOINT` | ✅ | ✅ Exact | Midpoint over period |
| `MIDPRICE` | ✅ | ✅ Exact | Midpoint price over period |
| `SAR` | ✅ | ⚠️ Shape | Parabolic SAR (same shape; reversal history diverges) |
| `SAREXT` | ✅ | ⚠️ Shape | Parabolic SAR Extended |
| `SMA` | ✅ | ✅ Exact | Simple Moving Average |
| `T3` | ✅ | ✅ Close | Triple Exponential MA (T3); converges after ~50 bars |
| `TEMA` | ✅ | ✅ Close | Triple EMA; converges after ~20 bars |
| `TRIMA` | ✅ | ✅ Exact | Triangular Moving Average |
| `WMA` | ✅ | ✅ Exact | Weighted Moving Average |
### Momentum Indicators
| TA-Lib Function | ferro-ta | Accuracy | Notes |
|-----------------|---------|----------|-------|
| `ADX` | ✅ | ✅ Close | Avg Directional Movement Index (TA-Lib Wilder sum-seeding) |
| `ADXR` | ✅ | ✅ Close | ADX Rating (inherits ADX; TA-Lib seeding) |
| `APO` | ✅ | ✅ Close | Absolute Price Oscillator (EMA-based) |
| `AROON` | ✅ | ✅ Exact | Aroon Up/Down |
| `AROONOSC` | ✅ | ✅ Exact | Aroon Oscillator |
| `BOP` | ✅ | ✅ Exact | Balance Of Power |
| `CCI` | ✅ | ✅ Exact | Commodity Channel Index (TA-Lib– compatible MAD formula) |
| `CMO` | ✅ | ✅ Close | Chande Momentum Oscillator (rolling window, TA-Lib– compatible) |
| `DX` | ✅ | ✅ Close | Directional Movement Index (TA-Lib Wilder sum-seeding) |
| `MACD` | ✅ | ✅ Close | MACD (EMA-based; converges after ~30 bars) |
| `MACDEXT` | ✅ | ✅ Close | MACD with controllable MA type (EMA-based; converges) |
| `MACDFIX` | ✅ | ✅ Close | MACD Fixed 12/26 (EMA-based; converges) |
| `MFI` | ✅ | ✅ Exact | Money Flow Index |
| `MINUS_DI` | ✅ | ✅ Close | Minus Directional Indicator (TA-Lib Wilder sum-seeding) |
| `MINUS_DM` | ✅ | ✅ Close | Minus Directional Movement (TA-Lib Wilder sum-seeding) |
| `MOM` | ✅ | ✅ Exact | Momentum |
| `PLUS_DI` | ✅ | ✅ Close | Plus Directional Indicator (TA-Lib Wilder sum-seeding) |
| `PLUS_DM` | ✅ | ✅ Close | Plus Directional Movement (TA-Lib Wilder sum-seeding) |
| `PPO` | ✅ | ✅ Close | Percentage Price Oscillator (EMA-based) |
| `ROC` | ✅ | ✅ Exact | Rate of Change |
| `ROCP` | ✅ | ✅ Exact | Rate of Change Percentage |
| `ROCR` | ✅ | ✅ Exact | Rate of Change Ratio |
| `ROCR100` | ✅ | ✅ Exact | Rate of Change Ratio × 100 |
| `RSI` | ✅ | ✅ Close | Relative Strength Index (TA-Lib Wilder seeding; converges after ~1 seed bar) |
| `STOCH` | ✅ | ✅ Close | Stochastic (TA-Lib– compatible SMA smoothing for slowk and slowd) |
| `STOCHF` | ✅ | ✅ Exact | Stochastic Fast (%K exact; %D NaN offset ±2) |
| `STOCHRSI` | ✅ | ✅ Close | Stochastic RSI (TA-Lib– compatible; SMA fastd, Wilder-seeded RSI) |
| `TRIX` | ✅ | ✅ Close | 1-day ROC of Triple EMA (EMA-based; converges) |
| `ULTOSC` | ✅ | ✅ Exact | Ultimate Oscillator |
| `WILLR` | ✅ | ✅ Exact | Williams' %R |
### Volume Indicators
| TA-Lib Function | ferro-ta | Accuracy | Notes |
|-----------------|---------|----------|-------|
| `AD` | ✅ | ✅ Exact | Chaikin A/D Line |
| `ADOSC` | ✅ | ✅ Exact | Chaikin A/D Oscillator |
| `OBV` | ✅ | ✅ Exact | On Balance Volume (increments identical; constant offset at bar 0) |
### Volatility Indicators
| TA-Lib Function | ferro-ta | Accuracy | Notes |
|-----------------|---------|----------|-------|
| `ATR` | ✅ | ✅ Close | Average True Range (TA-Lib Wilder seeding; matches from bar timeperiod) |
| `NATR` | ✅ | ✅ Close | Normalized ATR (TA-Lib Wilder seeding) |
| `TRANGE` | ✅ | ✅ Exact | True Range (bar 0 differs; all others identical) |
### Cycle Indicators
| TA-Lib Function | ferro-ta | Accuracy | Notes |
|-----------------|---------|----------|-------|
| `HT_DCPERIOD` | ✅ | ⚠️ Shape | Hilbert Transform Dominant Cycle Period (Ehlers algorithm) |
| `HT_DCPHASE` | ✅ | ⚠️ Shape | Hilbert Transform Dominant Cycle Phase |
| `HT_PHASOR` | ✅ | ⚠️ Shape | Hilbert Transform Phasor Components (inphase, quadrature) |
| `HT_SINE` | ✅ | ⚠️ Shape | Hilbert Transform SineWave (sine, leadsine) |
| `HT_TRENDLINE` | ✅ | ⚠️ Shape | Hilbert Transform Instantaneous Trendline |
| `HT_TRENDMODE` | ✅ | ⚠️ Shape | Hilbert Transform Trend vs Cycle Mode (1=trend, 0=cycle) |
### Price Transformations
| TA-Lib Function | ferro-ta | Accuracy | Notes |
|-----------------|---------|----------|-------|
| `AVGPRICE` | ✅ | ✅ Exact | Average Price |
| `MEDPRICE` | ✅ | ✅ Exact | Median Price |
| `TYPPRICE` | ✅ | ✅ Exact | Typical Price |
| `WCLPRICE` | ✅ | ✅ Exact | Weighted Close Price |
### Statistic Functions
| TA-Lib Function | ferro-ta | Accuracy | Notes |
|-----------------|---------|----------|-------|
| `BETA` | ✅ | ✅ Close | Beta coefficient (returns-based regression matching TA-Lib) |
| `CORREL` | ✅ | ✅ Exact | Pearson Correlation Coefficient |
| `LINEARREG` | ✅ | ✅ Exact | Linear Regression |
| `LINEARREG_ANGLE` | ✅ | ✅ Exact | Linear Regression Angle |
| `LINEARREG_INTERCEPT` | ✅ | ✅ Exact | Linear Regression Intercept |
| `LINEARREG_SLOPE` | ✅ | ✅ Exact | Linear Regression Slope |
| `STDDEV` | ✅ | ✅ Exact | Standard Deviation |
| `TSF` | ✅ | ✅ Exact | Time Series Forecast |
| `VAR` | ✅ | ✅ Exact | Variance |
### Pattern Recognition
ferro-ta implements all 61 candlestick patterns. All return the same `{-100, 0, 100}`
convention as TA-Lib. Pattern thresholds may differ slightly from the full TA-Lib
implementation.
| TA-Lib Function | ferro-ta | Notes |
|-----------------|---------|-------|
| `CDL2CROWS` | ✅ | Two Crows |
| `CDL3BLACKCROWS` | ✅ | Three Black Crows |
| `CDL3INSIDE` | ✅ | Three Inside Up/Down |
| `CDL3LINESTRIKE` | ✅ | Three-Line Strike |
| `CDL3OUTSIDE` | ✅ | Three Outside Up/Down |
| `CDL3STARSINSOUTH` | ✅ | Three Stars In The South |
| `CDL3WHITESOLDIERS` | ✅ | Three Advancing White Soldiers |
| `CDLABANDONEDBABY` | ✅ | Abandoned Baby |
| `CDLADVANCEBLOCK` | ✅ | Advance Block |
| `CDLBELTHOLD` | ✅ | Belt-hold |
| `CDLBREAKAWAY` | ✅ | Breakaway |
| `CDLCLOSINGMARUBOZU` | ✅ | Closing Marubozu |
| `CDLCONCEALBABYSWALL` | ✅ | Concealing Baby Swallow |
| `CDLCOUNTERATTACK` | ✅ | Counterattack |
| `CDLDARKCLOUDCOVER` | ✅ | Dark Cloud Cover |
| `CDLDOJI` | ✅ | Doji |
| `CDLDOJISTAR` | ✅ | Doji Star |
| `CDLDRAGONFLYDOJI` | ✅ | Dragonfly Doji |
| `CDLENGULFING` | ✅ | Engulfing Pattern |
| `CDLEVENINGDOJISTAR` | ✅ | Evening Doji Star |
| `CDLEVENINGSTAR` | ✅ | Evening Star |
| `CDLGAPSIDESIDEWHITE` | ✅ | Up/Down-gap side-by-side white lines |
| `CDLGRAVESTONEDOJI` | ✅ | Gravestone Doji |
| `CDLHAMMER` | ✅ | Hammer |
| `CDLHANGINGMAN` | ✅ | Hanging Man |
| `CDLHARAMI` | ✅ | Harami Pattern |
| `CDLHARAMICROSS` | ✅ | Harami Cross Pattern |
| `CDLHIGHWAVE` | ✅ | High-Wave Candle |
| `CDLHIKKAKE` | ✅ | Hikkake Pattern |
| `CDLHIKKAKEMOD` | ✅ | Modified Hikkake Pattern |
| `CDLHOMINGPIGEON` | ✅ | Homing Pigeon |
| `CDLIDENTICAL3CROWS` | ✅ | Identical Three Crows |
| `CDLINNECK` | ✅ | In-Neck Pattern |
| `CDLINVERTEDHAMMER` | ✅ | Inverted Hammer |
| `CDLKICKING` | ✅ | Kicking |
| `CDLKICKINGBYLENGTH` | ✅ | Kicking by the longer Marubozu |
| `CDLLADDERBOTTOM` | ✅ | Ladder Bottom |
| `CDLLONGLEGGEDDOJI` | ✅ | Long Legged Doji |
| `CDLLONGLINE` | ✅ | Long Line Candle |
| `CDLMARUBOZU` | ✅ | Marubozu |
| `CDLMATCHINGLOW` | ✅ | Matching Low |
| `CDLMATHOLD` | ✅ | Mat Hold |
| `CDLMORNINGDOJISTAR` | ✅ | Morning Doji Star |
| `CDLMORNINGSTAR` | ✅ | Morning Star |
| `CDLONNECK` | ✅ | On-Neck Pattern |
| `CDLPIERCING` | ✅ | Piercing Pattern |
| `CDLRICKSHAWMAN` | ✅ | Rickshaw Man |
| `CDLRISEFALL3METHODS` | ✅ | Rising/Falling Three Methods |
| `CDLSEPARATINGLINES` | ✅ | Separating Lines |
| `CDLSHOOTINGSTAR` | ✅ | Shooting Star |
| `CDLSHORTLINE` | ✅ | Short Line Candle |
| `CDLSPINNINGTOP` | ✅ | Spinning Top |
| `CDLSTALLEDPATTERN` | ✅ | Stalled Pattern |
| `CDLSTICKSANDWICH` | ✅ | Stick Sandwich |
| `CDLTAKURI` | ✅ | Takuri (Dragonfly Doji with very long lower shadow) |
| `CDLTASUKIGAP` | ✅ | Tasuki Gap |
| `CDLTHRUSTING` | ✅ | Thrusting Pattern |
| `CDLTRISTAR` | ✅ | Tristar Pattern |
| `CDLUNIQUE3RIVER` | ✅ | Unique 3 River |
| `CDLUPSIDEGAP2CROWS` | ✅ | Upside Gap Two Crows |
| `CDLXSIDEGAP3METHODS` | ✅ | Upside/Downside Gap Three Methods |
### Math Operators / Math Transforms
ferro-ta provides TA-Lib– compatible wrappers for all arithmetic and math-transform functions.
Rolling functions (SUM, MAX, MIN) produce NaN for the first `timeperiod - 1` bars.
| TA-Lib Function | ferro-ta | Notes |
|-----------------|---------|-------|
| `ADD` | ✅ | Element-wise addition |
| `SUB` | ✅ | Element-wise subtraction |
| `MULT` | ✅ | Element-wise multiplication |
| `DIV` | ✅ | Element-wise division |
| `SUM` | ✅ | Rolling sum over *timeperiod* |
| `MAX` / `MAXINDEX` | ✅ | Rolling maximum / index |
| `MIN` / `MININDEX` | ✅ | Rolling minimum / index |
| `ACOS` / `ASIN` / `ATAN` | ✅ | Arc trig transforms |
| `CEIL` / `FLOOR` | ✅ | Round up / down |
| `COS` / `SIN` / `TAN` | ✅ | Trig transforms |
| `COSH` / `SINH` / `TANH` | ✅ | Hyperbolic transforms |
| `EXP` / `LN` / `LOG10` | ✅ | Exponential / log transforms |
| `SQRT` | ✅ | Square root |
### Pandas API
**Contract:** All indicators accept `pandas.Series` (or 1-D DataFrame columns) and return
`pandas.Series` — or a **tuple of Series** for multi-output functions like `MACD` , `BBANDS` —
with the **original index preserved** .
**Default OHLCV column names:** When using a DataFrame with OHLCV data, the conventional names
are `open` , `high` , `low` , `close` , `volume` . To use different column names, use the helper
:func:`ferro_ta.utils.get_ohlcv` (or pass Series/arrays extracted from your DataFrame).
**Single Series or tuple of Series:**
```python
import pandas as pd
from ferro_ta import SMA , BBANDS , MACD , CDLDOJI
close = pd . Series ([ 44.34 , 44.09 , 44.15 , 43.61 , 44.33 ], index = pd . date_range ( "2024-01-01" , 5 ))
# Single-output: returns Series
sma = SMA ( close , timeperiod = 3 ) # pd.Series with same index
# Multi-output: returns tuple of Series
upper , mid , lower = BBANDS ( close , timeperiod = 3 ) # all pd.Series
```
**DataFrame with OHLCV columns (configurable names):**
```python
import pandas as pd
from ferro_ta import ATR , RSI
from ferro_ta.utils import get_ohlcv # or: from ferro_ta._utils import get_ohlcv
df = pd . DataFrame ({
"Open" : [ 1 , 2 , 3 ], "High" : [ 1.1 , 2.1 , 3.1 ],
"Low" : [ 0.9 , 1.9 , 2.9 ], "Close" : [ 1.05 , 2.05 , 3.05 ],
}, index = pd . date_range ( "2024-01-01" , periods = 3 , freq = "D" ))
# Extract with default names (open, high, low, close, volume)
o , h , l , c , v = get_ohlcv ( df , open_col = "Open" , high_col = "High" , low_col = "Low" , close_col = "Close" )
atr = ATR ( h , l , c , timeperiod = 2 ) # index preserved
rsi = RSI ( c , timeperiod = 2 ) # index preserved
```
### Extended Indicators
ferro-ta includes popular indicators that go beyond the TA-Lib standard set.
These are available in `ferro_ta.extended` and importable directly from `ferro_ta` .
| Function | ferro-ta | Notes |
|----------|---------|-------|
| `VWAP` | ✅ | Volume Weighted Average Price — cumulative (session) or rolling window |
| `SUPERTREND` | ✅ | ATR-based trend signal; returns (supertrend_line, direction) |
| `ICHIMOKU` | ✅ | Ichimoku Cloud — Tenkan, Kijun, Senkou A/B, Chikou Span |
| `DONCHIAN` | ✅ | Donchian Channels — rolling highest high / lowest low |
| `PIVOT_POINTS` | ✅ | Pivot points — Classic, Fibonacci, Camarilla methods |
| `KELTNER_CHANNELS` | ✅ | EMA ± (ATR × multiplier) bands; returns (upper, middle, lower) |
| `HULL_MA` | ✅ | Hull Moving Average — fast, low-lag WMA-based MA |
| `CHANDELIER_EXIT` | ✅ | ATR-based trailing stop levels; returns (long_exit, short_exit) |
| `VWMA` | ✅ | Volume Weighted Moving Average — rolling sum(close*vol) / sum(vol) |
| `CHOPPINESS_INDEX` | ✅ | Market choppiness/trending strength index (0– 100) |
```python
from ferro_ta import VWAP , SUPERTREND , ICHIMOKU , DONCHIAN , PIVOT_POINTS
from ferro_ta import KELTNER_CHANNELS , HULL_MA , CHANDELIER_EXIT , VWMA , CHOPPINESS_INDEX
import numpy as np
close = np . array ([ 44.34 , 44.09 , 44.15 , 43.61 , 44.33 , 44.83 , 45.10 , 45.15 ])
high = close + 0.5
low = close - 0.5
vol = np . full ( len ( close ), 1_000_000.0 )
# Cumulative / rolling VWAP
vwap = VWAP ( high , low , close , vol )
rolling_vwap = VWAP ( high , low , close , vol , timeperiod = 5 )
# Supertrend (trend line and direction: 1=up, -1=down)
st_line , direction = SUPERTREND ( high , low , close , timeperiod = 7 , multiplier = 3.0 )
# Ichimoku Cloud
tenkan , kijun , senkou_a , senkou_b , chikou = ICHIMOKU ( high , low , close )
# Donchian Channels
dc_upper , dc_mid , dc_lower = DONCHIAN ( high , low , timeperiod = 5 )
# Pivot Points
pivot , r1 , s1 , r2 , s2 = PIVOT_POINTS ( high , low , close , method = "classic" )
# method options: "classic", "fibonacci", "camarilla"
# Keltner Channels
kc_upper , kc_mid , kc_lower = KELTNER_CHANNELS ( high , low , close , timeperiod = 20 , atr_period = 10 )
# Hull Moving Average
hull = HULL_MA ( close , timeperiod = 16 )
# Chandelier Exit
long_exit , short_exit = CHANDELIER_EXIT ( high , low , close , timeperiod = 22 , multiplier = 3.0 )
# Volume Weighted Moving Average
vwma = VWMA ( close , vol , timeperiod = 20 )
# Choppiness Index (100 = choppy, 0 = strong trend)
ci = CHOPPINESS_INDEX ( high , low , close , timeperiod = 14 )
```
### Streaming / Live-Trading API
For real-time / bar-by-bar processing, import classes from `ferro_ta.streaming` .
Each class maintains state internally and returns `NaN` during the warmup window:
```python
from ferro_ta.streaming import StreamingSMA , StreamingEMA , StreamingRSI , StreamingATR
from ferro_ta.streaming import StreamingBBands , StreamingMACD , StreamingStoch
from ferro_ta.streaming import StreamingVWAP , StreamingSupertrend
sma = StreamingSMA ( period = 20 )
rsi = StreamingRSI ( period = 14 )
atr = StreamingATR ( period = 14 )
bb = StreamingBBands ( period = 20 , nbdevup = 2.0 , nbdevdn = 2.0 )
macd = StreamingMACD ( fastperiod = 12 , slowperiod = 26 , signalperiod = 9 )
stoch = StreamingStoch ( fastk_period = 5 , slowk_period = 3 , slowd_period = 3 )
vwap = StreamingVWAP () # reset() at session open
st = StreamingSupertrend ( period = 7 , multiplier = 3.0 )
for bar in live_data_feed :
current_sma = sma . update ( bar . close )
current_rsi = rsi . update ( bar . close )
current_atr = atr . update ( bar . high , bar . low , bar . close )
upper , mid , lower = bb . update ( bar . close )
macd_line , signal , histogram = macd . update ( bar . close )
slowk , slowd = stoch . update ( bar . high , bar . low , bar . close )
current_vwap = vwap . update ( bar . high , bar . low , bar . close , bar . volume )
st_line , trend_dir = st . update ( bar . high , bar . low , bar . close ) # 1=up, -1=down
```
### 📈 Implementation Coverage Summary
| Category | Implemented | Not Implemented |
|----------|:-----------:|:---------------:|
| Overlap Studies | 19 | 0 |
| Momentum Indicators | 28 | 0 |
| Volume Indicators | 3 | 0 |
| Volatility Indicators | 3 | 0 |
| Cycle Indicators | 6 | 0 |
| Price Transforms | 4 | 0 |
| Statistic Functions | 9 | 0 |
| Pattern Recognition | 61 | 0 |
| Math Operators / Transforms | 24 | 0 |
| Extended Indicators | 10 | — |
| Streaming Classes | 9 | — |
| **Total** | **162+** | **0** |
> 🎉 **100% of TA-Lib's function set is implemented.** NaN values are placed at the beginning of each output array for the warmup period.
---
## 🔄 Batch Execution API
Run indicators on multiple price series (symbols) in a single call. Dedicated Rust-backed functions for SMA, EMA, RSI, ATR, STOCH, and ADX; use `batch_apply` for any other indicator.
```python
import numpy as np
from ferro_ta.batch import batch_sma , batch_ema , batch_rsi , batch_atr , batch_stoch , batch_adx , batch_apply
# 100 bars × 5 symbols
close = np . random . rand ( 100 , 5 ) + 50.0
high = close + 0.1
low = close - 0.1
sma_out = batch_sma ( close , timeperiod = 14 ) # (100, 5)
ema_out = batch_ema ( close , timeperiod = 14 ) # (100, 5)
rsi_out = batch_rsi ( close , timeperiod = 14 ) # (100, 5)
atr_out = batch_atr ( high , low , close , timeperiod = 14 )
stoch_k , stoch_d = batch_stoch ( high , low , close )
adx_out = batch_adx ( high , low , close , timeperiod = 14 )
# Any single-series function via batch_apply
from ferro_ta import BBANDS
def bbands_upper ( c , ** kw ):
return BBANDS ( c , ** kw )[ 0 ]
upper = batch_apply ( close , bbands_upper , timeperiod = 20 )
```
---
## 🦀 Pure Rust Core Library
ferro-ta is structured as a Cargo workspace with two crates:
| Crate | Purpose |
|-------|---------|
| `ferro_ta` (root) | PyO3 `#[pyfunction]` wrappers — converts numpy ↔ `&[f64]` ; builds the Python wheel |
| `crates/ferro_ta_core` | Pure Rust indicators — no PyO3/numpy dependency; usable from any Rust project |
```bash
# Build and test the core crate directly
cargo build -p ferro_ta_core
cargo test -p ferro_ta_core
```
```rust
use ferro_ta_core ::overlap ;
let close = vec! [ 1.0 , 2.0 , 3.0 , 4.0 , 5.0 ];
let sma = overlap ::sma ( & close , 3 );
```
### Rust Module Structure
The main `ferro_ta` crate (`src/` ) uses a **consistent directory-based module layout** matching the TA-Lib category structure. Every module is a directory with `mod.rs` declaring sub-modules and a `register()` function; each indicator (or closely related group) lives in its own `.rs` file:
```
src/
├── lib.rs # PyModule entry point — calls each module's register()
├── overlap/ # Overlap Studies (SMA, EMA, BBANDS, MACD, SAR, …)
│ ├── mod.rs
│ ├── sma.rs, ema.rs, wma.rs, dema.rs, tema.rs, trima.rs, kama.rs, t3.rs
│ ├── bbands.rs, macd.rs, macdfix.rs, macdext.rs
│ ├── sar.rs, sarext.rs, mama.rs, midpoint.rs, midprice.rs
│ └── ma_mavp.rs
├── momentum/ # Momentum Indicators (RSI, STOCH, ADX, CCI, …)
│ ├── mod.rs
│ └── rsi.rs, mom.rs, roc.rs, willr.rs, aroon.rs, cci.rs, mfi.rs,
│ bop.rs, stochf.rs, stoch.rs, stochrsi.rs, apo.rs, ppo.rs, cmo.rs,
│ adx.rs, trix.rs, ultosc.rs
├── volatility/ # Volatility Indicators (ATR, NATR, TRANGE)
│ ├── mod.rs
│ ├── common.rs # shared TR computation
│ ├── trange.rs, atr.rs, natr.rs
├── volume/ # Volume Indicators (AD, ADOSC, OBV)
│ ├── mod.rs
│ └── ad.rs, adosc.rs, obv.rs
├── statistic/ # Statistic Functions (STDDEV, VAR, LINEARREG*, BETA, CORREL)
│ ├── mod.rs
│ ├── common.rs # shared linreg() helper
│ └── stddev.rs, var.rs, linearreg.rs, beta.rs, correl.rs
├── price_transform/ # Price Transformations (AVGPRICE, MEDPRICE, TYPPRICE, WCLPRICE)
│ ├── mod.rs
│ └── avgprice.rs, medprice.rs, typprice.rs, wclprice.rs
├── cycle/ # Cycle Indicators (HT_TRENDLINE, HT_DCPERIOD, …)
│ ├── mod.rs
│ ├── common.rs # shared HT core pipeline (compute_ht_core)
│ └── ht_trendline.rs, ht_dcperiod.rs, ht_dcphase.rs,
│ ht_phasor.rs, ht_sine.rs, ht_trendmode.rs
└── pattern/ # Pattern Recognition (CDL2CROWS, CDLDOJI, …)
├── mod.rs
├── common.rs # shared candle utilities
└── cdl*.rs # one file per pattern (61 patterns)
```
This layout makes it easy to add, review, or modify individual indicators in isolation — simply edit or add the relevant `.rs` file and update `mod.rs` .
### Python sub-package layout
The `python/ferro_ta/` package is organized into sub-packages by concern.
Backward-compat stubs at the old flat paths (e.g. `ferro_ta.momentum` ) re-export
from the new locations, so existing code continues to work without changes.
```
python/ferro_ta/
├── __init__.py # top-level re-exports and public API
├── core/ # Exceptions, configuration, registry, logging, raw FFI bindings
├── indicators/ # Technical indicators (momentum, overlap, volatility, volume,
│ # statistic, cycle, pattern, price_transform, math_ops, extended)
├── data/ # Streaming, batch, chunked, resampling, aggregation, adapters
├── analysis/ # Portfolio, backtest, regime, cross_asset, attribution,
2026-03-24 02:41:50 +05:30
│ # signals, features, crypto, options, futures,
│ # options_strategy, derivatives_payoff
2026-03-23 23:34:28 +05:30
├── tools/ # Visualisation, alerting, DSL, pipeline, workflow,
│ # api_info, GPU support
└── mcp/ # Model Context Protocol server
```
## 🌐 Other Languages (WebAssembly / Node.js)
A WebAssembly binding is available in the `wasm/` directory, exposing SMA, EMA, BBANDS,
RSI, ATR, OBV, and MACD for use in Node.js and browsers.
```javascript
// Node.js (after `wasm-pack build --target nodejs --out-dir pkg` in wasm/)
const { sma , rsi , macd } = require ( './wasm/pkg/ferro_ta_wasm.js' );
const close = new Float64Array ([ 44.34 , 44.09 , 44.15 , 43.61 , 44.33 , 44.83 , 45.10 ]);
const smaOut = sma ( close , 3 ); // Float64Array — first 2 values are NaN
const rsiOut = rsi ( close , 5 ); // Float64Array — first 5 values are NaN
// MACD — returns [macd_line, signal_line, histogram] as a js_sys::Array
const [ macdLine , signal , hist ] = macd ( close , 3 , 5 , 2 );
```
See [`wasm/README.md` ](wasm/README.md ) for build instructions, the full list of exposed
functions, and browser usage examples.
---
## 🔥 GPU Acceleration (Optional)
For very large arrays (millions of bars), an optional GPU-accelerated path is available
via [PyTorch ](https://pytorch.org/ ). Pass a `torch.Tensor` on CUDA or MPS and get a tensor back;
NumPy in → NumPy out (CPU fallback).
```bash
pip install "ferro-ta[gpu]"
# or install PyTorch yourself (e.g. with CUDA or MPS support):
# pip install torch
```
```python
import torch
from ferro_ta.gpu import sma , ema , rsi
# Use CUDA or MPS (Apple Silicon)
close_gpu = torch . tensor (
[ 44.34 , 44.09 , 44.15 , 43.61 , 44.33 , 44.83 , 45.10 , 45.15 , 43.61 , 44.33 ],
device = "cuda" , # or device="mps" on Apple Silicon
dtype = torch . float64 ,
)
result = sma ( close_gpu , timeperiod = 5 ) # torch.Tensor on same device
result_cpu = result . cpu () . numpy () # back to NumPy if needed
```
PyTorch tensors in → PyTorch tensors out; NumPy arrays in → NumPy arrays out (CPU).
See [`docs/gpu-backend.md` ](docs/gpu-backend.md ) for supported indicators, limitations,
and benchmark data.
---
## 📉 Backtesting
A minimal vectorized backtester is available at `ferro_ta.backtest` :
```python
import numpy as np
from ferro_ta.backtest import backtest
np . random . seed ( 42 )
close = np . cumprod ( 1 + np . random . randn ( 200 ) * 0.01 ) * 100
# Run an RSI 30/70 strategy
result = backtest ( close , strategy = "rsi_30_70" , timeperiod = 14 )
print ( f "Final equity: { result . final_equity : .4f } " )
print ( f "Number of trades: { result . n_trades } " )
# Or use SMA crossover
result2 = backtest ( close , strategy = "sma_crossover" , fast = 10 , slow = 30 )
result3 = backtest ( close , strategy = "macd_crossover" , commission_per_trade = 0.001 , slippage_bps = 5 )
```
> **Note:** This is a *minimal harness* for testing strategies. Optional `commission_per_trade` and `slippage_bps` are supported; for margin or full order types consider `backtrader`, `zipline`, or `vectorbt`.
> For production use consider `backtrader`, `zipline`, or `vectorbt`.
---
## 🔗 Indicator Pipeline
Compose multiple indicators into a reusable pipeline:
```python
import numpy as np
from ferro_ta import SMA , EMA , RSI , BBANDS
from ferro_ta.pipeline import Pipeline
close = np . cumprod ( 1 + np . random . randn ( 200 ) * 0.01 ) * 100
pipe = (
Pipeline ()
. add ( "sma_20" , SMA , timeperiod = 20 )
. add ( "ema_20" , EMA , timeperiod = 20 )
. add ( "rsi_14" , RSI , timeperiod = 14 )
. add ( "bb" , BBANDS , output_keys = [ "bb_upper" , "bb_mid" , "bb_lower" ],
timeperiod = 20 , nbdevup = 2.0 , nbdevdn = 2.0 )
)
results = pipe . run ( close )
# {'sma_20': array([...]), 'ema_20': array([...]), ..., 'bb_lower': array([...])}
print ( list ( results . keys ()))
```
---
## ⚙️ Configuration Defaults
Set global parameter defaults to avoid repeating them on every call:
```python
import ferro_ta.config as config
config . set_default ( "timeperiod" , 20 ) # applies to all indicators
config . set_default ( "RSI.timeperiod" , 14 ) # RSI-specific override
from ferro_ta import RSI , SMA
# RSI(close) uses timeperiod=14; SMA(close) uses timeperiod=20
# Context manager for temporary overrides
with config . Config ( timeperiod = 5 ):
result = SMA ( close ) # timeperiod=5 inside this block
# back to timeperiod=20 after the block
config . reset () # clear all custom defaults
```
---
## 🔌 Plugin Registry
Register and call any indicator (built-in or custom) by name. See the
`Writing a plugin <docs/plugins.rst>` _ doc for the plugin contract and a full example
(``examples/custom_indicator.py``).
` ``python
import numpy as np
from ferro_ta.registry import register, run, list_indicators
# Call a built-in by name
close = np.array([44.34, 44.09, 44.15, 43.61, 44.33, 44.83, 45.10])
sma = run("SMA", close, timeperiod=3)
# Register a custom indicator
def DOUBLE_RSI(close, timeperiod=14, smooth=3):
import ferro_ta
rsi = ferro_ta.RSI(close, timeperiod=timeperiod)
return ferro_ta.SMA(rsi, timeperiod=smooth)
register("DOUBLE_RSI", DOUBLE_RSI)
result = run("DOUBLE_RSI", close, timeperiod=5, smooth=2)
# List all registered indicators
print(list_indicators()[:5]) # ['AD', 'ADOSC', 'ADX', 'ADXR', 'APO']
` ``
---
## 🛡️ Error Handling
ferro-ta provides a typed exception hierarchy with **error codes** and **actionable suggestions**:
` ``python
from ferro_ta import FerroTAError, FerroTAValueError, FerroTAInputError
from ferro_ta.exceptions import check_timeperiod, check_equal_length
# Catch any ferro-ta error
try:
result = SMA(close, timeperiod=0)
except FerroTAValueError as e:
print(e.code) # "FTERR001"
print(e.suggestion) # "Set timeperiod=1 or higher."
print(e) # "[FTERR001] timeperiod must be >= 1, got 0\n Suggestion: ..."
# Validate inputs before calling
check_equal_length(open=open_, close=close) # raises FerroTAInputError (FTERR004) on mismatch
check_timeperiod(timeperiod) # raises FerroTAValueError (FTERR001) if < 1
` ``
Error code reference:
| Code | Exception | Meaning |
|------|-----------|---------|
| ` FTERR001` | ` FerroTAValueError` | Invalid parameter value |
| ` FTERR002` | ` FerroTAInputError` | Invalid input array |
| ` FTERR003` | ` FerroTAInputError` | Input array too short |
| ` FTERR004` | ` FerroTAInputError` | Mismatched array lengths |
| ` FTERR005` | ` FerroTAInputError` | Array contains NaN/Inf (strict mode) |
| ` FTERR006` | ` FerroTAValueError/InputError` | Rust-bridge error |
## 🔍 Observability & Logging
ferro-ta ships a lightweight logging module that integrates with Python's standard ` logging` library:
` ``python
import ferro_ta
# Enable DEBUG-level logging (writes to stderr)
ferro_ta.enable_debug()
result = ferro_ta.SMA(close, timeperiod=20)
# DEBUG [ferro_ta] calling SMA(ndarray(252,) dtype=float64, timeperiod=20)
# DEBUG [ferro_ta] SMA → ndarray(252,) [0.042 ms]
ferro_ta.disable_debug()
# Context manager: temporary debug output
with ferro_ta.debug_mode():
ferro_ta.RSI(close, timeperiod=14)
# Call with automatic shape + timing log
result = ferro_ta.log_call(ferro_ta.ATR, high, low, close, timeperiod=14)
# Benchmark: returns {mean_ms, min_ms, max_ms, total_ms, n}
stats = ferro_ta.benchmark(ferro_ta.SMA, close, timeperiod=20, n=500)
print(f"SMA mean: {stats['mean_ms']:.3f} ms")
# Decorator: wrap any function with automatic logging
@ferro_ta.traced
def my_strategy(close):
sma = ferro_ta.SMA(close, timeperiod=20)
rsi = ferro_ta.RSI(close, timeperiod=14)
return sma, rsi
` ``
## 🔎 API Discovery
` ``python
import ferro_ta
# List all 160+ indicators with metadata
all_indicators = ferro_ta.indicators()
print(len(all_indicators)) # 160+
# Filter by category
overlap = ferro_ta.indicators(category="overlap")
momentum = ferro_ta.indicators(category="momentum")
# Get parameter info for any indicator
d = ferro_ta.info(ferro_ta.SMA)
print(d["signature"]) # (close: ArrayLike, timeperiod: int = 30) -> NDArray[float64]
print(d["params"]) # {"close": {"default": None, ...}, "timeperiod": {"default": 30, ...}}
# By name string
d = ferro_ta.info("MACD")
` ``
See [` PLATFORMS.md`](PLATFORMS.md) for supported OS and Python versions.
See [` CHANGELOG.md`](CHANGELOG.md) and [` VERSIONING.md`](VERSIONING.md) for release notes and versioning policy.
See [` RELEASE.md`](RELEASE.md) for the step-by-step release playbook.
See [` examples/`](examples/) for Jupyter notebook examples (quickstart, streaming, backtesting, and more).
## 🗺️ Multi-Timeframe, Portfolio, and ML Features
### OHLCV Resampling and Multi-Timeframe API (` ferro_ta.resampling`)
` ``python
from ferro_ta.resampling import resample, volume_bars, multi_timeframe
from ferro_ta import RSI
import pandas as pd
# Resample 1-minute data to 5-minute bars (requires pandas)
df5 = resample(ohlcv_df, '5min')
# Volume bars (every 10,000 units of volume) — Rust backend
vbars = volume_bars(ohlcv_df, volume_threshold=10_000)
# Multi-timeframe RSI in one call
mtf = multi_timeframe(ohlcv_df, ['5min', '15min'], indicator=RSI,
indicator_kwargs={'timeperiod': 14})
# mtf = {'5min': array(...), '15min': array(...)}
` ``
### Tick Aggregation Pipeline (` ferro_ta.aggregation`)
` ``python
from ferro_ta.aggregation import aggregate_ticks, TickAggregator
# Tick bars, volume bars, time bars — all Rust-backed
tick_bars = aggregate_ticks(ticks, rule='tick:100')
volume_bars = aggregate_ticks(ticks, rule='volume:500')
time_bars = aggregate_ticks(ticks, rule='time:60')
# Class-based API
agg = TickAggregator(rule='tick:100')
bars = agg.aggregate(ticks) # → pandas DataFrame or dict
` ``
### Strategy Expression DSL (` ferro_ta.dsl`)
` ``python
from ferro_ta.dsl import Strategy, evaluate
# Parse and evaluate expression strings
strat = Strategy("RSI(14) < 30 and close > SMA(20)")
signal = strat.evaluate({"close": close_arr}) # 1/0 integer array
` ``
### Signal Composition and Screening (` ferro_ta.signals`)
` ``python
from ferro_ta.signals import compose, screen, rank_signals
# Weighted combination of signal columns (Rust-backed)
score = compose(signals_df, weights=[0.4, 0.35, 0.25])
# Screening
top2 = screen({'AAPL': 0.8, 'MSFT': 0.9, 'GOOG': 0.5}, top_n=2)
# {'MSFT': 0.9, 'AAPL': 0.8}
` ``
### Portfolio Analytics (` ferro_ta.portfolio`)
` ``python
from ferro_ta.portfolio import correlation_matrix, portfolio_volatility, beta, drawdown
corr = correlation_matrix(returns_df) # Pearson corr matrix
vol = portfolio_volatility(returns_df, weights, # sqrt(w'Σw)
annualise=252)
b = beta(asset_returns, benchmark_returns) # OLS beta
rb = beta(asset_returns, benchmark_returns, # rolling beta
window=30)
dd, mx = drawdown(equity_curve) # drawdown series + max
` ``
### Cross-Asset Relative Strength (` ferro_ta.cross_asset`)
` ``python
from ferro_ta.cross_asset import relative_strength, spread, ratio, zscore, rolling_beta
rs = relative_strength(asset_rets, bench_rets) # cumulative return ratio
sp = spread(price_a, price_b, hedge=1.0) # A - hedge * B
z = zscore(sp, window=20) # rolling Z-score
` ``
### Feature Matrix for ML (` ferro_ta.features`)
` ``python
from ferro_ta.features import feature_matrix
fm = feature_matrix(ohlcv, [
('RSI', {'timeperiod': 14}),
('SMA', {'timeperiod': 20}),
('ATR', {'timeperiod': 14}),
], nan_policy='drop')
# fm is a pandas DataFrame with one column per indicator
# Use with sklearn: clf.fit(fm.values, labels)
` ``
### Charting and Visualization (` ferro_ta.viz`)
` ``python
from ferro_ta.viz import plot
from ferro_ta import RSI, SMA
fig = plot(ohlcv_df, indicators={'RSI(14)': RSI(close), 'SMA(20)': SMA(close)},
backend='matplotlib', savefig='chart.png')
# Also supports 'plotly' backend for interactive charts
` ``
### Market Data Adapters (` ferro_ta.adapters`)
` ``python
from ferro_ta.adapters import CsvAdapter, InMemoryAdapter, register_adapter, DataAdapter
# Load from CSV
adapter = CsvAdapter('data.csv', index_col='date')
ohlcv = adapter.fetch()
# Custom adapter
class MyAdapter(DataAdapter):
def fetch(self, **kwargs): return ...
register_adapter('mybroker', MyAdapter)
` ``
---
## 🤝 Community
[](https://github.com/pratikbhadane24/ferro-ta/discussions)
- **GitHub Discussions** — Ask questions, share strategies, and request features in our [Discussions](https://github.com/pratikbhadane24/ferro-ta/discussions) space. Categories: **Q&A**, **Ideas**, **Show & Tell**, **Announcements**.
- **Contributing**: See [` CONTRIBUTING.md`](CONTRIBUTING.md) for setup, code style, and PR guidelines.
- **Code of Conduct**: All participants are expected to follow the [` CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md).
- **Governance**: Decision-making process and maintainer info in [` GOVERNANCE.md`](GOVERNANCE.md).
- **Roadmap**: Development plan in [` ROADMAP.md`](ROADMAP.md).
- **Security**: Responsible disclosure policy in [` SECURITY.md`](SECURITY.md).
- **Migration from TA-Lib**: Step-by-step guide in the [documentation ](docs/migration_talib.rst ).
- **Library Compatibility Guides** — drop-in migration instructions and cross-library test results:
- [TA-Lib compatibility ](docs/compatibility/talib.md ) — full indicator mapping, API differences, and migration guide
- [pandas-ta compatibility ](docs/compatibility/pandas_ta.md ) — indicator mapping, known differences, and comparison tests
- [ta (Bukosabino) compatibility ](docs/compatibility/ta.md ) — indicator mapping, known differences, and comparison tests
- [Tulipy compatibility ](docs/compatibility/tulipy.md ) — C99 Tulip Indicators: output truncation, memory requirements, signature mapping
- [finta compatibility ](docs/compatibility/finta.md ) — pure-Pandas library: DataFrame requirements, speed comparison, migration guide
- **Cross-Library Benchmarks** — accuracy and speed comparison across all 6 libraries:
- [Benchmarks README ](benchmarks/README.md ) — real timing results (µs), accuracy methodology, and known limitations
- [Performance Roadmap ](PERFORMANCE_ROADMAP.md ) — plan to achieve 100x speedup over Tulipy
---
<div align="center">
**ferro-ta** — Built with ❤️ and Rust. [Star ⭐ on GitHub ](https://github.com/pratikbhadane24/ferro-ta ) to support the project.
</div>