Saltar al contenido principal

Your first paper trading session

Goal: drive a paper-trading session from the bot you authored in first-bot. End-to-end: dispatch → fills → kill.

Why

Paper trading is the highest-fidelity dress rehearsal AlphaSwarm supports without putting real money at risk. Same broker abstraction, same risk overlays, same kill-switch wiring as live trading. The difference is that fills come from the simulated execution engine in alphaswarm/trading/paper_trading.py.

See Concept: paper trading.

Step 1 — verify the bot is ready

curl http://localhost:8000/bots/<bot_id>

Confirm the response includes a recent backtest_runs reference and non-zero sharpe. The paper-metadata-gate will refuse to start the session otherwise.

Step 2 — start the session

curl -X POST http://localhost:8000/bots/<bot_id>/paper \
-d '{"starting_cash":100000,"duration_minutes":60}'

The response includes paper_run_id. The session is now in the canonical Celery loop; alphaswarm-worker polls the broker every 1 second.

Step 3 — watch the WebSocket

In a browser console:

const ws = new WebSocket("ws://localhost:8000/ws/paper/<paper_run_id>");
ws.onmessage = (e) => {
const frame = JSON.parse(e.data);
console.log(frame.stage, frame.message, frame.equity, frame.positions);
};

You should see:

  • bar.received — every minute bar.
  • signal.emitted — when the strategy says "buy" / "sell" / "flat".
  • order.placed — order goes to the simulated broker.
  • order.filled — fill comes back; positions update.
  • equity.update — equity-curve point at the end of each bar.

All frames follow the canonical {task_id, stage, message, timestamp, **extras} envelope per AGENTS rule 4.

Step 4 — risk + kill switch

The bot's risk block (Step 1 of first-bot) is enforced by alphaswarm/risk/limits.py::RiskLimits. Once any limit is hit, the session emits risk.halted and stops.

The topbar kill switch in the Vite UI fans out to:

  • POST /bots/halt-all
  • POST /paper/stop-all
  • POST /agents/halt
  • POST /rl/halt-all
  • POST /workflows/halt
  • POST /terraform/halt
  • POST /quant-agents/halt

The whole stack stops in under 250 ms.

Step 5 — inspect the ledger

SELECT id, bot_id, status, total_pnl, num_fills, started_at, ended_at
FROM paper_trading_runs ORDER BY started_at DESC LIMIT 1;

SELECT order_id, symbol, side, qty, price, filled_at
FROM paper_fills
WHERE paper_run_id = '<from_above>'
ORDER BY filled_at;

Verify

  • WebSocket delivered at least one order.filled frame.
  • paper_trading_runs row has non-NULL total_pnl.
  • Kill switch closed the session.

What next