Files
ferro-ta/docs/changelog.rst
T
Pratik Bhadane fd1bb137d6 Dtw algo (#9)
* feat: implement Dynamic Time Warping (DTW) functionality

- Added DTW distance computation and optimal warping path functions in Rust.
- Introduced corresponding Python bindings for DTW, DTW_DISTANCE, and BATCH_DTW.
- Enhanced WASM support with a new dtw_distance function.
- Included comprehensive unit tests for DTW functionality, validating against the dtaidistance library and ensuring mathematical properties.

* chore: update ferro-ta version to 1.1.4

- Bumped version number of ferro-ta to 1.1.4 in uv.lock and Cargo.lock files.
- Ensured consistency across package dependencies for the updated version.
2026-04-07 23:38:36 +05:30

272 lines
14 KiB
ReStructuredText
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Release Notes
=============
These docs track package version ``1.1.4``.
1.1.0-audit (2026-03-28)
------------------------
**Comprehensive audit: 90 findings addressed**
*Code quality & correctness*
- **Welford's algorithm for BBANDS**: replaced naive ``sum_sq/N - mean^2`` variance
with numerically stable Welford's rolling algorithm in both batch and streaming BBANDS.
Fixes catastrophic cancellation for large-valued series (e.g., prices near 1e12).
- **FFI boundary safety**: ``transpose_to_series_major()`` in ``batch/mod.rs`` now
returns ``PyResult`` instead of using ``expect()``. Remaining ``as_slice().expect()``
calls in ``allow_threads`` closures are documented with SAFETY comments (structurally
infallible after C-contiguous transpose).
- **Clippy clean**: resolved all clippy warnings — complex type in ``adx_all`` extracted
to ``AdxAllResult`` type alias; ``welford_step`` helper annotated with
``#[allow(clippy::too_many_arguments)]``.
*Performance*
- **``target-cpu=native``**: new ``.cargo/config.toml`` enables native CPU instruction
set (AVX2, NEON, etc.) for all non-WASM targets. CI can override via ``RUSTFLAGS``.
*Testing*
- **Streaming unit tests**: 37 new tests in ``tests/unit/streaming/test_streaming.py``
covering ``StreamingSMA``, ``StreamingEMA``, ``StreamingRSI`` — batch parity, warmup
NaN behavior, reset, edge cases, and large dataset numerical stability.
- **Edge case tests**: 31 new tests in ``tests/unit/test_edge_cases.py`` — empty arrays,
single elements, all-NaN input, NaN propagation, extreme values (1e300, 1e-300),
constant series, period boundary conditions, OHLCV edge cases, and dtype coercion
(float32, int64).
- **Property-based tests**: expanded Hypothesis tests for EMA, BBANDS, MACD, ATR, WMA,
and OBV with algebraic invariants (upper >= middle >= lower, histogram == macd - signal,
ATR non-negative, etc.).
- **Pandas/polars integration tests**: new ``test_dataframe_integration.py`` verifying
transparent ``pd.Series`` and ``polars.Series`` support across SMA, EMA, RSI, BBANDS,
MACD, and end-to-end DataFrame workflows.
- **Fuzzing**: expanded from 2 to 9 fuzz targets — added EMA, BBANDS, MACD, ATR, STOCH,
MFI, and WMA with output invariant assertions.
- **Test helpers**: new ``tests/unit/helpers.py`` consolidating duplicated assertion
patterns (``nan_count``, ``finite``, ``assert_nan_warmup``, ``assert_output_length``,
``assert_range``, ``make_ohlcv``).
*Documentation*
- **README benchmarks**: updated to match actual artifact data — MFI 3.25x, WMA 2.20x,
BBANDS 1.97x, SMA 1.93x; corrected win count from 6 to 7 at 100k bars.
- **Rust doc comments**: added comprehensive ``///`` documentation to all public functions
in ``ferro_ta_core`` — overlap (SMA, EMA, WMA, BBANDS, MACD), momentum (RSI, STOCH,
ADX family), volatility (ATR, TRANGE), volume (OBV, MFI), statistic (STDDEV), and math
(sum, max, min, sliding_max, sliding_min).
*Linting*
- **Ruff clean**: fixed import sorting, unused imports, trailing whitespace, and
formatting across all Python files.
- **cargo fmt**: all Rust code formatted.
1.1.0 (2026-03-28)
------------------
**Phase 1 — Simulation fidelity**
- **Bid-ask spread model**: new ``CommissionModel.spread_bps`` field (basis points).
Half-spread is deducted per leg (entry and exit), modelling real market microstructure costs.
- **Breakeven stop**: new ``backtest_ohlcv_core`` parameter ``breakeven_pct`` and
``BacktestEngine.with_breakeven_stop(pct)``. Once profit reaches ``pct``, the
effective stop-loss is moved to the entry price, guaranteeing at worst a breakeven exit.
- **Bracket order priority**: when both stop-loss and take-profit are breached on the
same bar, the level closer to the bar's open price fires first (previously SL always won).
**Phase 2 — Portfolio & risk**
- **Short borrow cost**: new ``CommissionModel.short_borrow_rate_annual`` field.
Accrued per bar for short positions at the specified annualised rate.
- **Leverage / margin modeling**: new ``BacktestEngine.with_leverage(margin_ratio, margin_call_pct)``.
Tracks margin usage and triggers a margin-call force-close when equity falls below
``margin_call_pct × initial_margin``.
- **Loss circuit breakers**: new ``BacktestEngine.with_loss_limits(daily, total)``.
Halts all trading when a per-bar loss or total drawdown threshold is breached.
- **Portfolio constraints**: new ``BacktestEngine.with_portfolio_constraints(max_asset_weight,
max_gross_exposure, max_net_exposure)`` for multi-asset backtests.
**Phase 3 — Data & UX**
- **Bar aggregation** (``ferro_ta.analysis.resample``): ``resample_ohlcv()``, ``align_to_coarse()``,
``resample_ohlcv_labels()`` — pure-NumPy OHLCV resampling from any fine TF to any coarser TF.
- **Multi-timeframe engine** (``ferro_ta.analysis.multitf``): ``MultiTimeframeEngine`` — compute
strategy signals on coarser bars and execute on finer bars, with automatic signal alignment.
- **Dividend/split adjustment** (``ferro_ta.analysis.adjust``): ``adjust_ohlcv()``,
``adjust_for_splits()``, ``adjust_for_dividends()`` — backward-adjusted price series for
equity/index strategies.
- **Visualization** (``ferro_ta.analysis.plot``): ``plot_backtest()`` — interactive Plotly chart
with equity curve, drawdown panel, position panel, trade markers, and optional benchmark overlay.
**Phase 4 — Differentiation**
- **Regime detection** (``ferro_ta.analysis.regime``): ``detect_volatility_regime()``,
``detect_trend_regime()``, ``detect_combined_regime()``, ``RegimeFilter`` — pure-NumPy
6-state market regime labeling and signal filtering; no external ML dependencies.
- **Portfolio optimization** (``ferro_ta.analysis.optimize``): ``PortfolioOptimizer``,
``mean_variance_optimize()``, ``risk_parity_optimize()``, ``max_sharpe_optimize()``
minimum-variance, risk-parity, and maximum-Sharpe portfolios via SLSQP (requires scipy).
- **Paper trading bridge** (``ferro_ta.analysis.live``): ``PaperTrader`` — event-driven
bar-by-bar simulator matching ``backtest_ohlcv_core`` logic exactly; supports streaming
data, live state inspection, and seamless strategy migration from backtesting to live.
1.1.0 (2026-03-27)
------------------
**Advanced commission and fee model (Indian market support)**
- New ``CommissionModel`` class (pure Rust in ``ferro_ta_core``, exposed via
PyO3 and WASM) replaces the broken flat ``commission_per_trade`` scalar. The
old code subtracted an absolute currency amount from a 1.0-normalised equity
curve — equivalent to a 2 000 % error on a ₹1 lakh account. The new model
correctly converts every charge to a fraction of ``initial_capital`` before
deducting it from the equity curve.
- ``CommissionModel`` supports: proportional brokerage (``rate_of_value``),
flat per-order fee (``flat_per_order``), per-lot fee (``per_lot``), brokerage
cap (``max_brokerage``), Securities Transaction Tax (``stt_rate`` with
configurable buy/sell sides), exchange transaction charges, SEBI regulatory
charges, 18 % GST on brokerage + exchange + regulatory levies, and stamp duty
on buy leg only.
- Built-in presets: ``CommissionModel.equity_delivery_india()``,
``CommissionModel.equity_intraday_india()``,
``CommissionModel.futures_india()``, ``CommissionModel.options_india()``,
``CommissionModel.proportional(rate)``, ``CommissionModel.zero()``.
- JSON persistence: ``model.to_json()`` / ``CommissionModel.from_json(s)``,
``model.save(path)`` / ``CommissionModel.load(path)``.
- ``BacktestEngine.with_commission_model(model)`` — pass a full
``CommissionModel``; old ``with_commission(rate)`` kept as a shim.
- New ``initial_capital`` parameter (default ₹1,00,000) on both
``backtest_core`` and ``backtest_ohlcv_core``; also exposed as
``BacktestEngine.with_initial_capital(capital)``.
**Currency system — INR default with lakh/crore formatting**
- New ``Currency`` immutable descriptor in the Python layer with constants
``INR``, ``USD``, ``EUR``, ``GBP``, ``JPY``, ``USDT``.
- ``INR`` is the default currency for ``BacktestEngine``; change via
``engine.with_currency("USD")`` or ``engine.with_currency(EUR)``.
- ``currency.format(amount)`` produces Indian lakh/crore grouping for INR
(e.g. ``₹1,23,45,678.00``) and standard Western grouping for other
currencies.
- Module-level helper ``format_currency(amount, currency=INR)``.
- ``AdvancedBacktestResult`` gains ``currency``, ``initial_capital``, and
``equity_abs`` (absolute currency equity curve) slots.
- ``summary()`` now includes ``initial_capital``, ``final_capital``,
``absolute_pnl``, and ``currency`` keys.
- ``AdvancedBacktestResult.__repr__`` shows the final capital in the correct
currency symbol (e.g. ``final=₹1,23,450.00``).
- Trade log gains a ``pnl_abs`` column (PnL in absolute currency units).
- ``to_equity_dataframe()`` now includes an ``equity_abs`` column.
**Trailing stop loss**
- ``backtest_ohlcv_core`` (and ``BacktestEngine.with_trailing_stop(pct)``)
now supports a trailing stop implemented intrabar in Rust: the high-water
mark is updated each bar; the position is exited at
``trail_high × (1 pct)`` when ``low[i]`` crosses below it (long trades),
or ``trail_low × (1 + pct)`` for short trades.
**Benchmark comparison metrics**
- ``compute_performance_metrics`` accepts an optional ``benchmark_returns``
array. When provided, ``summary()`` includes: ``benchmark_total_return``,
``benchmark_cagr``, ``benchmark_annualized_vol``, ``benchmark_sharpe``,
``alpha`` (active return), ``beta``, ``tracking_error``, and
``information_ratio``.
- ``BacktestEngine.with_benchmark(close_array)`` — pass benchmark close prices.
**Volatility-target position sizing**
- New ``"volatility_target"`` method for ``with_position_sizing()``:
``engine.with_position_sizing("volatility_target", target_vol=0.15, vol_window=20)``.
Signals are pre-scaled in Python by ``clip(target_vol / rolling_annualised_vol, 0, 3)``
before the Rust core call, keeping the hot loop unchanged.
**Backtesting engine v2 — full feature set**
- ``BacktestEngine`` now supports true two-pass Kelly / half-Kelly position
sizing: a unit-signal pass computes win statistics, then the core engine
re-runs with signals scaled by the Kelly fraction.
- Added ``fixed_fractional`` position sizing method:
``engine.with_position_sizing("fixed_fractional", fraction=0.5)``.
- New ``StreamingBacktest`` Rust class for bar-by-bar incremental backtesting
(no bulk arrays needed); exposes ``.on_bar()``, ``.summary()``, ``.reset()``.
- ``AdvancedBacktestResult.to_equity_dataframe(freq)`` — returns equity,
returns, and drawdown as a ``pd.DataFrame`` with a synthetic DatetimeIndex.
- ``AdvancedBacktestResult.summary()`` — concise dict of the 9 most commonly
cited metrics plus ``n_trades``.
**Core indicator speedup**
- ADX-family indicators (``adx_all`` public API): all six series (PDM, MDM,
+DI, -DI, DX, ADX) can now be computed from a single TR/PDM/MDM pass via
``ferro_ta.adx_all()``, eliminating the 6× redundant computation that
occurred when callers fetched each series independently.
- ``adxr`` now reuses a single ``adx_inner`` call internally (was calling
``adx()`` which re-ran the inner loop).
1.0.6 (2026-03-24)
------------------
- Added a repo-managed pre-push gate so the core Rust, Python, docs, and WASM
checks can be run locally before release.
- Expanded Rust-backed analysis/data helpers, broadened the WASM exports, and
added cross-surface API manifest verification plus Node conformance checks.
- Refreshed benchmark coverage and perf artifacts, aligned Python CI with the
local tooling flow, and updated the locked security fixes needed for a clean
release pass.
1.0.4 (2026-03-24)
------------------
- Expanded the optional MCP server from a small hand-written subset to the
broader public ferro-ta callable surface, including stateful class support
through stored-instance management tools.
- Split the root documentation so the full TA-Lib compatibility matrix lives in
``TA_LIB_COMPATIBILITY.md`` while the README stays product-first and shorter.
- Refreshed MCP docs/tests and updated locked low-risk Python dependencies as
part of the release cleanup pass.
- Stopped tracking the stray ``.coverage`` artifact and aligned ignore rules
for local coverage outputs.
1.0.3 (2026-03-24)
------------------
- Added top-level package metadata helpers such as ``ferro_ta.__version__``,
``ferro_ta.about()``, and ``ferro_ta.methods()``.
- Added a standalone derivatives benchmark artifact for selected options
pricing, IV, Greeks, and Black-76 comparisons.
- Simplified release version bumps with a single script and updated release
guidance.
- Fixed Python CI/type-stub gaps around the new metadata API and corrected the
tag-driven GitHub Release workflow trigger used for publish automation.
1.0.2 (2026-03-24)
------------------
- Improved rolling statistical kernels and several Python analysis hotspots.
- Added reproducible perf-contract artifacts, TA-Lib regression guards, and
updated benchmark tooling.
- Tightened the public benchmark documentation so claims, caveats, and evidence
live closer together.
1.0.1 (2026-03-24)
------------------
- Improved release automation for PyPI, crates.io, and npm.
- Fixed CI workflow issues that caused otherwise healthy release jobs to fail.
- Ensured the published WASM package includes its built ``pkg/`` artifacts.
1.0.0 (2026-03-23)
------------------
- First stable release of the Rust-backed Python technical analysis library.
- Shipped broad TA-Lib coverage, streaming APIs, extended indicators, and the
initial Sphinx documentation set.
- Added the benchmark suite, release playbook, and compatibility/testing
scaffolding for stable releases.
For the canonical project changelog, including the full per-version details,
see `CHANGELOG.md <https://github.com/pratikbhadane24/ferro-ta/blob/main/CHANGELOG.md>`_.