Equivalence matrix
Every case ran twice on the same machine: unchanged backtrader 1.9.78.123 (A) and the same backtrader
with the TAKT build loaded (C), with the published scripts in tools/ (tools/matrix.py). The complete
canonical result of every parameter set (parameters, the output of every analyzer, every order
notification, every trade notification, final value, cash and positions; tools/bt_opt.py) was
compared byte for byte. AMD Ryzen Threadripper PRO 5975WX (Zen 3), Python 3.12.3. Times are single
runs on one CPU each (two cases at a time on two CPUs; the maxcpus=4 case ran its four worker
processes on both CPUs), for orientation only; the measured factors are in the README.
| Case | Strategy (source; file in tools/) |
Grid | Data and settings | Parameter sets | Closed trades | Order notifications | Result | Engine in C | A, s | C, s |
|---|---|---|---|---|---|---|---|---|---|---|
| smacross_btc1h | SmaCross (backtrader documentation ("Hello Algotrading!"); strats_bt_docs.py) |
{"pfast": [5, 10, 20], "pslow": [30, 60, 120]} |
BTCUSDT-1h; default settings (stdstats, optreturn, 7 analyzers) |
9 | 3,323 | 19,959 | identical | TAKT | 21.0 | 5.3 |
| smacross_eth5m | SmaCross (backtrader documentation ("Hello Algotrading!"); strats_bt_docs.py) |
{"pfast": [10, 20], "pslow": [50, 100]} |
ETHUSDT-5m; 5-minute candles, 105,120 bars |
4 | 4,673 | 28,050 | identical | TAKT | 35.9 | 10.3 |
| quickstart_sol_margin | TestStrategy (backtrader documentation (Quickstart, final version); strats_bt_docs.py) |
{"maperiod": [10, 15, 20, 25, 30]} |
SOLUSDT-1h --cash 1000 --comm 0 --sizer fixed10; quickstart settings: 1,000 cash, no commission, 10-unit fixed size; many orders rejected for margin |
5 | 7,173 | 58,894 | identical | TAKT | 14.9 | 7.1 |
| sigsmacross_sol | SigSmaCross (backtrader samples/sigsmacross/sigsmacross.py; strats_bt_samples.py) |
{"sma1": [5, 10, 20], "sma2": [30, 50]} |
SOLUSDT-1h; SignalStrategy |
6 | 2,700 | 16,206 | identical | TAKT | 15.6 | 4.9 |
| macdatr_bnb | MacdAtr (backtrader samples/macd-settings; strats_bt_samples.py) |
{"macd1": [8, 12], "macd2": [21, 26], "atrdist": [2.0, 3.0]} |
BNBUSDT-1h |
8 | 4,012 | 24,084 | identical | TAKT | 21.0 | 5.9 |
| btfd_xrp | Btfd (backtrader samples/btfd; strats_bt_samples.py) |
{"fall": [-0.01, -0.02], "hold": [2, 5], "target": [0.9]} |
XRPUSDT-1h --sizer none; order_target_percent |
4 | 9,879 | 59,274 | identical | TAKT | 13.4 | 7.0 |
| bkrsi_btc | BkRSI (bukosabino/wrapper-backtrader strategies/rsi.py (MIT); strats_bukosabino.py) |
{"period": [21, 28, 35]} |
BTCUSDT-1h --sizer none --bksize 0.1; explicit sizes |
3 | 274 | 1,693 | identical | TAKT | 6.2 | 2.0 |
| bkrsi_bracket_btc | BkRSI (bukosabino/wrapper-backtrader strategies/rsi.py (MIT); strats_bukosabino.py) |
{"period": [21, 28, 35]} |
BTCUSDT-1h --sizer none --bksize 0.1 --bracket 1; bracket orders (limit entry with expiry, stop loss, take profit) |
3 | 351 | 14,821 | identical | TAKT | 6.9 | 2.5 |
| bkaberration_sol | BkAberration (bukosabino/wrapper-backtrader strategies/bbands.py (MIT); strats_bukosabino.py) |
{"period": [20, 40], "devfactor": [2, 2.5]} |
SOLUSDT-1h --sizer none --bksize 10 |
4 | 733 | 4,404 | identical | TAKT | 8.5 | 2.5 |
| bkaberration_bracket_sol | BkAberration (bukosabino/wrapper-backtrader strategies/bbands.py (MIT); strats_bukosabino.py) |
{"period": [20, 40]} |
SOLUSDT-1h --sizer none --bksize 10 --bracket 1; bracket orders |
2 | 1,040 | 9,886 | identical | TAKT | 4.9 | 2.2 |
| bbadx_xrp_short_stop | BBADX (jasgin/backtrader-backtests BB_ADX.py (MIT); strats_jasgin.py) |
{"BB_MA": [20, 30], "ADX_Max": [25, 40]} |
XRPUSDT-1h --sizer pct50; short selling, stop orders |
4 | 3,825 | 23,145 | identical | TAKT | 11.8 | 5.3 |
| stochsr_xrp_oco | StochasticSR (jasgin/backtrader-backtests Stochastic_SR_Backtest.py (MIT); strats_jasgin.py) |
{"period": [14, 21], "stop_pips": [0.002, 0.01]} |
XRPUSDT-1h --sizer pct50; short selling, OCO stop orders |
4 | 5,047 | 48,366 | identical | TAKT | 11.8 | 5.4 |
| dma_btc_signal | DualMovingAverageStrategy (quantrocket-codeload/backtrader-dma (Apache-2.0); strats_quantrocket.py) |
{"smavg_window": [50, 100], "lmavg_window": [200, 300]} |
BTCUSDT-1h; SignalStrategy |
4 | 274 | 1,650 | identical | TAKT | 10.1 | 2.8 |
| empsma_5pairs | EmpSmaCross (empenoso/backtrader-quickstart-template sma_cross_strategy.py (MIT); strats_empenoso.py) |
{"fast_ma": [5, 10], "slow_ma": [30, 60]} |
BTCUSDT-1h,ETHUSDT-1h,SOLUSDT-1h,BNBUSDT-1h,XRPUSDT-1h --sizer none --cash 500000; five aligned data feeds, per-feed indicators |
4 | 8,817 | 52,929 | identical | TAKT | 32.2 | 12.7 |
| empsma_5pairs_asauthored | EmpSmaCross (empenoso/backtrader-quickstart-template sma_cross_strategy.py (MIT); strats_empenoso.py) |
{"fast_ma": [5, 10], "slow_ma": [30, 60]} |
BTCUSDT-1h,ETHUSDT-1h,SOLUSDT-1h,BNBUSDT-1h,XRPUSDT-1h --sizer none --cash 500000 --runonce 0 --exactbars -1; the author's settings: runonce=False, exactbars=-1 |
4 | 8,817 | 52,929 | identical | backtrader's own (fallback) | 53.4 | 53.6 |
| statsreader_btc_observer | StatsReader (ours: reads the broker observer, receives cash/value notifications; strats_takt.py) |
{"period": [20, 50]} |
BTCUSDT-1h; strategy reads the broker observer |
2 | 14,610 | 87,663 | identical | TAKT | 12.4 | 9.7 |
| smacross_nostdstats | SmaCross (backtrader documentation ("Hello Algotrading!"); strats_bt_docs.py) |
{"pfast": [5, 10], "pslow": [30, 60]} |
ETHUSDT-1h --stdstats 0 --analyzers min; stdstats=False, 3 analyzers |
4 | 1,884 | 11,307 | identical | TAKT | 7.0 | 2.3 |
| smacross_optreturn0 | SmaCross (backtrader documentation ("Hello Algotrading!"); strats_bt_docs.py) |
{"pfast": [5, 10], "pslow": [30, 60]} |
ETHUSDT-1h --optreturn 0; optreturn=False (full strategy objects returned) |
4 | 1,884 | 11,307 | identical | TAKT | 9.1 | 3.8 |
| smacross_coc_slip | SmaCross (backtrader documentation ("Hello Algotrading!"); strats_bt_docs.py) |
{"pfast": [5, 10], "pslow": [30, 60]} |
SOLUSDT-1h --coc 1 --slip 0.001; cheat-on-close, 0.1% slippage |
4 | 1,827 | 10,962 | identical | TAKT | 9.1 | 2.8 |
| smacross_fund_interest | SmaCross (backtrader documentation ("Hello Algotrading!"); strats_bt_docs.py) |
{"pfast": [5, 10], "pslow": [30, 60]} |
BNBUSDT-1h --fundmode 1 --interest 0.05; fund mode, 5% credit interest on longs |
4 | 1,916 | 11,508 | identical | TAKT | 9.1 | 2.8 |
| smacross_runnext | SmaCross (backtrader documentation ("Hello Algotrading!"); strats_bt_docs.py) |
{"pfast": [5, 10], "pslow": [30, 60]} |
BTCUSDT-1h --runonce 0; runonce=False |
4 | 1,871 | 11,238 | identical | backtrader's own (fallback) | 14.8 | 14.7 |
| smacross_daterange | SmaCross (backtrader documentation ("Hello Algotrading!"); strats_bt_docs.py) |
{"pfast": [5, 10], "pslow": [30, 60]} |
XRPUSDT-1h --fromdate 2024-06-01 --todate 2025-06-30; fromdate/todate subset |
4 | 669 | 4,026 | identical | TAKT | 3.8 | 1.2 |
| smacross_lowcash_margin | SmaCross (backtrader documentation ("Hello Algotrading!"); strats_bt_docs.py) |
{"pfast": [5, 10], "pslow": [30, 60]} |
BTCUSDT-1h --cash 100 --sizer fixed; 100 cash, 1 BTC fixed size: every order rejected |
4 | 0 | 3,750 | identical | TAKT | 8.3 | 1.9 |
| smacross_2data | SmaCross (backtrader documentation ("Hello Algotrading!"); strats_bt_docs.py) |
{"pfast": [5, 10], "pslow": [30, 60]} |
ETHUSDT-1h,BTCUSDT-1h; two aligned data feeds |
4 | 1,884 | 11,307 | identical | TAKT | 12.0 | 3.4 |
| smacross_maxcpus4 | SmaCross (backtrader documentation ("Hello Algotrading!"); strats_bt_docs.py) |
{"pfast": [5, 10, 20, 30], "pslow": [40, 80, 120]} |
BTCUSDT-1h --maxcpus 4; maxcpus=4 (worker processes) |
12 | 3,539 | 21,255 | identical | TAKT | 13.8 | 5.2 |
Total: 25 cases, 114 parameter sets, 91,022 closed trades, 600,613 order notifications; 25 of 25 identical.
The canonical results (149 MB per side) were compared in full; every case also printed the same
digest line in A and C (matrix.log, matrix_raw.tsv: the first 16 hex digits of the SHA-256).
Unless stated otherwise: 10,000 USDT cash, 0.1% commission, 95% PercentSizer, stdstats=True,
optreturn=True, maxcpus=1, analyzers TradeAnalyzer, DrawDown, SharpeRatio, Returns, SQN,
Transactions and TimeReturn (days) plus the three recording analyzers of tools/bt_opt.py; data
Binance spot 1-hour candles 2023-10-01 to 2026-09-30 (26,304 bars).
Order outcomes that occur in these cases (from the recorded notifications of A): Completed; Margin
(7,928 in quickstart_sol_margin, 23 in bkrsi_btc, 21 in bbadx_xrp_short_stop, every order in
smacross_lowcash_margin); Rejected, Canceled, Expired and Margin (bracket orders with a validity
date in bkrsi_bracket_btc; Canceled and Expired in bkaberration_bracket_sol); Canceled by OCO
(stochsr_xrp_oco); short positions and stop orders (bbadx_xrp_short_stop, stochsr_xrp_oco).
"Engine in C": TAKT where the TAKT build ran every parameter set itself; "backtrader's own
(fallback)" where the setting is one the TAKT build does not cover and backtrader's own engine ran
it (runonce=False, exactbars), at backtrader's own speed and with the same result.