chore: prepare v1.1.0 release

Update version numbers across Rust, Python, and documentation files to 1.1.0. Enhance the .gitignore to include macOS dSYM files and plans directory. Introduce new dependencies in the Rust core library and update the README to reflect recent performance benchmarks and backtesting engine capabilities. Add new artifacts to the benchmarks manifest and improve documentation for the backtesting engine API.
This commit is contained in:
Pratik Bhadane
2026-03-30 12:45:52 +05:30
parent 2d776b6f90
commit 436954138f
174 changed files with 29297 additions and 10773 deletions
+73
View File
@@ -10,6 +10,11 @@ a Python technical analysis library.
* - Area
- Status
- What it is
* - Backtesting engine
- Adjacent
- Vectorized Rust backtester: OHLCV fill, stop-loss/TP, 23 performance
metrics, trade extraction, parallel Monte Carlo, walk-forward analysis,
and multi-asset portfolio simulation. See :ref:`backtesting-engine`.
* - Derivatives analytics
- Adjacent
- Options pricing, Greeks, implied volatility helpers, futures basis,
@@ -36,6 +41,74 @@ a Python technical analysis library.
- Registry and plugin packaging model for custom indicators. See
:doc:`plugins`.
.. _backtesting-engine:
Backtesting Engine
------------------
``ferro_ta.analysis.backtest`` ships a production-grade backtesting engine
backed entirely by Rust hot-path functions.
**Core API:**
.. code-block:: python
from ferro_ta.analysis.backtest import BacktestEngine, monte_carlo, walk_forward
result = (
BacktestEngine()
.with_commission(0.001)
.with_slippage(5.0) # basis points
.with_ohlcv(high=high, low=low, open_=open_)
.with_stop_loss(0.02)
.with_take_profit(0.04)
.run(close, "sma_crossover")
)
print(result.metrics["sharpe"]) # one of 23 metrics
print(result.trades) # pandas DataFrame
print(result.drawdown_series.min()) # max drawdown
mc = monte_carlo(result, n_sims=1000) # parallel bootstrap
wf = walk_forward(close, "rsi", param_grid=[{"timeperiod": t} for t in [10,14,20]],
train_bars=500, test_bars=100)
**Available Rust primitives** (``ferro_ta._ferro_ta``):
- ``backtest_core`` — close-only, vectorized, commission + slippage
- ``backtest_ohlcv_core`` — fill at open, intrabar stop-loss / take-profit
- ``compute_performance_metrics`` — 23 metrics in one pass (Sharpe, Sortino,
Calmar, CAGR, Omega, Ulcer, win rate, profit factor, tail ratio, etc.)
- ``extract_trades_ohlcv`` — 9 parallel arrays (entry/exit bar, MAE, MFE, …)
- ``backtest_multi_asset_core`` — N-asset parallel backtest via Rayon
- ``monte_carlo_bootstrap`` — parallel block bootstrap, returns (n_sims, n_bars)
- ``walk_forward_indices`` — anchored/rolling fold index generator
- ``kelly_fraction`` / ``half_kelly_fraction``
**Speed vs competitors** (100k bars, SMA crossover, Apple M-series):
.. list-table::
:header-rows: 1
* - Library
- Time
- vs ferro-ta
* - ferro-ta ``backtest_core``
- 0.29 ms
- —
* - NumPy vectorized
- 0.46 ms
- 1.6× slower
* - vectorbt
- 2.9 ms
- 10× slower
* - backtesting.py
- 320 ms
- 1,100× slower
* - backtrader
- ~520 ms (10k bars)
- >15,000× slower
How to read the project
-----------------------
+6255 -4994
View File
File diff suppressed because it is too large Load Diff
+83
View File
@@ -13,9 +13,92 @@ The authoritative benchmark workflow lives in ``benchmarks/``:
- Cross-library speed suite: ``benchmarks/test_speed.py``
- Cross-library accuracy suite: ``benchmarks/test_accuracy.py``
- TA-Lib head-to-head script: ``benchmarks/bench_vs_talib.py``
- Backtesting engine benchmark: ``benchmarks/bench_backtest.py``
- Table generation from benchmark JSON: ``benchmarks/benchmark_table.py``
- Perf-contract artifact bundle: ``benchmarks/run_perf_contract.py``
Backtesting engine — competitor comparison
------------------------------------------
Measured on Apple M-series, Python 3.13, Rust 1.91, using an SMA(20/50)
crossover strategy with 0.1% commission and 5 bps slippage. Median of 5 runs.
.. list-table:: Speed vs backtesting libraries (signal → equity curve)
:header-rows: 1
* - Library
- 1k bars
- 10k bars
- 100k bars
- vs ferro-ta core (100k)
* - **ferro-ta** ``backtest_core``
- 0.004 ms
- 0.033 ms
- 0.286 ms
- —
* - **ferro-ta** ``backtest_ohlcv_core``
- 0.004 ms
- 0.037 ms
- 0.332 ms
- ~same
* - NumPy vectorized (manual)
- 0.013 ms
- 0.042 ms
- 0.459 ms
- 1.6× slower
* - vectorbt 0.28
- 1.32 ms
- 1.31 ms
- 2.90 ms
- **10× slower**
* - backtesting.py
- 10.5 ms
- 42.3 ms
- 319.6 ms
- **1,117× slower**
* - backtrader 1.9
- 53.9 ms
- 518 ms
- n/a (skipped)
- **>15,000× slower**
Accuracy: ferro-ta positions and bar-returns are **bit-exact** against the NumPy
reference implementation (max per-bar equity diff = 0.00e+00 with zero
commission/slippage).
Additional ferro-ta capabilities not present in the libraries above:
.. list-table::
:header-rows: 1
* - Capability
- ferro-ta result
- NumPy baseline
- Speedup
* - Monte Carlo 1,000 sims (100k bars)
- 50 ms (parallel Rayon + LCG)
- 612 ms (Python loop)
- **12×**
* - 23 performance metrics, single call (100k bars)
- 2.8 ms
- 0.36 ms (2 metrics only)
- 0.12 ms / metric
* - Multi-asset 100 assets (100k bars)
- 43 ms parallel / 88 ms serial
- —
- 2× parallel speedup
* - Walk-forward fold indices (100k bars)
- 0.3 µs
- —
- —
Reproduce the backtest benchmark:
.. code-block:: bash
python benchmarks/bench_backtest.py --sizes 10000 100000 \
--json benchmarks/artifacts/latest/bench_backtest_results.json
Latest checked-in TA-Lib artifact
---------------------------------
+204 -1
View File
@@ -1,7 +1,210 @@
Release Notes
=============
These docs track package version ``1.0.6``.
These docs track package version ``1.2.0``.
1.2.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.2.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)
------------------
+1
View File
@@ -59,6 +59,7 @@ Core library:
Adjacent and experimental tooling:
- **Backtesting engine** — OHLCV fill, 23 metrics, Monte Carlo, walk-forward, multi-asset — see :doc:`adjacent_tooling`
- Derivatives analytics — see :doc:`derivatives`
- Agentic workflow and LangChain tool wrappers — see `Agentic guide <https://github.com/pratikbhadane24/ferro-ta/blob/main/docs/agentic.md>`_
- MCP server for MCP-compatible clients — see `MCP guide <https://github.com/pratikbhadane24/ferro-ta/blob/main/docs/mcp.md>`_
+29 -7
View File
@@ -234,6 +234,29 @@ wrapper with validation and `_to_f64`; all computation runs in the extension.
and `benchmarks/profile_runtime_hotspots.py` record timings with git/runtime
metadata so you can compare apples to apples across machines and commits.
## Backtesting Performance
ferro-ta's backtesting engine is the fastest in the Python ecosystem for
vectorized single- and multi-asset scenarios.
| Library | 100k bars | vs ferro-ta |
|---------|-----------|-------------|
| ferro-ta `backtest_core` | **0.29 ms** | — |
| ferro-ta `backtest_ohlcv_core` | **0.33 ms** | ~same |
| NumPy vectorized | 0.46 ms | 1.6× slower |
| vectorbt | 2.90 ms | 10× slower |
| backtesting.py | 319 ms | 1,117× slower |
| backtrader | ~50,000 ms (est.) | >15,000× slower |
Additional capabilities measured at 100k bars:
| Capability | Time |
|---|---|
| Monte Carlo 1,000 sims (parallel) | 50 ms — 12× faster than NumPy loop |
| 23 performance metrics | 2.8 ms (0.12 ms/metric) |
| Multi-asset 100 symbols, parallel | 43 ms — 2× vs serial |
| Walk-forward index generation | 0.3 µs |
## Benchmark Tooling
The benchmark suite now includes a small set of machine-readable scripts for
@@ -241,6 +264,7 @@ performance work beyond the full pytest benchmark table:
- `python benchmarks/bench_batch.py --json batch_benchmark.json`
- `python benchmarks/bench_streaming.py --json streaming_benchmark.json`
- `python benchmarks/bench_backtest.py --json bench_backtest_results.json`
- `python benchmarks/profile_runtime_hotspots.py --json runtime_hotspots.json`
- `python benchmarks/bench_simd.py --json simd_benchmark.json`
- `python benchmarks/run_perf_contract.py --output-dir benchmarks/artifacts/latest`
@@ -301,13 +325,11 @@ for history and commits.
Maintainer-facing list of slower paths and optional improvements. Update as
bottlenecks are fixed or deferred.
**Backtest** (`python/ferro_ta/backtest.py`):
- Equity with commission uses an O(n) Python loop (lines 374380). Could
vectorize (e.g. cumsum of commission events) or move to a small Rust helper.
- When both slippage and commission are used, `position_changed` is computed
twice; compute once and reuse.
- Built-in strategies do redundant `np.asarray(..., dtype=np.float64)` if
callers already pass contiguous float64; minor.
**Backtest** (`python/ferro_ta/analysis/backtest.py`):
- Core signal→equity loop is fully in Rust (`backtest_core`, `backtest_ohlcv_core`).
- Commission and slippage applied inside Rust; no Python loop on the hot path.
- `compute_performance_metrics` computes all 23 metrics in a single Rust pass.
- Monte Carlo runs in parallel Rayon threads with LCG seeding (GIL released).
**Batch** (`python/ferro_ta/batch.py`):
- `batch_apply` runs a Python loop over columns (one Python call per column).
+74 -1
View File
@@ -59,10 +59,83 @@ Module status
* - ``ferro_ta.analysis.*``
- Adjacent tooling
- Useful analytics helpers, but not the primary product story.
* - ``ferro_ta.analysis.resample``
- Supported (v1.2.0)
- ``resample_ohlcv()``, ``align_to_coarse()``, ``resample_ohlcv_labels()`` — pure-NumPy
OHLCV bar aggregation across timeframes.
* - ``ferro_ta.analysis.multitf``
- Supported (v1.2.0)
- ``MultiTimeframeEngine`` — multi-timeframe signal generation with automatic alignment.
* - ``ferro_ta.analysis.adjust``
- Supported (v1.2.0)
- ``adjust_ohlcv()``, ``adjust_for_splits()``, ``adjust_for_dividends()`` — backward-adjusted
price series for equity/index strategies.
* - ``ferro_ta.analysis.plot``
- Supported (v1.2.0)
- ``plot_backtest()`` — interactive Plotly backtest visualization (requires plotly).
* - ``ferro_ta.analysis.regime``
- Supported (v1.2.0)
- ``detect_volatility_regime()``, ``detect_trend_regime()``, ``detect_combined_regime()``,
``RegimeFilter`` — pure-NumPy 6-state market regime labeling; no ML dependencies.
* - ``ferro_ta.analysis.optimize``
- Supported (v1.2.0)
- ``PortfolioOptimizer``, ``mean_variance_optimize()``, ``risk_parity_optimize()``,
``max_sharpe_optimize()`` — portfolio optimization via SLSQP (requires scipy).
* - ``ferro_ta.analysis.live``
- Supported (v1.2.0)
- ``PaperTrader`` — event-driven paper trading bridge matching backtest logic exactly.
* - MCP, WASM, GPU, plugin, and agent-oriented tooling
- Experimental or adjacent
- Evaluate these independently from the core indicator library.
Backtesting engine features
---------------------------
.. list-table::
:header-rows: 1
* - Feature
- Status
- Notes
* - Flat/proportional commission
- Supported
- Via ``CommissionModel`` presets and ``BacktestEngine.with_commission_model()``.
* - Bid-ask spread model (``spread_bps``)
- Supported (v1.2.0)
- New ``CommissionModel.spread_bps`` field; half-spread deducted per leg.
* - Short borrow cost (``short_borrow_rate_annual``)
- Supported (v1.2.0)
- New ``CommissionModel.short_borrow_rate_annual`` field; accrued per bar for short positions.
* - Trailing stop loss
- Supported
- ``BacktestEngine.with_trailing_stop(pct)`` — intrabar high-water mark tracking.
* - Breakeven stop (``breakeven_pct``)
- Supported (v1.2.0)
- ``BacktestEngine.with_breakeven_stop(pct)`` — moves stop to entry once profit reaches ``pct``.
* - Bracket order priority
- Supported (v1.2.0)
- When both SL and TP are breached on the same bar, the level closer to open fires first.
* - Leverage / margin modeling
- Supported (v1.2.0)
- ``BacktestEngine.with_leverage(margin_ratio, margin_call_pct)`` — tracks margin and
triggers force-close on margin call.
* - Loss circuit breakers
- Supported (v1.2.0)
- ``BacktestEngine.with_loss_limits(daily, total)`` — halts trading on drawdown breach.
* - Portfolio constraints
- Supported (v1.2.0)
- ``BacktestEngine.with_portfolio_constraints(max_asset_weight, max_gross_exposure,
max_net_exposure)`` for multi-asset backtests.
* - Volatility-target position sizing
- Supported
- ``BacktestEngine.with_position_sizing("volatility_target", ...)``.
* - Walk-forward / Monte Carlo
- Supported
- Available via ``BacktestEngine`` higher-level methods.
* - Benchmark comparison
- Supported
- ``BacktestEngine.with_benchmark(close_array)`` — alpha, beta, information ratio.
Supported Python versions
-------------------------
@@ -107,7 +180,7 @@ For source builds, packaging details, and platform notes, see
Release status
--------------
These docs track package version ``1.0.6``.
These docs track package version ``1.2.0``.
- Release notes by version: :doc:`changelog`
- Canonical project changelog: `CHANGELOG.md <https://github.com/pratikbhadane24/ferro-ta/blob/main/CHANGELOG.md>`_