Trading Lab
A futures backtester and replay tool that evaluates trades against prop firm account rules.

The real problem
Backtests that report only net P&L miss account failures between entry and exit. A strategy can finish profitable after breaching daily loss or trailing drawdown. Evaluations also depend on profit targets, consistency thresholds, and minimum trading days.
I built this after passing evaluations without finding a durable trading edge.
Architecture
Databento history is ingested into PostgreSQL/TimescaleDB; time_bucket() aggregates candles before Python prepares indicators and signals. FastAPI coordinates queries, simulation, evaluation, and persistence.
pybind11 passes NumPy OHLC and signal arrays into the C++17 loop, which returns trades and equity. Python restores timestamps and scores account rules. SolidJS handles charts, replay controls, and saved-run comparisons.
Technical decisions and trade-offs
- Small native boundary. Keep DataFrames, metrics, and rules in Python; compile the numerical loop. Faster runs, but an extension to build and maintain.
- Shared-memory batches. Release the GIL and run signal variants in a C++ thread pool over read-only price arrays, avoiding a history copy per trial.
- Python reference. Keep a fallback and test C++/Python trade and equity parity across execution modes. Matching rounding takes priority over aggressive floating-point optimizations.
- Explicit fills. Default to next-bar opens with adverse slippage; synthetic spreads and brackets are opt-in. Persist assumptions with each run. When both bracket levels touch, assume the stop first.
Core workflows
- Configure. Select symbol, dates, interval, position size, and an evaluation preset.
- Backtest and compare. Save trades, equity, and rule outcomes; compare two runs.
- Replay. Step through history, place manual trades, and save or resume sessions.


Current limitations and next work
- EOD drawdown uses starting account size rather than a full session-close trailing model.
- OHLC bars and synthetic quotes cannot reproduce intrabar order sequence or queue position.
- Next: reduce Python result materialization and indicator prep costs; add hosted deployment and authentication.