← All Collections
10 parts

High-Performance Backtest Engines

How to build a backtest engine that runs hundreds of times faster without changing a single PnL number — data layout, caching, adaptive resolution, and architecture, from first speedups to production internals.

  1. 01
    The Backtest Speed Ladder: 298x on a Laptop CPU, Identical PnL to the Last Trade
    Jun 26, 2026 #algotrading

    The Backtest Speed Ladder: 298x on a Laptop CPU, Identical PnL to the Last Trade

    Five implementations of the same 80-combo parameter sweep, all verified to produce identical PnL: pandas rolling.apply takes 69.9 seconds, numpy 3.1, numba 2.0, parallel numba 0.23 — a measured 298x speedup on an Apple M2 Max with zero hardware changes, and still ~13x over a competent vectorized baseline. What each rung buys, why a GPU is not the missing piece, and where the real bottleneck in mass parameter search lives.

  2. 02
    The Framework Tax: When Your Backtest Library Is Slower Than a Naive Pandas Loop
    Jul 2, 2026 #algotrading

    The Framework Tax: When Your Backtest Library Is Slower Than a Naive Pandas Loop

    We benchmarked eight backtest engines on one identical parameter sweep — 150k bars, 80 HMA-cross combos, trade-count parity locked at 2707. Two of the most popular event-driven frameworks came in slower than a hand-written pandas loop, while a vectorized/compiled engine ran the same work ~13,000× faster. A study of the per-bar overhead that popular libraries were never built to amortize.

  3. 03
    Aggregated Parquet Cache: How to Speed Up Multi-Timeframe Backtests by Hundreds of Times
    Mar 16, 2026 #algotrading

    Aggregated Parquet Cache: How to Speed Up Multi-Timeframe Backtests by Hundreds of Times

    How to precompute timeframes and indicators from minute candles, save them to parquet, and use them for mass strategy testing without redundant recalculations.

  4. 04
    The Two-Axis Parameter Space: Why Most of Your Sweep Should Be Nearly Free
    Jul 3, 2026 #algotrading

    The Two-Axis Parameter Space: Why Most of Your Sweep Should Be Nearly Free

    Not all parameters cost the same to search. A strategy's parameters split into an expensive axis (indicators — recomputed over the whole series) and a cheap axis (decision thresholds — an O(n) pass over precomputed signals). Because indicators are invariant to thresholds, you compute them once and sweep thousands of threshold configs at ~5,600 cfg/s — roughly 1,600x cheaper than recomputing per config. A re-pricing of the curse of dimensionality.

  5. 05
    Adaptive Drill-Down: Backtest with Variable Granularity from Minutes to Raw Trades
    Mar 17, 2026 #algotrading

    Adaptive Drill-Down: Backtest with Variable Granularity from Minutes to Raw Trades

    How adaptive data granularity speeds up backtests and saves storage: drill-down from 1m to 1s, 100ms, and raw trades only where price moved significantly or volume spiked, not across the entire historical series.

  6. 06
    The Fidelity Gate: Coarse-to-Fine Backtesting Fools You Faster Unless the Cheap Proxy Ranks Like the Expensive One
    Jul 5, 2026 #algotrading

    The Fidelity Gate: Coarse-to-Fine Backtesting Fools You Faster Unless the Cheap Proxy Ranks Like the Expensive One

    Drill-down / multi-fidelity search (ASHA, successive halving, Hyperband) screens thousands of configs cheaply and promotes only survivors to the expensive full evaluation. It is a genuine speedup — but it collapses silently if the low-fidelity ranking disagrees with the high-fidelity one. We measured the fold-rank correlation: at one fold Spearman ρ can be 0.03 (ranks almost randomly), climbing to 0.43, 0.67, 0.78, 0.91 as folds accumulate. The fix is one mandatory gate — measure ρ(cheap, full) first, and auto-raise the minimum fidelity to the first rung where ρ ≥ 0.5.

  7. 07
    Random vs Smart Search: The Crossover Is Eval Cost, Not the Algorithm
    Jul 4, 2026 #algotrading

    Random vs Smart Search: The Crossover Is Eval Cost, Not the Algorithm

    When one backtest is cheap, dumb scrambled Sobol wins on raw throughput — smart samplers (TPE, CMA-ES, ASHA) pay a Python ask/tell tax that drops them 20x, so they evaluate far fewer points at equal wall-clock and lose. Make each eval expensive (multi-TF + walk-forward folds) and the crossover flips. We measured both regimes, and why fold-rank fidelity (ρ@1 rising 0.03→0.43) is the precondition for pruning to pay off.

  8. 08
    The GPU Precision Trap: How an fp32 Backtest on Apple Metal Silently Returns Garbage
    Jul 6, 2026 #algotrading

    The GPU Precision Trap: How an fp32 Backtest on Apple Metal Silently Returns Garbage

    Apple's Metal GPU has no float64. Port a vectorized backtest to it naively and the tempting prefix-sum WMA overflows fp32 — max relative error 211× — yet it still runs and returns plausible-looking numbers. The fix is not more precision; it is a different formulation: a direct windowed convolution, fp32-safe to 8×10⁻⁷ and 55.9× faster than single-thread numba. The trap, the arithmetic, and how to prove you didn't fall in.

  9. 09
    When the GPU Pays Off: The Parameter-Sweep Roofline, Where a Headline 167x Is Really 27x Algorithm Times 6.2x Hardware
    Jul 7, 2026 #algotrading

    When the GPU Pays Off: The Parameter-Sweep Roofline, Where a Headline 167x Is Really 27x Algorithm Times 6.2x Hardware

    The GPU's lead over CPU grows with batch size — 54.5x at one combo per call up to 359.6x at 61 on our multi-timeframe indicator precompute — because a small sweep cannot amortize kernel-launch and transfer overhead. We decompose a headline 167x into a 27x algorithmic win that also helps the CPU and a 6.2x hardware win, show the true GPU-vs-best-CPU lead is only 3.2x single-timeframe and 6.2x multi, and give a decision guide for how wide a sweep must be before a GPU is worth buying into.

  10. 10
    The IPC Tax: Put the Backtest Engine Behind a Socket and Lose 13% — Almost None of It to the Socket
    Jun 30, 2026 #algotrading

    The IPC Tax: Put the Backtest Engine Behind a Socket and Lose 13% — Almost None of It to the Socket

    We ported a numba backtest kernel line-for-line to Rust and called it across a process boundary four ways, with an equivalence gate confirming identical PnL to the last trade. Shipping the entire 1.2 MB price series through a Unix socket costs ~2 ms — about 0.1% of the job. JSON-encoding the same payload costs 1348x more than raw bytes, chatty per-combo calls re-ship the data 80 times, and a per-bar call pattern would pay 2.1 s of pure IPC on a 2.0 s job. The boundary is cheap; the tax is in how you cross it.