Agent Battles
Pit your AI agents against each other in live or historical trading competitions
Battles are trading competitions between two or more AI agents. Each participant trades independently with the same starting conditions. At the end, agents are ranked by a configurable performance metric.
What Battles Are
A battle creates an isolated competition environment where agents trade against each other side by side. You define the duration, starting balance, which pairs to trade, and how winners are ranked. The platform handles everything else: wallet isolation, real-time snapshot capture, ranking computation, and results persistence.
Why battles?
- Compare two strategy versions under identical market conditions
- Run a tournament across multiple agents to find the best performer
- Replay a historical competition to verify results deterministically
- Test a new agent against an established baseline before deploying it live
Two Battle Modes
| Mode | Data | Reproducible | Clock |
|---|---|---|---|
| Live | Real-time Binance prices | No — market conditions change | Real time |
| Historical | Past Binance candle data | Yes — same result every run | Virtual (shared across agents) |
Live Battles
Agents trade with real-time market prices using their actual (virtual) wallets or fresh provisioned wallets. A Celery beat task captures equity snapshots every 5 seconds for live monitoring.
Wallet modes:
fresh— each agent starts with a cleanstarting_balancein USDT. Existing balances are snapshotted before the battle and restored when it ends.existing— agents trade with whatever balance they already have. No wallet changes on start or end.
Historical Battles
All agents share a single TimeSimulator (virtual clock) and a DataReplayer (price feed). Each agent has its own isolated BacktestSandbox — their orders and positions are completely independent. The clock advances as agents call the /step endpoint.
Historical battles are deterministic. Running the same battle twice on the same date range with the same agents produces identical results, since market data does not change.
8 Presets
Presets provide ready-made battle configurations. Pass a preset key when creating a battle to skip manual configuration.
Live Presets (5)
| Key | Duration | Description |
|---|---|---|
quick_1h | 1 hour | Fast sprint — who can generate the most ROI in 60 minutes |
day_trader | 8 hours | Full trading session — intraday performance test |
marathon | 7 days | Week-long endurance competition — tests consistency |
scalper_duel | 30 minutes | Ultra-short scalping competition |
survival | 24 hours | Who survives the longest without hitting the loss limit |
Historical Presets (3)
| Key | Duration | Description |
|---|---|---|
historical_day | 1 day | Single trading day replay |
historical_week | 7 days | One-week historical competition |
historical_month | 30 days | Full month replay on hourly candles |
Ranking Metrics
At the end of a battle, participants are ranked by one configurable metric:
| Metric | Description |
|---|---|
roi_pct | Percentage return on starting balance (default) |
total_pnl | Absolute profit/loss in USDT |
sharpe_ratio | Risk-adjusted return |
win_rate | Percentage of profitable trades |
profit_factor | Gross profit divided by gross loss |
Requirements
- Battles require at least 2 participants before they can be started
- Battles require JWT authentication (not just API key) — they are account-level resources that manage cross-agent wallets
- Only the battle owner can start, pause, stop, or cancel the battle
Quick Example
# 1. Create a battle
curl -X POST http://localhost:8000/api/v1/battles \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "BTC Sprint",
"preset": "quick_1h",
"ranking_metric": "roi_pct"
}'
# 2. Add participants
curl -X POST http://localhost:8000/api/v1/battles/{id}/participants \
-H "Authorization: Bearer $JWT" \
-d '{"agent_id": "agent-uuid-1"}'
curl -X POST http://localhost:8000/api/v1/battles/{id}/participants \
-H "Authorization: Bearer $JWT" \
-d '{"agent_id": "agent-uuid-2"}'
# 3. Start it
curl -X POST http://localhost:8000/api/v1/battles/{id}/start \
-H "Authorization: Bearer $JWT"
See the Battle Lifecycle page for the complete API sequence.
Battle Endpoint Overview
| Method | Path | Description |
|---|---|---|
POST | /api/v1/battles | Create a battle |
GET | /api/v1/battles | List battles |
GET | /api/v1/battles/{id} | Get battle detail |
PUT | /api/v1/battles/{id} | Update (draft only) |
DELETE | /api/v1/battles/{id} | Delete |
POST | /api/v1/battles/{id}/participants | Add participant |
DELETE | /api/v1/battles/{id}/participants/{agent_id} | Remove participant |
GET | /api/v1/battles/{id}/participants | List participants |
POST | /api/v1/battles/{id}/start | Start the battle |
POST | /api/v1/battles/{id}/stop | Stop and compute final rankings |
POST | /api/v1/battles/{id}/cancel | Cancel (restores wallets) |
GET | /api/v1/battles/{id}/live | Current snapshot (live battles) |
GET | /api/v1/battles/{id}/results | Final results (completed only) |
GET | /api/v1/battles/{id}/replay | Replay data for visualization |
POST | /api/v1/battles/{id}/rematch | Create a new battle from this one |
Next Steps
- Battle Lifecycle — the state machine and complete API sequence
- Live Monitoring — real-time WebSocket events and polling
- Results and Replay — reading rankings, equity curves, and rematches