A production-ready REST API wrapper for Interactive Brokers built with FastAPI and ib_insync. Provides a clean, simple interface for algorithmic trading, portfolio management, and order execution.
- ✅ Limit Orders - Buy/sell at specific prices
- ✅ Bracket Orders - Protected trades with automatic stop-loss and take-profit
- ✅ Order Tracking - Monitor pending orders in real-time
- ✅ Order Cancellation - Cancel unfilled orders programmatically
- ✅ Custom References - Tag orders for easy tracking
- ✅ Account Summary - Real-time balance and cash availability
- ✅ Position Tracking - Monitor all open positions with P&L
- ✅ Execution History - Track filled orders from multiple sources
- 🔒 Thread-Safe - Sequential command queue prevents race conditions
- 🔄 Auto-Reconnect - Manages IB Gateway connections automatically
- 📝 Type Safety - Pydantic models for request validation
- 🚀 Async/Await - Built on FastAPI for high performance
- 📚 Auto Documentation - Interactive API docs at
/docs - 🧪 Test Suite - Comprehensive testing included
This API is perfect for:
- Algorithmic Trading Systems - Execute trades programmatically
- Portfolio Management Tools - Monitor and rebalance portfolios
- Trading Bots - Automate trading strategies
- Risk Management - Implement stop-loss and take-profit automatically
- Research & Backtesting - Connect live data to analysis tools
- Python 3.8 or higher
- Interactive Brokers account (Paper Trading recommended for testing)
- IB Gateway or TWS installed
git clone https://github.com/IdoPeer14/ibkr-trading-api.git
cd ibkr-trading-api# Create virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install requirements
pip install -r requirements.txtSee IB_GATEWAY.md for detailed setup instructions.
Quick setup:
- Launch IB Gateway or TWS
- Go to Configure → Settings → API → Settings
- Enable: ✅ Enable ActiveX and Socket Clients
- Set Port: 4002 (Paper Trading)
- Add Trusted IP: 127.0.0.1
# Easy start with script
./start.sh
# Or manually
uvicorn main:app --host 127.0.0.1 --port 8000 --reloadServer runs at: http://localhost:8000
# Quick health check
curl http://localhost:8000/
# Get account info
curl http://localhost:8000/account
# Interactive docs
# Open browser: http://localhost:8000/docscurl http://localhost:8000/accountResponse:
{
"balance": 201879.04,
"cash": 200000.0
}curl http://localhost:8000/positionsResponse:
{
"positions": [
{
"symbol": "AAPL",
"qty": 10,
"avg_cost": 230.50,
"market_value": 2305.00
}
]
}curl -X POST http://localhost:8000/order/limit \
-H "Content-Type: application/json" \
-d '{
"symbol": "AAPL",
"action": "BUY",
"quantity": 10,
"limit_price": 230.00,
"order_ref": "my_trade_001"
}'Response:
{
"status": "✅ Limit order sent",
"permId": 1788680597
}Protected order with automatic stop-loss and take-profit:
curl -X POST http://localhost:8000/order/bracket \
-H "Content-Type: application/json" \
-d '{
"symbol": "AAPL",
"action": "BUY",
"quantity": 10,
"entry_price": 230.00,
"stop_loss": 225.00,
"take_profit": 240.00,
"order_ref": "protected_trade_001"
}'Response:
{
"status": "✅ Bracket order sent",
"permIds": [1788680598, 1788680599, 1788680600]
}curl http://localhost:8000/orderscurl -X POST http://localhost:8000/order/cancel \
-H "Content-Type: application/json" \
-d '{"perm_id": 1788680597}'# All executions
curl http://localhost:8000/executions
# Filtered by symbol
curl "http://localhost:8000/executions?symbol=AAPL"import requests
class IBKRClient:
def __init__(self, base_url="http://localhost:8000"):
self.base_url = base_url
def get_account(self):
response = requests.get(f"{self.base_url}/account")
return response.json()
def buy_limit(self, symbol, quantity, price, order_ref=None):
data = {
"symbol": symbol,
"action": "BUY",
"quantity": quantity,
"limit_price": price,
"order_ref": order_ref
}
response = requests.post(f"{self.base_url}/order/limit", json=data)
return response.json()
def bracket_order(self, symbol, action, quantity, entry, stop, profit):
data = {
"symbol": symbol,
"action": action,
"quantity": quantity,
"entry_price": entry,
"stop_loss": stop,
"take_profit": profit
}
response = requests.post(f"{self.base_url}/order/bracket", json=data)
return response.json()
# Usage
client = IBKRClient()
account = client.get_account()
print(f"Balance: ${account['balance']:,.2f}")
# Place protected order
order = client.bracket_order(
symbol="AAPL",
action="BUY",
quantity=10,
entry=230.00,
stop=225.00,
profit=240.00
)
print(f"Order placed: {order['permIds']}")const axios = require('axios');
class IBKRClient {
constructor(baseURL = 'http://localhost:8000') {
this.client = axios.create({ baseURL });
}
async getAccount() {
const { data } = await this.client.get('/account');
return data;
}
async buyLimit(symbol, quantity, price, orderRef = null) {
const { data } = await this.client.post('/order/limit', {
symbol,
action: 'BUY',
quantity,
limit_price: price,
order_ref: orderRef
});
return data;
}
async bracketOrder(symbol, action, quantity, entry, stop, profit) {
const { data } = await this.client.post('/order/bracket', {
symbol, action, quantity,
entry_price: entry,
stop_loss: stop,
take_profit: profit
});
return data;
}
}
// Usage
const ibkr = new IBKRClient();
(async () => {
const account = await ibkr.getAccount();
console.log(`Balance: $${account.balance}`);
const order = await ibkr.bracketOrder('AAPL', 'BUY', 10, 230, 225, 240);
console.log(`Order placed: ${order.permIds}`);
})();┌─────────────────┐
│ Client App │ (Python, JS, etc.)
└────────┬────────┘
│ HTTP REST
▼
┌─────────────────────────────────┐
│ FastAPI Server (Port 8000) │
│ ┌──────────────────────────┐ │
│ │ Routes │ │
│ └────────┬─────────────────┘ │
│ │ │
│ ┌────────▼─────────────────┐ │
│ │ Command Queue │ │ ← Thread-safe
│ │ (Sequential Execution) │ │
│ └────────┬─────────────────┘ │
│ │ │
│ ┌────────▼─────────────────┐ │
│ │ IBKR Modules │ │
│ │ - Positions │ │
│ │ - Orders │ │
│ │ - Executions │ │
│ └────────┬─────────────────┘ │
│ │ │
│ ┌────────▼─────────────────┐ │
│ │ IB Client Manager │ │
│ │ - Auto connect │ │
│ │ - Error handling │ │
│ └────────┬─────────────────┘ │
└────────────┼─────────────────────┘
│ ib_insync
▼
┌─────────────────────────────────┐
│ IB Gateway / TWS (Port 4002) │
└─────────────────────────────────┘
│ TWS API
▼
┌─────────────────────────────────┐
│ Interactive Brokers Platform │
└─────────────────────────────────┘
- Command Queue - Ensures thread-safe sequential execution
- Transient Connections - Opens/closes IB connection per request
- Pydantic Models - Type-safe request validation
- Async/Await - Non-blocking FastAPI operations
- Modular Structure - Separated concerns for maintainability
# Interactive test menu
python test_api.py
# Run all tests (safe mode)
python test_api.py --all# Comprehensive demonstration
python live_demo.pyThe demo will:
- ✅ Check account status
- ✅ Place test orders (low prices, won't fill)
- ✅ Monitor order status
- ✅ Cancel orders
- ✅ Show execution history
ibkr-trading-api/
├── main.py # FastAPI application entry point
├── requirements.txt # Python dependencies
├── start.sh # Quick start script
├── api/
│ └── routes.py # API route definitions
├── ibkr_api/
│ ├── client.py # IB connection management
│ ├── command_queue.py # Thread-safe command execution
│ ├── positions.py # Position tracking
│ ├── orders.py # Order management
│ ├── executions.py # Execution tracking
│ └── utils.py # Helper functions
├── test_api.py # Test suite
├── live_demo.py # Live demonstration
├── README.md # This file
└── IB_GATEWAY.md # IB Gateway setup guide
Create a .env file (optional):
IB_HOST=127.0.0.1
IB_PORT=4002 # 4002 for Paper, 4001 for Live
IB_CLIENT_ID=100
API_HOST=127.0.0.1
API_PORT=8000| Environment | Port | Risk Level |
|---|---|---|
| Paper Trading | 4002 | ✅ Safe for testing |
| Live Trading | 4001 |
# ✅ Good - Track your orders
order_ref = f"strategy_1_{timestamp}"
client.buy_limit("AAPL", 10, 230.00, order_ref=order_ref)
# ❌ Bad - No tracking
client.buy_limit("AAPL", 10, 230.00)# ✅ Good - Persistent storage
executions = client.get_executions()
for exec in executions:
database.save(exec) # Your database
# ❌ Bad - Rely on API (resets on restart)
executions = client.get_executions()# ✅ Good - Verify funds
account = client.get_account()
if account['cash'] >= required_cash:
client.buy_limit("AAPL", 10, 230.00)
else:
print("Insufficient funds!")# ✅ Good - Protected trade
client.bracket_order(
symbol="AAPL",
action="BUY",
quantity=10,
entry=230.00,
stop=225.00, # -2.2% risk
profit=240.00 # +4.3% reward
)
# ❌ Bad - No protection
client.buy_limit("AAPL", 10, 230.00)Solution:
- Verify IB Gateway/TWS is running
- Check API is enabled (Port 4002)
- Add 127.0.0.1 to trusted IPs
- Test connection:
telnet 127.0.0.1 4002
Common Causes:
- Price too far from market
- After-hours trading (9:30 AM - 4:00 PM ET only)
- Insufficient funds
- Stock halted/delisted
Explanation:
- Execution history resets when IB Gateway restarts
- Solution: Save executions to your own database
For more troubleshooting, see README.md in the original files.
- Interactive API Docs: http://localhost:8000/docs
- Alternative Docs: http://localhost:8000/redoc
- IB Gateway Setup: IB_GATEWAY.md
- IB API Documentation: https://interactivebrokers.github.io/tws-api/
- ib_insync Documentation: https://ib-insync.readthedocs.io/
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Test thoroughly with Paper Trading
- Commit:
git commit -m 'Add amazing feature' - Push:
git push origin feature/amazing-feature - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
IMPORTANT: This software is for educational and research purposes only.
- ❌ Not financial advice
- ❌ No guarantees of profit
- ❌ Trading involves risk of loss
- ❌ Past performance ≠ future results
Use at your own risk. The authors are not responsible for any financial losses.
Always:
- ✅ Test thoroughly with Paper Trading
- ✅ Understand the risks
- ✅ Never invest more than you can afford to lose
- ✅ Consult with financial professionals
- Interactive Brokers for the TWS API
- ib_insync for the excellent Python wrapper
- FastAPI for the amazing web framework
Built with ❤️ for algorithmic traders