* feat: broaden CPU and platform coverage across PyPI, nodes, and crates.io Replace static SIMD with runtime CPU-feature dispatch and expand the release wheel matrix so one set of artifacts runs on any target CPU and platform without illegal-instruction crashes. Rust core: - Add multiversion runtime dispatch (crates/ferro_ta_core/src/simd.rs); drop compile-time `wide`. `simd` feature is now default-on and forwarded through the pyo3 crate, and stays compatible with #![forbid(unsafe_code)]. Packaging: - abi3-py310: one cp310-abi3 wheel per platform (covers CPython 3.10+). - CI matrix adds Linux aarch64 + musllinux (x86_64/aarch64) and Windows arm64. Node/Docker + docs: - api/Dockerfile: document baseline+dispatch (no target-cpu pin) and add a fail-fast import check; aarch64 containers now install cleanly. - Rewrite docs/guides/simd.md; fix stale `wide` mention in ADR 0003. - Add ADR 0006 (CPU coverage strategy). Also bundles in-flight release prep already staged in the tree (DTW exception types, SBOM/provenance security, supporting docs). * fix(ci): clear cargo-deny and pip-audit failures; apply dependency bumps cargo-deny (advisories): - Ignore pyo3 RUSTSEC-2026-0176 / RUSTSEC-2026-0177 in deny.toml with a documented rationale: ferro-ta uses neither affected code path (PyList/PyTuple nth iterators; PyCFunction::new_closure). Upstream fix needs pyo3 >=0.29 (large API migration), tracked as a follow-up. pip-audit: - Bump dev lockfile idna 3.18, pytest 9.1.1, urllib3 2.7.0 to clear PYSEC-2026-215, CVE-2025-71176, PYSEC-2026-141/142. Dependency bumps (supersede open dependabot PRs; they auto-close on merge): - cargo: log 0.4.32, serde_json 1.0.150, rayon 1.12.0 - api/requirements.txt: uvicorn>=0.49.0, pydantic>=2.13.4, ferro-ta>=1.1.4 - CI actions: deploy-pages v5, upload-pages-artifact v5, action-gh-release v3 The open `wide` 1.5.0 bump (PR #24) is obsolete — the crate is removed in this branch. * chore: address CodeRabbit review; remove docs/adr section CodeRabbit findings: - CI sbom job: add `attestations: write` so attest-build-provenance can run (it had only contents:write + id-token:write). - simd.rs: vectorize `wma_seed` with lane-local accumulators — it was scalar behind the multiversion wrapper, adding dispatch overhead for no SIMD gain. - CHANGELOG: consolidate the duplicate `### Changed` heading. - python/ferro_ta/__init__.py: also re-export the `FerroTaError` alias. - docs/guides/dtw.md: soften "byte-for-byte" parity to within-tolerance. Remove docs/adr/ at maintainer request and clean up the ADR links in the SIMD and DTW guides. The ADR files remain in commit 9506a30 if ever needed.
⚡ ferro-ta
Rust-powered Python technical analysis with a TA-Lib-compatible API
Focused on one primary job: fast, reproducible technical analysis for Python users who want TA-Lib-style ergonomics without native build friction.
ferro-tais a Rust-backed Python technical analysis library for NumPy-first workloads. It keeps TA-Lib-style ergonomics, ships pre-built wheels on supported targets, and publishes reproducible benchmark artifacts instead of blanket speed claims.
🚀 What ferro-ta is
| TA-Lib | ferro-ta | |
|---|---|---|
| Primary product | C-backed Python TA library | Rust-backed Python TA library |
| API shape | talib.SMA(close, 20) |
ferro_ta.SMA(close, 20) |
| Installation | Often requires native/system setup | Pre-built wheels on supported targets |
| Scope | Technical indicators | Technical indicators first; other tooling is optional and secondary |
⚡ Benchmark evidence
The latest checked-in TA-Lib comparison artifact uses contiguous float64
arrays at 10k and 100k bars on an Apple M3 Max, CPython 3.13.5, and Rust 1.91.1.
ferro-taachieves competitive parity with TA-Lib, winning on 7 of 12 tested indicators at 100k bars (5 of 12 at 10k bars).- Strong performance wins at 100k bars include
MFI(3.25×),WMA(2.20×),BBANDS(1.97×), andSMA(1.93×) vs TA-Lib. - TA-Lib maintains performance advantages on
STOCHandADX;EMA,ATR, andOBVare statistical ties. - Compared to pure-Python libraries like Tulipy,
ferro-taprovides 150-350x speedups through Rust-optimized implementations.
See the benchmark methodology and artifacts:
🎯 Core capabilities
- 160+ indicators with a TA-Lib-style public API.
- Batch and streaming APIs for multi-series and bar-by-bar workloads.
- NumPy-first execution with pandas and polars adapters.
- Pre-built wheels on the supported Python and OS matrix.
- Type stubs, error codes, examples, and reproducible benchmarks.
Adjacent and experimental surfaces such as derivatives analytics, MCP, GPU, plugins, and WASM remain opt-in and secondary to the core TA library story.
📦 Installation
pip install ferro-ta
Optional extras:
pip install "ferro-ta[pandas]" # pandas.Series support
pip install "ferro-ta[polars]" # polars.Series support
pip install "ferro-ta[gpu]" # PyTorch-backed GPU helpers
pip install "ferro-ta[options]" # derivatives analytics helpers
pip install "ferro-ta[mcp]" # MCP server for agent/tool clients
pip install "ferro-ta[all]" # most optional extras (excluding gpu)
⚡ Quick start
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])
sma = SMA(close, timeperiod=5)
ema = EMA(close, timeperiod=5)
rsi = RSI(close, timeperiod=14)
macd_line, signal, histogram = MACD(close, fastperiod=12, slowperiod=26, signalperiod=9)
upper, middle, lower = BBANDS(close, timeperiod=5, nbdevup=2.0, nbdevdn=2.0)
📊 TA-Lib compatibility
ferro-taimplements 100% of TA-Lib's function set (162+indicators).- Most functions are marked
ExactorClose; the remaining notable non-exact categories are the Hilbert cycle indicators plusMAMA,SAR, andSAREXT. - The full parity matrix and coverage summary now live in TA_LIB_COMPATIBILITY.md.
Migration and compatibility references:
🗺️ Docs map
Core guides:
Evidence and APIs:
Optional and experimental surfaces:
Project and release docs:
🛠️ Development
uv sync --extra dev
uv run pytest tests/unit tests/integration
uv run maturin build --release --out dist
More setup details live in CONTRIBUTING.md.