Broker Layer — New MCP Tools¶
Problem¶
Current trading tools (trading_place_limit_order, etc.) work by automating TradingView's UI — clicking buttons, filling forms, scraping order tables. This is:
- Fragile: Breaks when TradingView updates CSS selectors
- Slow: 2-5 seconds per operation (wait for UI transitions)
- Limited: No access to account data, position sizing, or order types beyond what the UI exposes
- Paper Trading only: No real broker connection
Solution: Direct Broker API MCP Tools¶
Add new MCP tools that call broker APIs directly, bypassing TradingView's trading panel entirely.
Broker: Tradovate¶
API: REST + WebSocket Auth: OAuth 2.0 (client credentials or authorization code) Docs: https://api.tradovate.com Markets: CME futures (ES, NQ, CL, GC, etc.)
New Tools¶
broker_tradovate_connect¶
Authenticate with Tradovate API.
Params:
credentials: "demo" | "live" # Which environment
Returns:
{ connected: true, account_id: "...", environment: "demo", balance: 50000 }
broker_tradovate_account¶
Get account info (balance, margin, buying power).
Params: (none)
Returns:
{ account_id, balance, available_margin, realized_pnl, unrealized_pnl }
broker_tradovate_place_order¶
Place an order via API.
Params:
symbol: string # "ESU6", "NQU6", "CLV6"
side: "buy" | "sell"
type: "limit" | "market" | "stop" | "stop_limit"
quantity: number # Number of contracts
price?: number # Required for limit/stop_limit
stop_price?: number # Required for stop/stop_limit
bracket?: {
take_profit: number # Limit price for profit target
stop_loss: number # Stop price for protective stop
}
time_in_force: "day" | "gtc" | "ioc" | "fok"
Returns:
{ order_id, status: "pending" | "filled" | "rejected", fill_price?, message? }
broker_tradovate_modify_order¶
Modify a pending order (price, quantity, bracket levels).
Params:
order_id: string
price?: number
quantity?: number
bracket?: { take_profit?: number, stop_loss?: number }
Returns:
{ order_id, status: "modified", new_price, new_quantity }
broker_tradovate_cancel_order¶
Cancel a pending order.
Params:
order_id: string
Returns:
{ order_id, status: "cancelled" }
broker_tradovate_get_orders¶
List all orders (pending, filled, cancelled).
Params:
status?: "pending" | "filled" | "cancelled" | "all"
Returns:
[{ order_id, symbol, side, type, quantity, price, status, fill_price, timestamp }]
broker_tradovate_get_positions¶
List open positions.
Params: (none)
Returns:
[{ symbol, side, quantity, avg_price, unrealized_pnl, margin_used }]
broker_tradovate_close_position¶
Flatten a position (market order to close).
Params:
symbol: string
Returns:
{ symbol, closed_quantity, fill_price, realized_pnl }
broker_tradovate_get_fills¶
Get recent fill history.
Params:
symbol?: string
limit?: number # Default 50
Returns:
[{ fill_id, order_id, symbol, side, quantity, price, timestamp }]
Broker: Interactive Brokers (IBKR)¶
API: Client Portal API (REST) or TWS API (socket) Auth: Session-based (Client Portal) or TWS gateway Markets: All asset classes (stocks, options, futures, forex)
New Tools¶
broker_ibkr_connect¶
Authenticate with IBKR Client Portal or TWS gateway.
Params:
mode: "portal" | "tws" # Client Portal REST or TWS socket
port?: number # TWS gateway port (default 7497 paper, 7496 live)
Returns:
{ connected: true, account_id: "...", mode: "paper" | "live" }
broker_ibkr_account¶
Get account summary.
Params: (none)
Returns:
{ account_id, net_liquidation, available_funds, buying_power, cushion }
broker_ibkr_place_order¶
Place an order.
Params:
symbol: string # Contract identifier (e.g., "ES", "AAPL")
sec_type: "FUT" | "STK" | "OPT" | "FX"
side: "buy" | "sell"
type: "limit" | "market" | "stop" | "stop_limit" | "trail"
quantity: number
price?: number
stop_price?: number
trail_amount?: number
bracket?: { take_profit: number, stop_loss: number }
time_in_force: "day" | "gtc" | "ioc"
Returns:
{ order_id, status, message? }
broker_ibkr_modify_order¶
Modify pending order.
Params:
order_id: string
price?: number
quantity?: number
stop_price?: number
Returns:
{ order_id, status: "modified" }
broker_ibkr_cancel_order¶
Cancel pending order.
Params:
order_id: string
Returns:
{ order_id, status: "cancelled" }
broker_ibkr_get_orders¶
List orders.
Params:
status?: "pending" | "filled" | "cancelled" | "all"
Returns:
[{ order_id, symbol, side, type, quantity, price, status, timestamp }]
broker_ibkr_get_positions¶
List open positions.
Params: (none)
Returns:
[{ symbol, sec_type, side, quantity, avg_price, market_price, unrealized_pnl }]
broker_ibkr_close_position¶
Flatten position.
Params:
symbol: string
sec_type: "FUT" | "STK" | "OPT" | "FX"
Returns:
{ symbol, closed_quantity, fill_price, realized_pnl }
broker_ibkr_get_fills¶
Recent fill history.
Params:
symbol?: string
limit?: number
Returns:
[{ fill_id, order_id, symbol, side, quantity, price, commission, timestamp }]
Shared / Broker-Agnostic Tools¶
These tools work across any connected broker:
broker_status¶
Check which broker is connected and its state.
Returns:
{ broker: "tradovate" | "ibkr" | "paper" | "none", environment: "demo" | "live", connected: boolean }
broker_position_size¶
Calculate position size based on risk parameters.
Params:
account_balance?: number # Override (otherwise reads from broker)
risk_percent: number # e.g., 1.0 for 1%
entry_price: number
stop_price: number
tick_size: number # e.g., 0.25 for ES
tick_value: number # e.g., 12.50 for ES
Returns:
{ risk_dollars, stop_distance_ticks, position_size, margin_required }
broker_risk_check¶
Pre-flight validation before placing an order.
Params:
symbol: string
side: "buy" | "sell"
quantity: number
entry_price: number
stop_price: number
Returns:
{ approved: boolean, risk_dollars, risk_percent, margin_available, warnings: [] }
Implementation Plan¶
Phase 1: Tradovate Demo¶
- Add
src/core/broker-tradovate.js— REST client with OAuth - Add
src/tools/broker.js— MCP tool registrations - Test against Tradovate demo environment
- Wire into FATBot dashboard position/order panels
Phase 2: IBKR Paper¶
- Add
src/core/broker-ibkr.js— Client Portal REST or TWS socket - Extend
src/tools/broker.jswith IBKR tools - Test against IBKR paper trading
Phase 3: Risk Controls¶
- Implement
broker_position_sizeandbroker_risk_check - Add max position limits, daily loss limits
- Require confirmation for live environment orders
Phase 4: Live Trading¶
- Enable live environment credentials (with explicit user confirmation)
- Add order audit log
- Add kill-switch tool (
broker_flatten_all)
Safety Requirements¶
- Demo/paper first — All tools must work in demo/paper before live
- Explicit environment selection — Never default to live
- Risk checks before orders —
broker_risk_checkshould be called beforebroker_*_place_order - Confirmation for destructive actions — Flatten all, cancel all
- Audit logging — Every order action logged with timestamp
- Max position limits — Configurable per-symbol contract limits
- Daily loss limit — Stop trading if daily P&L exceeds threshold
- No credentials in code — Use environment variables or secure config