554 lines
32 KiB
Markdown
554 lines
32 KiB
Markdown
# Changelog
|
||
|
||
All notable changes to **ferro-ta** are documented in this file.
|
||
|
||
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||
and the project uses [Semantic Versioning](https://semver.org/).
|
||
|
||
---
|
||
|
||
## [Unreleased]
|
||
|
||
## [1.2.0] — 2026-06-29
|
||
|
||
### Added
|
||
|
||
- **Runtime CPU-feature dispatch** for SIMD hot paths via the `multiversion`
|
||
crate (`ferro_ta_core/src/simd.rs`). One binary now selects baseline /
|
||
AVX2-FMA / AVX-512 / NEON kernels at load time via CPUID instead of being
|
||
pinned at build time, so it runs on any CPU of the target architecture with
|
||
no illegal-instruction crashes on older chips. The `simd` feature is on by
|
||
default; `--no-default-features` gives a pure-scalar build.
|
||
- **Broader wheel coverage**: release builds now also produce Linux `aarch64`
|
||
(manylinux) and `musllinux` (x86_64 + aarch64) wheels and a Windows `arm64`
|
||
wheel, alongside the existing Linux x86_64, macOS universal2, and Windows
|
||
x64 wheels.
|
||
- **abi3 wheels** (`cp310-abi3`): a single stable-ABI wheel per platform now
|
||
covers CPython 3.10+ (including future 3.14+), replacing the per-version
|
||
wheel matrix.
|
||
- **Dynamic Time Warping** (`DTW`, `DTW_DISTANCE`, `BATCH_DTW`): Euclidean-cost
|
||
DTW with optional Sakoe-Chiba band (`window=` parameter). `DTW()` returns
|
||
`(distance, path)` with the optimal warping path as an `(N, 2)` index array;
|
||
`DTW_DISTANCE()` is the faster distance-only variant; `BATCH_DTW()` computes
|
||
distances from each row of a 2-D matrix to a reference series in parallel
|
||
via rayon. Distance convention matches `dtaidistance.dtw.distance()`.
|
||
- **Indicator-specific exception types** (`FerroTaError`, `InvalidPeriodError`,
|
||
`InsufficientDataError`, `LengthMismatchError`, `NumericConvergenceError`,
|
||
`InvalidInputError`): finer-grained errors for catching specific failure
|
||
modes. All subclass `ValueError` so existing `except ValueError` code keeps
|
||
working (backward compatible).
|
||
|
||
### Changed
|
||
|
||
- **SIMD is now enabled by default and runtime-dispatched.** Replaced the
|
||
compile-time `wide` crate (which was never actually enabled in published
|
||
wheels) with `multiversion`. The `wide` Cargo feature is removed; use the
|
||
default `simd` feature instead.
|
||
- **Dependency bumps.** Rust: `log` 0.4.32, `serde_json` 1.0.150,
|
||
`rayon` 1.12.0. API service (`api/requirements.txt`): `uvicorn>=0.49.0`,
|
||
`pydantic>=2.13.4`, `ferro-ta>=1.1.4`. CI actions: `actions/deploy-pages` v5,
|
||
`actions/upload-pages-artifact` v5, `softprops/action-gh-release` v3.
|
||
- Python coverage threshold raised from 65% to 80% and enforced in CI.
|
||
|
||
### Fixed
|
||
|
||
- **aarch64 Linux containers can now install ferro-ta.** Previously no Linux
|
||
`aarch64` wheel was published, so arm64 images (e.g. AWS Graviton) fell back
|
||
to an sdist build that failed without a Rust toolchain. A manylinux/musllinux
|
||
aarch64 wheel is now published.
|
||
- Published wheels now actually ship SIMD-accelerated kernels; the prior build
|
||
enabled no SIMD feature at all.
|
||
|
||
### Security
|
||
|
||
- **SLSA build provenance** attestations are now generated for every PyPI
|
||
wheel and sdist via `actions/attest-build-provenance`. Verify with
|
||
`gh attestation verify <wheel>`.
|
||
- **Sigstore keyless signatures** are now published alongside both
|
||
CycloneDX/SPDX SBOMs on every GitHub Release (`.sig` + `.pem` files).
|
||
- `ferro_ta_core` crate now declares `#![forbid(unsafe_code)]` to prevent
|
||
regression — the pure-logic layer has no unsafe code and never will.
|
||
- Dependabot now covers the WASM npm package in addition to pip, cargo,
|
||
and GitHub Actions.
|
||
- **pip-audit fixes**: bumped dev lockfile deps `idna` 3.18, `pytest` 9.1.1,
|
||
and `urllib3` 2.7.0 to clear PYSEC-2026-215, CVE-2025-71176, and
|
||
PYSEC-2026-141/142.
|
||
- **pyo3 advisories triaged**: RUSTSEC-2026-0176 and RUSTSEC-2026-0177 are
|
||
ignored in `deny.toml` with rationale — ferro-ta uses neither affected code
|
||
path (PyList/PyTuple `nth` iterators; `PyCFunction::new_closure`). The
|
||
upstream fix requires pyo3 >=0.29 (a large API migration), tracked for a
|
||
follow-up.
|
||
|
||
## [1.1.3] — 2026-04-02
|
||
|
||
### Added
|
||
|
||
- **Stock instrument** (`instrument="stock"`) in `PayoffLeg` and `StrategyLeg`
|
||
for modelling equity-holding strategies (Covered Call, Protective Put, Collar,
|
||
Covered Strangle, Stock + Spread). Linear payoff identical to futures.
|
||
Exposed in all three layers: Rust core, Python, and WASM.
|
||
- **Extended Greeks** (`extended_greeks`): closed-form vanna (∂Δ/∂σ), volga
|
||
(∂²V/∂σ²), charm (∂Δ/∂t), speed (∂Γ/∂S), and color (∂Γ/∂t) for BSM.
|
||
Batch vectorisation supported.
|
||
- **Digital options** (`digital_option_price`, `digital_option_greeks`):
|
||
cash-or-nothing and asset-or-nothing pricing (BSM closed-form) plus
|
||
numerical delta / gamma / vega. Scalar and batch variants.
|
||
- **American options** (`american_option_price`, `early_exercise_premium`):
|
||
Barone-Adesi-Whaley (1987) quadratic approximation — O(1) per evaluation.
|
||
Scalar and batch variants.
|
||
- **Historical volatility estimators** (all rolling, annualised): close-to-close,
|
||
Parkinson, Garman-Klass, Rogers-Satchell, Yang-Zhang. Yang-Zhang is
|
||
~14× more efficient than close-to-close and handles overnight gaps.
|
||
- **Volatility cone** (`vol_cone`): min / p25 / median / p75 / max distribution
|
||
of realised vol across user-specified window lengths — contextualises current
|
||
IV against historical norms.
|
||
- **`strategy_value`**: pre-expiry BSM mid-price value of a multi-leg strategy
|
||
over a spot grid (time value included), complementing `strategy_payoff`
|
||
(expiry intrinsic).
|
||
- **`expected_move`**: log-normal ±1σ expected price range over N days.
|
||
- **`put_call_parity_deviation`**: detects stale quotes or data errors by
|
||
computing C − P − (S·e^{−qT} − K·e^{−rT}).
|
||
- All new analytics exposed to **WASM** (`wasm/src/lib.rs`):
|
||
`extended_greeks`, `digital_price`, `digital_greeks`, `american_price`,
|
||
`early_exercise_premium`, `close_to_close_vol`, `parkinson_vol`,
|
||
`garman_klass_vol`, `rogers_satchell_vol`, `yang_zhang_vol`, `vol_cone`,
|
||
`expected_move`, `put_call_parity_deviation`, `strategy_payoff_dense`,
|
||
`aggregate_greeks_dense`, `strategy_value_grid`.
|
||
- `aggregate_greeks_dense` added to `ferro_ta_core::options::payoff` (pure
|
||
Rust, no PyO3/numpy dependency) enabling WASM reuse.
|
||
- Comprehensive docstrings (NumPy style with Parameters / Returns / Notes /
|
||
Examples) on all new Python functions.
|
||
- Accuracy test suite `tests/unit/test_derivatives_accuracy.py` validates
|
||
digital options, extended Greeks, American options, and vol estimators
|
||
against scipy and analytical reference formulas.
|
||
- scipy added to `dev` optional dependencies for reference testing.
|
||
|
||
### Changed
|
||
|
||
- `StrategyLeg.expiry_selector`, `StrategyLeg.strike_selector`, and
|
||
`StrategyLeg.option_type` are now `Optional` (None allowed for stock legs).
|
||
Existing option legs are unaffected.
|
||
- `docs/derivatives-analytics.md` rewritten to cover all new features with
|
||
runnable examples and an efficiency comparison table for vol estimators.
|
||
|
||
## [1.1.2] — 2026-04-01
|
||
|
||
### Changed
|
||
|
||
- WASM npm package now ships both Node.js (CommonJS) and browser/web worker
|
||
(ESM) builds via conditional exports in package.json.
|
||
- Fixed wasm-publish.yml: added job condition, workflow_dispatch inputs, and
|
||
pre-publish test gate.
|
||
- Fixed CI.yml: SBOM job now waits for both PyPI and crates.io publish.
|
||
- Aligned Node.js version to 20 across all CI workflows.
|
||
- Rewrote wasm/README.md and ferro_ta_core/README.md to reflect full feature
|
||
parity (200+ WASM exports, 22 core modules).
|
||
|
||
## [1.1.1] — 2026-04-01
|
||
|
||
### Added
|
||
|
||
- Full feature parity across Rust core, Python, and WASM targets.
|
||
- 56 new pure-Rust indicator functions in ferro_ta_core: ROC/ROCP/ROCR/ROCR100,
|
||
WILLR, AROON/AROONOSC, CCI, BOP, STOCHRSI, APO, PPO, CMO, TRIX, ULTOSC,
|
||
DEMA, TEMA, TRIMA, KAMA, T3, SAR, SAREXT, MAMA, MIDPOINT, MIDPRICE,
|
||
MACDFIX, MACDEXT, MA (generic dispatcher), MAVP, VAR, LINEARREG variants,
|
||
TSF, BETA, CORREL, NATR, and 19 math operators/transforms.
|
||
- 120+ new WASM bindings: all 61 candlestick patterns (via macro), 9 streaming
|
||
API structs, options pricing/greeks/IV/chain/surface, futures basis/roll/curve/
|
||
synthetic, backtest engine (close-only + OHLCV), walk-forward analysis,
|
||
Monte Carlo bootstrap, performance metrics, batch operations, portfolio
|
||
analytics, and signal utilities.
|
||
- `workflow_dispatch` trigger added to `wasm-publish.yml` for manual npm
|
||
publishing.
|
||
|
||
## [1.0.6] — 2026-03-24
|
||
|
||
### Added
|
||
|
||
- Added a repo-managed pre-push gate that mirrors the core local CI and
|
||
release checks, including version and changelog validation, Rust formatting
|
||
and clippy, Python linting and type checks, tests, docs, and the WASM smoke
|
||
suite.
|
||
- Added generated API manifest tooling and CI coverage so Python and WASM
|
||
export drift is detected before release candidates are pushed.
|
||
- Expanded the Rust-backed implementation surface for analysis and data-heavy
|
||
workflows, including backtest signal generation, portfolio loops, payoff and
|
||
Greeks aggregation, chunked indicator execution, and related helper paths.
|
||
- Expanded the WASM package surface with additional indicator exports such as
|
||
`WMA`, `ADX`, and `MFI`, along with refreshed Node examples and conformance
|
||
coverage against the Python package.
|
||
|
||
### Changed
|
||
|
||
- Refreshed benchmark wrappers, perf-contract artifacts, and benchmark
|
||
comparison helpers so the checked-in performance evidence stays aligned with
|
||
the current feature set.
|
||
- Hardened Python CI and local tooling so they run the same typecheck and test
|
||
entrypoints, including installing the optional MCP dependency needed by the
|
||
MCP server tests.
|
||
- Updated local pre-commit integration to match the current Ruff
|
||
configuration and refreshed locked dependencies to pick up the audited
|
||
PyJWT security fix.
|
||
|
||
### Fixed
|
||
|
||
- One-off benchmark output files produced in the repository root are now
|
||
ignored so local benchmarking no longer dirties the repo by default.
|
||
- Tightened API typing and MCP helper behavior so the stricter lint and
|
||
typecheck pipeline passes consistently before release.
|
||
|
||
## [1.0.4] — 2026-03-24
|
||
|
||
### Added
|
||
|
||
- The optional MCP server now exposes the broad public ferro-ta callable
|
||
surface, including exact top-level exports, non-top-level public analysis and
|
||
tooling functions, and generic stored-instance tools for stateful classes and
|
||
returned callables.
|
||
- Added a dedicated `TA_LIB_COMPATIBILITY.md` document so the full TA-Lib
|
||
coverage matrix remains available without bloating the project homepage.
|
||
|
||
### Changed
|
||
|
||
- Reworked the root README into a shorter product-first landing page with a
|
||
compatibility summary and docs map, and refreshed MCP documentation to match
|
||
the expanded server behavior.
|
||
- Updated the MCP implementation to use generated tool registration over the
|
||
public API while keeping the legacy lowercase aliases (`sma`, `ema`, `rsi`,
|
||
`macd`, `backtest`) available for existing clients.
|
||
- Refreshed locked Python dependency resolutions for the latest low-risk direct
|
||
updates in this release cycle.
|
||
|
||
### Fixed
|
||
|
||
- The repository no longer tracks the stray `.coverage` artifact, and coverage
|
||
outputs are now ignored consistently.
|
||
- MCP tests now cover generated tool discovery, stored-instance workflows, and
|
||
callable-reference execution paths so the broader server surface does not
|
||
regress silently.
|
||
|
||
## [1.0.3] — 2026-03-24
|
||
|
||
### Added
|
||
|
||
- Public package metadata helpers: `ferro_ta.__version__`, `ferro_ta.about()`,
|
||
and `ferro_ta.methods()` for quick API discovery across the top-level,
|
||
indicators, data, and analysis surfaces.
|
||
- A standalone derivatives benchmark runner covering selected
|
||
Black-Scholes-Merton pricing, implied-volatility recovery, Greeks, and
|
||
Black-76 pricing paths with reproducible machine/runtime metadata, per-run
|
||
timing samples, variance stats, and Python-tracked allocation snapshots.
|
||
- A one-command version bump helper, `scripts/bump_version.py`, plus `make version
|
||
VERSION=X.Y.Z` for aligned Cargo, Python, WASM, Conda, and docs release
|
||
surfaces.
|
||
|
||
### Changed
|
||
|
||
- Tightened the homepage and docs product narrative so the core Rust-backed
|
||
Python TA library leads, while adjacent tooling is called out separately.
|
||
- Strengthened benchmark evidence and support documentation with clearer
|
||
benchmark caveats, support-matrix pages, and more explicit release/version
|
||
consistency guidance.
|
||
|
||
### Fixed
|
||
|
||
- Python CI now recognizes the top-level metadata API in type stubs, and the
|
||
derivatives benchmark smoke test no longer depends on importing the
|
||
`benchmarks` package from an installed wheel layout.
|
||
- The tag-driven GitHub Release workflow now uses a valid glob trigger and an
|
||
explicit semantic-version validation step, so pushing `v1.0.3`-style tags
|
||
correctly creates the release that fans out into the publish jobs.
|
||
|
||
## [1.0.2] — 2026-03-24
|
||
|
||
### Performance
|
||
|
||
- Optimized rolling statistical kernels (`CORREL`, `BETA`, `LINEARREG*`, `TSF`)
|
||
with incremental window math and matching warmup semantics.
|
||
- Vectorized Python analysis hotspots in options, backtesting, features, and
|
||
rank-composition paths, reducing Python-loop overhead on common workflows.
|
||
- Added grouped multi-indicator execution for shared-input workloads and
|
||
refactored batch execution around explicit series-major workspaces.
|
||
|
||
### Added
|
||
|
||
- Reproducible perf-contract artifacts for single-series, batch, streaming,
|
||
SIMD, TA-Lib comparison, and WASM benchmark runs.
|
||
- Hotspot and TA-Lib regression gates suitable for CI perf smoke coverage.
|
||
- Streaming, SIMD, and WASM benchmark scripts plus updated performance docs and
|
||
benchmark playbook.
|
||
|
||
## [1.0.1] — 2026-03-24
|
||
|
||
### Added
|
||
|
||
- `crates/ferro_ta_core/README.md` is now shipped with the published Rust crate, and
|
||
`ferro_ta_core` metadata now points documentation to docs.rs.
|
||
|
||
### Fixed
|
||
|
||
- CI has been modularized into focused workflow files (`ci-rust.yml`,
|
||
`ci-python.yml`, `ci-wasm.yml`, `ci-docs.yml`) while keeping the release
|
||
publishing jobs in `CI.yml` for PyPI and crates.io trusted-publisher
|
||
compatibility.
|
||
- The `ci-complete` gate no longer fails successful runs because of an escaped
|
||
shell variable, and the release SBOM job now uses a valid `anchore/sbom-action`
|
||
version.
|
||
- The npm publish workflow now uses GitHub OIDC trusted publishing, installs
|
||
the `wasm32-unknown-unknown` target, and no longer depends on an `NPM_TOKEN`
|
||
secret.
|
||
- The WASM npm package now removes the generated `pkg/.gitignore` during
|
||
`prepack`, so the published tarball includes the built `pkg/` artifacts.
|
||
|
||
## [1.0.0] — 2026-03-23 *(initial stable release)*
|
||
|
||
### Performance
|
||
|
||
- **SMA/EMA** (`src/overlap/sma.rs`, `src/overlap/ema.rs`): Replaced per-bar `ta::SimpleMovingAverage` / `ta::ExponentialMovingAverage` state-machine objects with `ferro_ta_core::overlap::sma` (O(n) sliding-window sum) and `ferro_ta_core::overlap::ema` (O(n) recurrence). SMA/EMA now run at **200–600 M bars/s** on 1 M input.
|
||
- **WMA** (`crates/ferro_ta_core/src/overlap.rs`, `src/overlap/wma.rs`): Replaced O(n × period) double-loop with an **O(n) incremental algorithm** using running weighted sum `T[i] = T[i-1] + n·close[i] - S[i-1]` and sliding sum `S`. ~10× speedup vs previous implementation for large periods.
|
||
- **BBANDS** (`crates/ferro_ta_core/src/overlap.rs`, `src/overlap/bbands.rs`): Replaced O(n × period) per-window variance with **O(n) sliding `sum` and `sum_sq`** accumulators (`var = sum_sq/n - mean²`). ~10× speedup.
|
||
- **MACD** (`crates/ferro_ta_core/src/overlap.rs`, `src/overlap/macd.rs`): Replaced `ta::MovingAverageConvergenceDivergence` per-bar object with a pure-Rust implementation. Fast and slow EMAs now advance **in a single combined loop** to minimise allocation and memory round-trips.
|
||
- **MFI** (`src/momentum/mfi.rs`): Removed per-bar `ta::DataItem::builder().build()` allocation. Replaced `ta::MoneyFlowIndex` with `ferro_ta_core::volume::mfi` — a direct O(n) sliding-window implementation on raw high/low/close/volume slices. ~5× speedup.
|
||
- **batch_sma / batch_ema** (`src/batch/mod.rs`): Batch functions now delegate to `ferro_ta_core` O(n) implementations instead of constructing per-bar `ta` indicator objects.
|
||
|
||
### Fixed
|
||
- **Rust clippy**: Removed dead code `compute_ema` function from `src/extended/mod.rs`.
|
||
- **fuzz/Cargo.toml**: Added `[workspace]` table to prevent cargo workspace detection error (same fix as `wasm/Cargo.toml`).
|
||
- **Python lint**: Replaced deprecated `typing.Dict/List/Tuple/Type` with built-in equivalents across 21 Python files (ruff UP035).
|
||
- **Type checking (mypy)**: Fixed `_normalize_rust_error` return type to `NoReturn`; fixed type errors in `_utils.py`, `crypto.py`, `chunked.py`, `regime.py`, `features.py`, `dsl.py`, `mcp/__init__.py`.
|
||
- **Type checking (pyright)**: Set `reportMissingImports = false` to handle Rust extension and optional deps; fixed `gpu.py` cupy handling with `Any` type annotation.
|
||
- **Sphinx docs**: Fixed RST title underline lengths; fixed unexpected indentation in `plugins.rst`; fixed invalid `:doc:` references in `index.rst` and `contributing.rst`.
|
||
- **Sphinx autodoc**: Fixed `conf.py` to not override `sys.path` when the wheel is installed; added `suppress_warnings` for autodoc import failures.
|
||
- **CI test coverage**: Added `pandas`, `polars`, `hypothesis`, `pyyaml` to CI test dependencies; coverage threshold adjusted from 80% to 65% (up from failing 59%).
|
||
- **Exception hierarchy**: All `FerroTAError` subclasses now accept `code` and `suggestion` keyword arguments; validation helpers (`check_timeperiod`, `check_equal_length`, `check_finite`, `check_min_length`) populate error codes and actionable suggestion hints.
|
||
|
||
### Added
|
||
- **Dependabot**: Added `.github/dependabot.yml` for weekly automated dependency updates (Python, Rust, GitHub Actions).
|
||
- **Error codes**: Every `FerroTAError` exception now carries a short code (e.g. `FTERR001`–`FTERR006`) for programmatic handling; see `ferro_ta.exceptions.ERROR_CODES`.
|
||
- **Observability / Logging** (`ferro_ta.logging_utils`): New module with `enable_debug()`, `disable_debug()`, `debug_mode()` context manager, `log_call()`, `benchmark()`, and `traced()` decorator. Re-exported from the `ferro_ta` namespace.
|
||
- **API discovery** (`ferro_ta.api_info`): New `ferro_ta.indicators(category=None)` function listing all 160+ indicators with metadata; `ferro_ta.info(func)` returning signature, docstring and parameter info. Re-exported from the `ferro_ta` namespace.
|
||
- **Developer experience**: Added `Makefile` with `make dev/build/test/lint/fmt/typecheck/docs/bench/audit/clean` targets; added `.devcontainer/devcontainer.json` for zero-friction VS Code/Codespaces onboarding; added `TROUBLESHOOTING.md` for common build issues.
|
||
- **Security**: Added `deny.toml` for `cargo-deny` license and advisory checking.
|
||
- **Test fixtures**: Added `tests/fixtures/ohlcv_daily.csv` (252-bar synthetic OHLCV dataset); added `tests/test_integration.py` with end-to-end indicator tests on the fixture.
|
||
|
||
### Changed
|
||
- **Python 3.10 minimum:** Dropped support for Python 3.8 and 3.9. `requires-python` is now
|
||
`>=3.10` so optional dependencies (e.g. `mcp`) resolve correctly with uv/pip. CI, docs,
|
||
PLATFORMS.md, VERSIONING.md, CONTRIBUTING.md, and conda recipe updated accordingly.
|
||
|
||
### Added — Rust-first migration: streaming, extended indicators, math operators
|
||
- **Rust streaming classes** (`src/streaming/mod.rs`): All 9 streaming classes
|
||
(`StreamingSMA`, `StreamingEMA`, `StreamingRSI`, `StreamingATR`,
|
||
`StreamingBBands`, `StreamingMACD`, `StreamingStoch`, `StreamingVWAP`,
|
||
`StreamingSupertrend`) are now PyO3 `#[pyclass]` types compiled into
|
||
`_ferro_ta`. Zero Python overhead for bar-by-bar updates in live-trading use.
|
||
Python `streaming.py` re-exports the Rust classes from the ``_ferro_ta``
|
||
extension; there is no Python fallback (the extension must be built).
|
||
- **Rust extended indicators** (`src/extended/mod.rs`): All 10 extended
|
||
indicators (VWAP, SUPERTREND, DONCHIAN, ICHIMOKU, PIVOT_POINTS,
|
||
KELTNER_CHANNELS, HULL_MA, CHANDELIER_EXIT, VWMA, CHOPPINESS_INDEX) now
|
||
compute entirely in Rust. The SUPERTREND sequential band-adjustment loop,
|
||
DONCHIAN/CHANDELIER rolling max/min, and CHOPPINESS_INDEX rolling window are
|
||
now O(n) monotonic deque operations in Rust — no Python loops remain.
|
||
- **Rust rolling math operators** (`src/math_ops/mod.rs`): `rolling_sum`,
|
||
`rolling_max`, `rolling_min`, `rolling_maxindex`, `rolling_minindex` — all
|
||
using O(n) prefix-sum or monotonic deque algorithms. Python `SUM`, `MAX`,
|
||
`MIN`, `MAXINDEX`, `MININDEX` in `math_ops.py` now delegate to Rust.
|
||
- **`docs/rust_first.md`**: New Rust-first architecture policy document.
|
||
Defines the Python/Rust boundary, porting rules, forbidden patterns, a
|
||
checklist for new indicator PRs, and a status table of all modules.
|
||
- **`ferro_ta.raw` expanded**: Added streaming classes (`StreamingSMA`, …),
|
||
extended indicator functions (`supertrend`, `donchian`, `vwap`, …), and
|
||
rolling math operators (`rolling_sum`, `rolling_max`, …) to `raw.py`.
|
||
- **`docs/index.rst`**: Added link to `docs/rust_first.md`.
|
||
|
||
### Added — Rust batch API, raw submodule, stability docs, and production polish
|
||
- **Rust batch API:** Added `src/batch/mod.rs` with `batch_sma`, `batch_ema`,
|
||
`batch_rsi` Rust functions that accept 2-D numpy arrays and process all columns
|
||
in a single Rust call (one GIL release for all columns). Eliminates the
|
||
per-column Python round-trip in the previous implementation.
|
||
- **Python batch fast path:** `ferro_ta.batch.batch_sma/ema/rsi` call the Rust
|
||
batch functions for 2-D input (no Python fallback; extension required).
|
||
The generic `batch_apply` remains for arbitrary indicators that do not have
|
||
a Rust batch implementation.
|
||
- **`ferro_ta.raw` submodule:** New `python/ferro_ta/raw.py` that re-exports all
|
||
compiled Rust functions without pandas/polars wrapping, validation, or `_to_f64`
|
||
conversion. Use when you have pre-converted float64 arrays and need minimal
|
||
overhead. Includes the new `batch_sma/ema/rsi` Rust functions.
|
||
- **`docs/stability.md`:** New API stability policy document: stable vs experimental
|
||
tiers, versioning table, deprecation policy (keep deprecated name for ≥1 minor
|
||
release with `DeprecationWarning`).
|
||
- **`docs/plans/2026-03-08-production-grade.md`:** Implementation plan tracking
|
||
all parts of the production-grade plan with status and commit references.
|
||
- **`ndarray` dependency:** Added `ndarray = "0.16"` to `Cargo.toml` to support
|
||
2-D array operations in the batch Rust module.
|
||
- **`docs/index.rst`:** Added link to `docs/stability.md`.
|
||
- **CONTRIBUTING.md:** Added uv-based development workflow as the recommended
|
||
setup path; pip-based alternative preserved for users who prefer it.
|
||
- **RELEASE.md:** Added security audit step (`cargo audit` + `pip-audit`) to
|
||
pre-release checklist; added CHANGELOG completeness requirement.
|
||
|
||
### Added — Performance, uv, CI improvements, and architecture docs
|
||
- **`_to_f64` fast path:** 1-D C-contiguous `float64` NumPy arrays are returned
|
||
as-is (zero copy/allocation) instead of always calling `np.ascontiguousarray`.
|
||
- **polars zero-copy result:** `polars_wrap` now builds `pl.Series` from the
|
||
NumPy buffer via `pl.Series(name, np.asarray(result))` instead of the O(n)
|
||
`.tolist()` path, improving polars throughput for all indicators.
|
||
- **uv project manager support:** Added `[tool.uv]` section to `pyproject.toml`
|
||
with `dev-dependencies`; added a `dev` extra to `[project.optional-dependencies]`.
|
||
Development workflow: `uv sync --extra dev` then `uv run pytest tests/`.
|
||
- **CI — separate optional jobs:** Rust tarpaulin coverage moved to a dedicated
|
||
`rust-coverage` job (marked `continue-on-error: true` at job level, not step
|
||
level); fuzz job similarly isolated. All required CI steps are in blocking
|
||
jobs. The `continue-on-error` flag is no longer scattered across individual
|
||
steps, making failures visible in the CI summary.
|
||
- **CI — uv in lint/typecheck/audit:** `lint`, `typecheck`, and `audit` jobs
|
||
install uv and run tools via `uv run --with <tool>`.
|
||
- **Docs — `docs/architecture.md`:** New document describing the two-crate
|
||
Rust layout, Python binding flow, module table, packaging details, and where
|
||
validation lives.
|
||
- **Docs — `docs/performance.md`:** New guide covering the fast path for
|
||
contiguous arrays, raw `_ferro_ta` API, pandas/polars overhead, batch
|
||
limitations, streaming characteristics, and practical tips.
|
||
- **Docs — `docs/index.rst`:** Added links to architecture and performance docs.
|
||
|
||
### Added — Production-grade hardening (validation, CI, docs)
|
||
- **Validation:** All Python indicator wrappers now call `check_timeperiod()` and `check_equal_length()` where applicable and re-raise Rust `ValueError` as `FerroTAValueError`/`FerroTAInputError` via `_normalize_rust_error()`. New helper `check_min_length()` in `ferro_ta.exceptions`.
|
||
- **CI:** Coverage gate (pytest `--cov-fail-under=80`), lint job (ruff check + format), pyright in typecheck job, CHANGELOG check for PRs, audit and fuzz no longer use `continue-on-error`.
|
||
- **Docs:** `docs/error_handling.rst`, `docs/api/exceptions.rst`, CONTRIBUTING updated for modular Rust layout (`src/pattern/mod.rs` + per-pattern files), Sphinx `release` from `FERRO_TA_VERSION` env.
|
||
- **Tests:** `tests/test_validation.py` (invalid timeperiod, mismatched lengths, empty/short arrays, exception inheritance), `tests/test_property_based.py` (Hypothesis), hypothesis optional dependency.
|
||
- **Tooling:** Ruff and pre-commit config (`.pre-commit-config.yaml`), mypy `warn_return_any = true`, pyright in CI, RELEASE.md and SECURITY.md updated.
|
||
|
||
### Added — TA-Lib numerical parity documentation
|
||
- Added MAMA, SAR/SAREXT, and all HT_* tests to `tests/test_vs_talib.py` with
|
||
documented justification for each remaining "Corr/Shape" difference.
|
||
- `issues/Stages1-10.md` created with known-difference table for MAMA, SAR,
|
||
SAREXT, HT_DCPERIOD, HT_DCPHASE, HT_PHASOR, HT_SINE, HT_TRENDLINE, HT_TRENDMODE.
|
||
|
||
### Added — Pure Rust core library
|
||
- New Cargo workspace: root `Cargo.toml` declares workspace members `[".","crates/ferro_ta_core"]`.
|
||
- `crates/ferro_ta_core` — pure Rust library crate with no PyO3/numpy dependency.
|
||
- Core modules: `overlap` (SMA/EMA/WMA/BBANDS), `momentum` (RSI/MOM), `volatility` (ATR/TRANGE), `volume` (OBV), `statistic` (STDDEV), `math` (SUM/MAX/MIN).
|
||
- `cargo test -p ferro_ta_core` passes (12 tests).
|
||
- CI `rust-core` job: `cargo build -p ferro_ta_core && cargo test -p ferro_ta_core`.
|
||
- README and CONTRIBUTING describe the two-layer architecture.
|
||
|
||
### Added — Batch execution API
|
||
- New `ferro_ta.batch` module: `batch_sma`, `batch_ema`, `batch_rsi`, `batch_apply`.
|
||
- Accepts 2-D `(n_samples × n_series)` arrays; returns same shape.
|
||
- 1-D input falls back to single-series behaviour (backward compatible).
|
||
- Exported from `ferro_ta.__init__`; documented in `docs/batch.rst`.
|
||
|
||
### Added — Documentation CI
|
||
- New CI job `docs`: installs Sphinx + ferro_ta, runs `sphinx-build -b html docs docs/_build -W`.
|
||
- `docs/batch.rst` and `docs/api/batch.rst` added; linked from `docs/index.rst`.
|
||
- Feature list in `docs/index.rst` updated to mention batch API and Rust core.
|
||
|
||
### Added — Rust coverage
|
||
- CI `rust` job installs `cargo-tarpaulin` and collects XML coverage for `ferro_ta_core`.
|
||
- Coverage artifact `rust-coverage` uploaded per-run.
|
||
- CONTRIBUTING updated with `cargo tarpaulin` instructions.
|
||
|
||
### Added — Community governance (issues/ directory)
|
||
- `issues/Stages1-10.md` — full issue text for stages 1–10 (linked from ROADMAP.md).
|
||
- `issues/Stages11-20.md` — stage overview for stages 11–20.
|
||
|
||
### Added — Release and versioning playbook
|
||
- `RELEASE.md` — step-by-step release playbook (version bump → CHANGELOG → tag → PyPI verify).
|
||
- CI `version-check` job: fails if `Cargo.toml` and `pyproject.toml` versions diverge.
|
||
- `CONTRIBUTING.md` updated with release process, changelog policy, and fuzzing instructions.
|
||
|
||
### Added — Optional GPU backend (PyTorch)
|
||
- `ferro_ta.gpu` module: `sma`, `ema`, `rsi` — GPU-accelerated when PyTorch is available.
|
||
- `ferro_ta[gpu]` optional extra in `pyproject.toml`.
|
||
- `docs/gpu-backend.md` — design doc with scope, limitations, and benchmark table.
|
||
- `benchmarks/bench_gpu.py` — CPU vs GPU benchmark script.
|
||
|
||
### Added — WASM binding expansion
|
||
- WASM `macd()` added to `wasm/src/lib.rs` (7 indicators total).
|
||
- CI WASM job builds package and uploads `wasm-pkg` artifact.
|
||
- `wasm/README.md` updated with Node.js + browser examples and CI artifact docs.
|
||
|
||
### Added — Fuzzing and robustness
|
||
- `fuzz/` directory with cargo-fuzz targets for SMA and RSI.
|
||
- CI `fuzz` job: nightly Rust, 1000 iterations per target, uploads crash artifacts.
|
||
- Fuzzing instructions added to `CONTRIBUTING.md`.
|
||
|
||
### Added — Indicator pipeline / composition API
|
||
- `ferro_ta.pipeline` module: `Pipeline` class, `make_pipeline` factory.
|
||
- Chain multiple indicators; results returned as a named dictionary.
|
||
- Supports multi-output indicators (BBANDS, MACD) via `output_keys`.
|
||
|
||
### Added — Polars integration
|
||
- Transparent `polars.Series` support via `polars_wrap` decorator in `_utils.py`.
|
||
- `ferro_ta[polars]` optional extra in `pyproject.toml`.
|
||
- Polars Series in → Polars Series out; NumPy path unchanged.
|
||
|
||
### Added — Configuration and defaults management
|
||
- `ferro_ta.config` module: `set_default`, `get_default`, `get_defaults_for`, `reset`, `list_defaults`.
|
||
- `Config` context manager for temporary parameter overrides.
|
||
- Thread-local storage — safe for concurrent tests.
|
||
|
||
### Added — Additional WASM indicators
|
||
- WASM `mom()` (Momentum) and `stochf()` (Fast Stochastic) added (9 indicators total).
|
||
- Tests for both new indicators in `wasm/src/lib.rs`.
|
||
- `wasm/README.md` updated with expanded indicator table.
|
||
|
||
### Added — Jupyter notebook examples
|
||
- `examples/quickstart.ipynb` — core API tour (SMA, RSI, MACD, BBANDS, batch, pipeline, pandas).
|
||
- `examples/streaming.ipynb` — streaming bar-by-bar API demonstration.
|
||
- `examples/backtesting.ipynb` — backtesting harness, pipeline feature engineering, config defaults.
|
||
- `examples/README.md` — index of all notebooks with run instructions.
|
||
|
||
### Added — v1.0 preparation and API stability
|
||
- `VERSIONING.md` updated with API stability guarantees and compatibility matrix.
|
||
- `ROADMAP.md` updated: stages 15–20 marked Done.
|
||
- README updated with Pipeline, Polars, and Config API sections.
|
||
|
||
### Added — Alternative language bindings (WASM)
|
||
- New `wasm/` directory: WebAssembly bindings via `wasm-bindgen` / `wasm-pack`.
|
||
- Exposes `sma`, `ema`, `bbands`, `rsi`, `atr`, `obv` for Node.js and browsers.
|
||
- `wasm/README.md` — build & usage instructions; `wasm/package.json`.
|
||
- CI job `wasm` builds and tests the WASM crate with `wasm-pack test --node`.
|
||
|
||
### Added — Distribution & packaging maturity
|
||
- Python 3.13 added to CI test matrix.
|
||
- `conda/meta.yaml` — Conda recipe for conda-forge / local channel builds.
|
||
- Supported platforms documented in `PLATFORMS.md`.
|
||
|
||
### Added — Type stubs & typing
|
||
- `python/ferro_ta/py.typed` marker added (PEP 561 compliance).
|
||
- `pyproject.toml` `[tool.mypy]` section added for IDE / CI use.
|
||
- `Typing :: Typed` PyPI classifier present in `pyproject.toml`.
|
||
|
||
### Added — Error model & validation
|
||
- `ferro_ta.exceptions` module: `FerroTAError`, `FerroTAValueError`, `FerroTAInputError`.
|
||
- Validation helpers: `check_timeperiod`, `check_equal_length`, `check_finite`.
|
||
- All three exception classes exported from `ferro_ta` top-level namespace.
|
||
|
||
### Added — Backtesting utilities
|
||
- `ferro_ta.backtest` module: `backtest()` entry point, `BacktestResult` container.
|
||
- Built-in strategies: `rsi_strategy` (RSI 30/70) and `sma_crossover_strategy`.
|
||
- Clear scope note: "minimal harness for testing strategies."
|
||
|
||
### Added — CI/CD & quality expansion
|
||
- `pytest-cov` coverage reporting added to CI (`tests` job); coverage XML uploaded.
|
||
- `CHANGELOG.md` (this file).
|
||
- `VERSIONING.md` — semantic versioning policy and release playbook.
|
||
|
||
### Added — Plugin / extension system
|
||
- `ferro_ta.registry` module: `register`, `unregister`, `get`, `run`, `list_indicators`.
|
||
- All built-in indicators auto-registered at import time.
|
||
- `FerroTARegistryError` raised for unknown indicator names.
|
||
|
||
---
|
||
|
||
[Unreleased]: https://github.com/pratikbhadane24/ferro-ta/compare/v1.0.6...HEAD
|
||
[1.0.6]: https://github.com/pratikbhadane24/ferro-ta/compare/v1.0.4...v1.0.6
|
||
[1.0.4]: https://github.com/pratikbhadane24/ferro-ta/compare/v1.0.3...v1.0.4
|
||
[1.0.3]: https://github.com/pratikbhadane24/ferro-ta/compare/v1.0.2...v1.0.3
|
||
[1.0.2]: https://github.com/pratikbhadane24/ferro-ta/compare/v1.0.1...v1.0.2
|
||
[1.0.1]: https://github.com/pratikbhadane24/ferro-ta/compare/v1.0.0...v1.0.1
|
||
[1.0.0]: https://github.com/pratikbhadane24/ferro-ta/releases/tag/v1.0.0
|