Orders
Live pending + filled orders across every broker NVTrader is wired to. Same wire shape regardless of broker — SimBroker, Alpaca paper, Webull (pending UAT) — so the table is identical and you can pivot accounts without restarting the app.
Overview
Two tables stacked: Pending (working at the venue) and Filled (terminal — filled, partially filled, cancelled, rejected). Toolbar at the top lets you switch the active broker and refresh.
Broker switcher
Click the broker chip in the header. The dropdown shows every broker with a linked account. The switch:
- Writes
data/runtime/active_broker.txt(a tiny file, atomic). - Future REST calls to
get_broker()read from that file first, thenBROKERenv, then settings, then"sim". - No process restart needed.
This is how you can be running an Alpaca paper account in the morning and a Webull UAT account in the afternoon, with one user, one server.
Switching brokers does not migrate positions. Each broker keeps its own position book. The dashboard shows whichever broker is active.
Columns explained
| column | meaning |
|---|---|
| id | NVTrader-internal order id (UUID). Used in audit + observability. |
| broker_order_id | What the venue assigned. Pasteable into the Alpaca / Webull dashboard for the underlying order. |
| symbol · side · qty | Self-explanatory. |
| type | market · limit · stop. |
| limit / stop | The price for non-market types. |
| status | Pending: new · accepted · partial. Filled: filled · cancelled · rejected. |
| avg_fill | VWAP across fills. |
| submitted_at · filled_at | UTC timestamps from the broker. |
| rationale | Short string from the agent that placed it (or "manual" if from the chat). |
Placing an order
Three paths:
- From the chat —
buy 2 NVDA at market. Kimi picksplace_order, fills args, calls the active broker, you get a table row back with the broker order id. - From the rebalance modal — Portfolio → Rebalance. Approving fans out N orders, one per non-zero target weight delta.
- From an agent — anything that publishes
RebalanceApprovedon the bus reachesExecutionBusAgent.handle(), which calls the same broker code path. See A2A event bus.
How to interpret fill behavior
- Submitted Sunday afternoon → "queued for next session" — Alpaca holds market orders until the open. This is normal.
- Filled in chunks — the venue split for liquidity;
avg_fillis the VWAP. - Status = rejected — read the broker's reason string in the rationale column. Common: PDT (pattern day trader) limit, insufficient buying power, restricted name.
- Pending forever — venue accepted but never matched. Cancel from the Orders page.
REST surface
| Verb | Path | Purpose |
|---|---|---|
| GET | /api/broker/active | Which broker is the runtime override pointing at. |
| POST | /api/broker/switch | Atomically swap the active broker. |
| GET | /api/broker/orders?status=pending | Working orders. |
| GET | /api/broker/orders?since=ISO | Orders submitted in a window. |
| POST | /api/broker/place | One-shot order. Body: {symbol, side, qty, type, limit?, stop?, rationale}. |
| DELETE | /api/broker/orders/{id} | Cancel a working order. |