A trading bot built the careful way: simulation and backtesting first, then an exchange testnet end to end, with arming guards that keep the live executor locked until an operator explicitly turns it on.
Python
pytest
PostgreSQL
Docker
NextJS
Overview
The interesting problem in a trading bot is not the strategy — it is making sure the code that touches real money has earned the right to. TradePilot is structured as a series of gates: a simulator with backtesting, then the same pipeline against an exchange's testnet, and only then a live executor that stays disarmed by default.
How it is built
Simulation first — strategies run against historical and synthetic data in a simulator that shares the order and position model with the real executor, so what is tested is what would run.
Sandbox end to end — the full loop (signals, orders, fills, reconciliation) runs against the exchange testnet, with the same configuration surface as live.
Arming guards — the live executor cannot place an order unless several explicit, operator-controlled conditions are met; the "money decisions" are deliberately human.
Tests as the safety net — several hundred pytest cases cover the state machine, risk limits and the reconciliation logic.
Self-hosted — runs on a small always-on machine with scripted database dumps and restores.
How it fits together
Diagram sourceflowchart
flowchart TD
sim["Simulator and backtesting"] -->|gate| sandbox["Full loop on the exchange testnet"]
sandbox -->|gate| live["Live executor, disarmed by default"]
guards["Operator-controlled arming conditions"] --> live
tests["Several hundred pytest cases"] -.-> sim
tests -.-> sandbox
Status
Simulation, backtesting groundwork and the sandbox loop are done and tested; live trading is intentionally still gated.