Agentic Trading
Let your AI agent send limit orders to your connected brokers: switch it on in Settings, preview every order, then place it with a confirmation tied to that exact order. Every attempt is audited.
Turn it on
Agentic trading is off for every account. The account owner switches it on in the dashboard under Settings → AI Agent Trading. It cannot be switched on through the API or MCP. Until it is on, order calls return 403 agent_trading_disabled; reading positions, performance, indicators and alerts never needs it.
The same endpoints back the MCP tools list_trading_accounts, preview_order, place_order, cancel_order and list_agent_orders.
Trading accounts
/trading/accountsThe accounts you can pick in the trade window (SnapTrade brokers with trading access, TradeZero, TradeStation, broker MCP connections and your paper account), each with its accountId and what it supports, plus whether agentic trading is on.
1. Preview
/trading/orders/previewValidates the order, checks it against the account's broker rules, prices every leg at the live quote and lists warnings (a limit far from the mid, a wide or missing quote, a credit / debit mismatch). With agentic trading on it returns a confirmationToken valid for 5 minutes for this exact order. Nothing is placed.
assetType"option"requiredaccountIdstringrequiredlegsarray (1-4)requiredsymbol, strike, expiration (YYYY-MM-DD), optionType CALL | PUT, action BUY_TO_OPEN | SELL_TO_OPEN | BUY_TO_CLOSE | SELL_TO_CLOSE, quantity (1-100 contracts).limitPricenumberrequiredpriceEffectstringassetType"stock"requiredaccountIdstringrequiredsymbol / actionstringrequiredquantitynumberrequiredlimitPricenumberrequiredcurl -X POST "https://quantwheel.com/api/v1/trading/orders/preview" \
-H "Authorization: Bearer qw_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"order": {
"assetType": "option",
"accountId": "acc_1",
"legs": [{ "symbol": "SPY", "strike": 550, "expiration": "2026-11-20",
"optionType": "PUT", "action": "SELL_TO_OPEN", "quantity": 1 }],
"limitPrice": 5.65
}
}'{
"order": { "assetType": "option", "accountId": "acc_1", "limitPrice": 5.65, "legs": [ ... ] },
"description": "SELL_TO_OPEN 1 SPY 2026-11-20 550 PUT @ 5.65",
"account": { "accountId": "acc_1", "name": "Schwab", "broker": "snaptrade",
"capabilities": { "optionOrders": true, "multiLegOptionOrders": true, "stockOrders": true, "cancelAgentOrders": true } },
"estimate": {
"legs": [{ "symbol": "SPY", "strike": 550, "bid": 5.5, "ask": 5.8, "mid": 5.65,
"estimatedValuePerShare": 5.65, "priceSource": "mid" }],
"units": 1,
"estimatedNetPerShare": 5.65,
"estimatedEffect": "CREDIT",
"limitTotal": 565,
"estimatedTotal": 565,
"warnings": []
},
"agentTrading": { "enabled": true },
"confirmationToken": "qwo1.1792687512.Zk3...",
"confirmationExpiresAt": "2026-10-22T15:05:12.000Z",
"next": "Show this preview ... to the user. Only after the user explicitly confirms ..."
}2. Place
/trading/ordersSend the order exactly as previewed with its confirmationToken, after the user confirmed it. Any change (quantity, strike, price, account) needs a new preview, otherwise the call returns 403 confirmation_invalid. Pass an idempotencyKey (or the Idempotency-Key header) and reuse it on retries: a repeated key returns the first outcome with duplicate: true and never sends a second order.
curl -X POST "https://quantwheel.com/api/v1/trading/orders" \
-H "Authorization: Bearer qw_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2d0e-spy-csp-1" \
-d '{ "order": { ...exactly as previewed... }, "confirmationToken": "qwo1.1792687512.Zk3..." }'{
"orderId": "cm2x9agent0001",
"action": "PLACE",
"status": "SUBMITTED",
"channel": "API",
"accountId": "acc_1",
"broker": "snaptrade",
"description": "SELL_TO_OPEN 1 SPY 2026-11-20 550 PUT @ 5.65",
"brokerageOrderId": "b-77831",
"error": null,
"createdAt": "2026-10-22T15:01:02.000Z",
"completedAt": "2026-10-22T15:01:03.000Z",
"duplicate": false,
"message": "Order submitted successfully"
}| Error code | Meaning |
|---|---|
agent_trading_disabled | The owner has not switched on agentic trading. |
confirmation_invalid | No, an expired, or a mismatched confirmation token. Preview again. |
broker_rejected | The broker or its order route refused the order; error has its reason. |
rate_limited | More than 10 agent orders a minute. |
Cancel
/trading/orders/{orderId}/cancelCancels a working order an agent placed, by the orderId from the log. Supported on SnapTrade brokers and TradeStation. Other orders, and any order you placed yourself, are cancelled in the QuantWheel orders panel or with the broker.
Audit log
/trading/orders?limit=25Every place and cancel attempt, newest first: SUBMITTED, REJECTED, FAILED, DENIED (trading off, bad token, unknown account) or REQUESTED (in flight), with the channel (API or MCP), the order and the broker order id. Rows are written before the order reaches the broker.
Safety model
- Off by default, switched on only by a signed-in person in the dashboard.
- LIMIT orders only, 1-100 contracts per leg or up to 10,000 shares.
- Preview first; the token is bound to the user, the exact order and 5 minutes.
- The order goes through the same route as the trade window, so every plan, terms and broker check still applies.
- 10 agent orders a minute per account across API and MCP.
- MCP marks place_order and cancel_order destructive, so clients ask before calling them.