Quick Decision: Which API?
| Criterion |
TWS API (Recommended) |
Client Portal REST API |
| Best for |
Automated trading, portfolio mgmt |
Web dashboards, light usage |
| Auth |
Local login via TWS/IB Gateway |
OAuth 2.0 JWT |
| Performance |
Async, low latency, high throughput |
REST, slower |
| Data quality |
Tick-by-tick available |
Level 1 only |
| Multi-account |
All accounts simultaneously |
Per-request |
| Infrastructure |
Local Java app (port 7496/7497) |
HTTPS REST calls |
| Python library |
ib_async (recommended) |
requests + OAuth |
| Cost |
Free |
Free |
Default recommendation: TWS API via ib_async library for all programmatic work.
Account Architecture
Tim's setup: Roth IRA + Personal Brokerage + THK Enterprises (future business account)
- All linked under single IBKR username/password
- Single API session accesses all linked accounts
- Use
reqLinkedAccounts() to enumerate account IDs
- Specify account ID per order placement
- Market data subscriptions charged once across all linked accounts
- One active session per username — connecting elsewhere closes current session
IRA-Specific Restrictions (Critical)
| Restriction |
Impact |
| No short selling |
placeOrder() will reject short orders |
| No margin borrowing |
Cash-only (no debit balances) |
| No foreign currency borrowing |
Must execute FX trade first |
| Futures margin 2x higher |
Position sizing affected |
| MLPs/UBTI prohibited |
Filter these from IRA order flow |
| Withdrawals USD only |
Informational |
Core API Operations
Read Operations (Safe — use for all account types)
# Key TWS API functions for portfolio queries
reqLinkedAccounts() # List all account IDs
reqAccountSummary() # Balances, buying power, equity (all accounts)
reqPositions() # Current positions (up to 50 sub-accounts)
reqPositionsMulti() # Per-account positions (>50 sub-accounts)
reqAccountUpdates() # Stream account + position data (single account)
reqMktData() # Real-time Level 1 market data
reqHistoricalData() # Historical price data
Write Operations (Use with caution — respect IRA restrictions)
placeOrder(account_id, contract, order) # Place order on specific account
cancelOrder(order_id) # Cancel pending order
reqGlobalCancel() # Cancel all open orders
Client Portal REST Endpoints (Alternative)
GET /iserver/accounts # List accounts
GET /iserver/account/{id}/positions # Positions
GET /iserver/account/{id}/summary # Balances
POST /iserver/account/{id}/orders # Place order
GET /market/candle # Historical candles
Python Library: ib_async
Install: pip install ib_async
Why ib_async over alternatives:
- Modern successor to ib_insync (original creator's project continued)
- Native asyncio support
- Implements IBKR binary protocol internally (no need for official ibapi)
- Active maintenance (GitHub: ib-api-reloaded/ib_async)
Alternatives (use only if ib_async doesn't meet needs):
ib_insync — Legacy, stable but unmaintained since early 2024
ibapi — Official IBKR library, cumbersome event loop
Reference: Connection Pattern
See reference/connection-patterns.md for:
- IB Gateway setup and configuration
- Connection/reconnection handling
- Session timeout management (6-min ping for CP API)
- Multi-account query patterns
- Error handling and rate limit management
Reference: Trading Patterns
See reference/trading-patterns.md for:
- Order types (market, limit, stop, bracket, IB algos)
- IRA-safe order validation
- Multi-account order routing
- Position sizing with account-type awareness
- Greeks-aware options order flow
Infrastructure Requirements
- IB Gateway (lightweight) or TWS (full UI) running locally
- Java 8+ installed
- API enabled in TWS/Gateway settings
- Ports: 7496 (live) / 7497 (paper trading)
- Credentials: Stored in OS credential manager (never hardcode)
Security Best Practices
- Run IB Gateway on localhost only (no internet exposure)
- Use read-only login for portfolio queries when trading not needed
- Store credentials in macOS Keychain / Linux secret-service
- Implement session timeout handling
- Validate market data subscriptions before placing orders
- Log all order attempts with account ID + timestamp
Cost Structure
| Item |
Cost |
| API access |
Free |
| Market data |
$5-50/month per exchange subscription |
| Trading commissions |
Standard IBKR rates (varies by asset) |
| Account minimums |
$500 per account |
| Estimated total |
~$1,500 aggregate minimum; $15-50/month data |
Integration with Trading-Signals Skill
This skill complements the trading-signals-skill:
- trading-signals → generates signals, confluence scores, regime detection
- ibkr-api → executes trades, queries positions, manages accounts
- Pipeline: Signal generation → Position sizing → IRA validation → Order execution
IBKR MCP Server (Installed)
ArjunDivecha/ibkr-mcp-server is installed and configured:
- Location:
~/Desktop/tk_projects/ibkr-mcp-server/
- Claude Code: Added to
~/.claude.json (user scope)
- Claude Desktop: Added to
claude_desktop_config.json
- Mode: Paper trading (port 7497), live trading disabled
- Safety: Order cap 1,000 shares, confirmation required
Available MCP Tools
| Tool |
Purpose |
Account Types |
get_portfolio |
Positions + P&L |
All accounts |
get_account_summary |
Balances, margin, buying power |
All accounts |
switch_account |
Toggle Roth IRA / Personal / THK |
Multi-account |
get_market_data |
Real-time quotes |
N/A |
get_historical_data |
Historical OHLCV |
N/A |
place_order |
Orders with safety checks |
All (IRA restrictions enforced) |
check_shortable_shares |
Short availability |
Personal/Business only |
get_margin_requirements |
Margin needs per security |
Personal/Business only |
get_borrow_rates |
Borrow costs for shorts |
Personal/Business only |
short_selling_analysis |
Full short analysis package |
Personal/Business only |
get_connection_status |
IB Gateway health check |
N/A |
To Activate
- Start IB Gateway → port 7497 (paper) or 7496 (live)
- Enable API: Config → API → Settings → "ActiveX and Socket Clients"
- Add 127.0.0.1 to Trusted IPs
- Restart Claude Code / Claude Desktop
Other Community MCP Servers
code-rabi/interactive-brokers-mcp — Client Portal REST API
xiao81/IBKR-MCP-Server — TWS API focused
Hellek1/ib-mcp — Read-only via ib_async (safest)
Multi-Broker Aggregation
For unified view across IBKR + Robinhood:
- SnapTrade MCP (
dangelov/mcp-snaptrade) — Read-only aggregator, 15+ brokerages, OAuth-based (safe)
- Alpaca MCP (official) — Alternative broker with production-ready MCP
- Manual CSV import from Robinhood as fallback (ToS-safe)
See reference/multi-broker-strategy.md for aggregation patterns.
Emit Outcome Sidecar
As the final step, write to ~/.claude/skill-analytics/last-outcome-ibkr-api.json:
{"ts":"[UTC ISO8601]","skill":"ibkr-api","version":"1.0.0","variant":"default",
"status":"[success|partial|error]","runtime_ms":[estimated ms from start],
"metrics":{"queries_executed":[n],"positions_analyzed":[n],"accounts_checked":[n]},
"error":null,"session_id":"[YYYY-MM-DD]"}
Use status "partial" if some stages failed but results were produced. Use "error" only if no output was generated.
1---2name: ibkr-api-skill3description: Interactive Brokers (IBKR) API integration for portfolio management, account queries, and trade execution across multiple account types (Roth IRA, personal brokerage, business). Use when the user mentions IBKR, Interactive Brokers, IB Gateway, TWS API, Client Portal API, brokerage API, portfolio positions, account balances, placing trades via API, multi-account trading, IRA trading restrictions, or wants to build/debug code that connects to Interactive Brokers. Also triggers on "ib_async", "ib_insync", "ibapi", or any IBKR endpoint reference.4---5
6<objective>
7Build and manage Interactive Brokers (IBKR) integrations for portfolio queries, trade execution, and multi-account management across Roth IRA, personal brokerage, and business accounts using TWS API (ib_async) or Client Portal REST API.
8</objective>
9
10<quick_start>
111. Install: `pip install ib_async`
122. Start IB Gateway on port 7497 (paper) or 7496 (live)
133. Connect: `ib = IB(); await ib.connectAsync('127.0.0.1', 7497, clientId=1)`
144. Query: `positions = ib.positions()` / `summary = await ib.accountSummaryAsync()`
15</quick_start>
16
17<success_criteria>
18- API connection established and authenticated
19- Portfolio positions and balances retrieved across all linked accounts
20- IRA restrictions enforced on write operations
21- Credentials stored securely (never hardcoded)
22</success_criteria>
23
24## Quick Decision: Which API?
25
26| Criterion | TWS API (Recommended) | Client Portal REST API |
27|-----------|----------------------|----------------------|
28| **Best for** | Automated trading, portfolio mgmt | Web dashboards, light usage |
29| **Auth** | Local login via TWS/IB Gateway | OAuth 2.0 JWT |
30| **Performance** | Async, low latency, high throughput | REST, slower |
31| **Data quality** | Tick-by-tick available | Level 1 only |
32| **Multi-account** | All accounts simultaneously | Per-request |
33| **Infrastructure** | Local Java app (port 7496/7497) | HTTPS REST calls |
34| **Python library** | ib_async (recommended) | requests + OAuth |
35| **Cost** | Free | Free |
36
37**Default recommendation**: TWS API via **ib_async** library for all programmatic work.
38
39## Account Architecture
40
41Tim's setup: Roth IRA + Personal Brokerage + THK Enterprises (future business account)
42
43- All linked under single IBKR username/password
44- Single API session accesses all linked accounts
45- Use `reqLinkedAccounts()` to enumerate account IDs
46- Specify account ID per order placement
47- Market data subscriptions charged once across all linked accounts
48- **One active session per username** — connecting elsewhere closes current session
49
50### IRA-Specific Restrictions (Critical)
51
52| Restriction | Impact |
53|-------------|--------|
54| No short selling | `placeOrder()` will reject short orders |
55| No margin borrowing | Cash-only (no debit balances) |
56| No foreign currency borrowing | Must execute FX trade first |
57| Futures margin 2x higher | Position sizing affected |
58| MLPs/UBTI prohibited | Filter these from IRA order flow |
59| Withdrawals USD only | Informational |
60
61## Core API Operations
62
63### Read Operations (Safe — use for all account types)
64
65```python
66# Key TWS API functions for portfolio queries
67reqLinkedAccounts() # List all account IDs
68reqAccountSummary() # Balances, buying power, equity (all accounts)
69reqPositions() # Current positions (up to 50 sub-accounts)
70reqPositionsMulti() # Per-account positions (>50 sub-accounts)
71reqAccountUpdates() # Stream account + position data (single account)
72reqMktData() # Real-time Level 1 market data
73reqHistoricalData() # Historical price data
74```
75
76### Write Operations (Use with caution — respect IRA restrictions)
77
78```python
79placeOrder(account_id, contract, order) # Place order on specific account
80cancelOrder(order_id) # Cancel pending order
81reqGlobalCancel() # Cancel all open orders
82```
83
84### Client Portal REST Endpoints (Alternative)
85
86```
87GET /iserver/accounts # List accounts
88GET /iserver/account/{id}/positions # Positions
89GET /iserver/account/{id}/summary # Balances
90POST /iserver/account/{id}/orders # Place order
91GET /market/candle # Historical candles
92```
93
94## Python Library: ib_async
95
96**Install**: `pip install ib_async`
97
98**Why ib_async over alternatives:**
99- Modern successor to ib_insync (original creator's project continued)
100- Native asyncio support
101- Implements IBKR binary protocol internally (no need for official ibapi)
102- Active maintenance (GitHub: ib-api-reloaded/ib_async)
103
104**Alternatives** (use only if ib_async doesn't meet needs):
105- `ib_insync` — Legacy, stable but unmaintained since early 2024
106- `ibapi` — Official IBKR library, cumbersome event loop
107
108### Reference: Connection Pattern
109
110See `reference/connection-patterns.md` for:
111- IB Gateway setup and configuration
112- Connection/reconnection handling
113- Session timeout management (6-min ping for CP API)
114- Multi-account query patterns
115- Error handling and rate limit management
116
117### Reference: Trading Patterns
118
119See `reference/trading-patterns.md` for:
120- Order types (market, limit, stop, bracket, IB algos)
121- IRA-safe order validation
122- Multi-account order routing
123- Position sizing with account-type awareness
124- Greeks-aware options order flow
125
126## Infrastructure Requirements
127
1281. **IB Gateway** (lightweight) or **TWS** (full UI) running locally
1292. **Java 8+** installed
1303. **API enabled** in TWS/Gateway settings
1314. **Ports**: 7496 (live) / 7497 (paper trading)
1325. **Credentials**: Stored in OS credential manager (never hardcode)
133
134## Security Best Practices
135
136- Run IB Gateway on localhost only (no internet exposure)
137- Use read-only login for portfolio queries when trading not needed
138- Store credentials in macOS Keychain / Linux secret-service
139- Implement session timeout handling
140- Validate market data subscriptions before placing orders
141- Log all order attempts with account ID + timestamp
142
143## Cost Structure
144
145| Item | Cost |
146|------|------|
147| API access | Free |
148| Market data | $5-50/month per exchange subscription |
149| Trading commissions | Standard IBKR rates (varies by asset) |
150| Account minimums | $500 per account |
151| Estimated total | ~$1,500 aggregate minimum; $15-50/month data |
152
153## Integration with Trading-Signals Skill
154
155This skill complements the `trading-signals-skill`:
156- **trading-signals** → generates signals, confluence scores, regime detection
157- **ibkr-api** → executes trades, queries positions, manages accounts
158- Pipeline: Signal generation → Position sizing → IRA validation → Order execution
159
160## IBKR MCP Server (Installed)
161
162**ArjunDivecha/ibkr-mcp-server** is installed and configured:
163- **Location:** `~/Desktop/tk_projects/ibkr-mcp-server/`
164- **Claude Code:** Added to `~/.claude.json` (user scope)
165- **Claude Desktop:** Added to `claude_desktop_config.json`
166- **Mode:** Paper trading (port 7497), live trading disabled
167- **Safety:** Order cap 1,000 shares, confirmation required
168
169### Available MCP Tools
170
171| Tool | Purpose | Account Types |
172|------|---------|---------------|
173| `get_portfolio` | Positions + P&L | All accounts |
174| `get_account_summary` | Balances, margin, buying power | All accounts |
175| `switch_account` | Toggle Roth IRA / Personal / THK | Multi-account |
176| `get_market_data` | Real-time quotes | N/A |
177| `get_historical_data` | Historical OHLCV | N/A |
178| `place_order` | Orders with safety checks | All (IRA restrictions enforced) |
179| `check_shortable_shares` | Short availability | Personal/Business only |
180| `get_margin_requirements` | Margin needs per security | Personal/Business only |
181| `get_borrow_rates` | Borrow costs for shorts | Personal/Business only |
182| `short_selling_analysis` | Full short analysis package | Personal/Business only |
183| `get_connection_status` | IB Gateway health check | N/A |
184
185### To Activate
1861. Start IB Gateway → port 7497 (paper) or 7496 (live)
1872. Enable API: Config → API → Settings → "ActiveX and Socket Clients"
1883. Add 127.0.0.1 to Trusted IPs
1894. Restart Claude Code / Claude Desktop
190
191### Other Community MCP Servers
192- `code-rabi/interactive-brokers-mcp` — Client Portal REST API
193- `xiao81/IBKR-MCP-Server` — TWS API focused
194- `Hellek1/ib-mcp` — Read-only via ib_async (safest)
195
196## Multi-Broker Aggregation
197
198For unified view across IBKR + Robinhood:
199- **SnapTrade MCP** (`dangelov/mcp-snaptrade`) — Read-only aggregator, 15+ brokerages, OAuth-based (safe)
200- **Alpaca MCP** (official) — Alternative broker with production-ready MCP
201- Manual CSV import from Robinhood as fallback (ToS-safe)
202
203See `reference/multi-broker-strategy.md` for aggregation patterns.
204
205## Emit Outcome Sidecar
206
207As the final step, write to `~/.claude/skill-analytics/last-outcome-ibkr-api.json`:
208```json
209{"ts":"[UTC ISO8601]","skill":"ibkr-api","version":"1.0.0","variant":"default",
210 "status":"[success|partial|error]","runtime_ms":[estimated ms from start],
211 "metrics":{"queries_executed":[n],"positions_analyzed":[n],"accounts_checked":[n]},
212 "error":null,"session_id":"[YYYY-MM-DD]"}
213```
214Use status "partial" if some stages failed but results were produced. Use "error" only if no output was generated.