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