|
IBKR |
Architect |
Installation |
- Download and install TWS or IB Gateway
- “Before spending precious development time troubleshooting on the API side,
it is recommended to first experiment with the TWS directly.” – IBKR docs
- Configure TWS for API usage
- Download and install the IBKR API
|
pip install architect-py
|
Connect To Client |
First, ensure that TWS or IB Gateway is running on your computer.
If it crashes, you’ll lose your connection! Make sure it’s a compatible version as well.
from ibapi.client import EClient # send requests
from ibapi.wrapper import EWrapper # receive callbacks
import threading
class IBApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.nextId = None
app = IBApp()
app.connect("127.0.0.1", 7497, clientId=1)
threading.Thread(target=app.run, daemon=True).start()
|
Create keys at the linked webpage.
from architect_py import Client
client = Client(
api_key="API_KEY",
api_secret="API_SECRET",
paper_trading=False
)
|
Get Front Month Future |
These functions must be run in the context of a class, so to make it apples-to-apples
we won’t rewrite __init__ and connection lines.
Getting the front future is left as an exercise because it isn’t trivial.
from ibapi.contract import Contract
NQ_lead_future: Contract | None = None
class App(EWrapper, EClient):
def contractDetails(self, reqId, cd):
self._cd.append(cd) # gather every contract returned
def contractDetailsEnd(self, reqId):
global NQ_lead_future
futs = [cd.contract for cd in self._cd
if cd.contract.secType == "FUT"]
NQ_lead_future = min(
futs, key=lambda c: c.lastTradeDateOrContractMonth
) # earliest active expiry
print("Lead NQ future =", NQ_lead_future.localSymbol)
self.disconnect()
q = Contract()
q.symbol, q.secType, q.exchange = "NQ", "FUT+CONTFUT", "GLOBEX"
app.reqContractDetails(1, q)
|
NQ_lead_future = client.get_front_future(
"NQ CME Futures", "CME"
)
|
Fetch All Accounts |
class App(EWrapper, EClient):
def accountSummary(self, reqId, account, tag, val, currency):
print(account, tag, val, currency)
def accountSummaryEnd(self, reqId):
self.disconnect()
app.reqAccountSummary(1, "All", "All")
|
accounts = client.list_accounts()
|
Fetch Historical Fills |
class App(EWrapper, EClient):
def accountSummary(self, reqId, account, tag, val, currency):
print(account, tag, val, currency)
def execDetails(self, reqId, contract, execution):
print(execution.execId, contract.localSymbol,
execution.side, execution.shares, execution.price)
def execDetailsEnd(self, reqId):
self.disconnect()
app.reqExecutions(1, ExecutionFilter())
|
await client.get_fills()
|
Get The Midpoint Price |
mid = None
class App(EWrapper, EClient):
def tickPrice(self, reqId, tickType, price, _attrib):
if tickType == 1: # BID
self.bid = price
elif tickType == 2: # ASK
self.ask = price
if self.bid and self.ask:
mid = (self.bid + self.ask) / 2
self.cancelMktData(reqId)
self.disconnect()
app.reqMktData(1, NQ_lead_future, "", False, False, [])
|
snapshot = await client.get_l1_book_snapshot(
NQ_lead_future, "CME")
midpoint_price = (
snapshot.best_ask[0] + snapshot.best_bid[0]) / 2
|
Buy the Lead NQ Future At Midpoint Price |
from ibapi.order import Order
class App(EWrapper, EClient):
def nextValidId(self, orderId: int):
self.nextId = orderId
o = Order()
o.action = "BUY"
o.orderType = "LMT"
o.totalQuantity = 1
o.lmtPrice = MIDPOINT_PRICE
self.placeOrder(self.nextId, NQ_lead_future, o)
self.disconnect()
# Hard to control timing given network calls
|
from decimal import Decimal
from architect_py import OrderType, TimeInForce, OrderDir
order = await client.place_limit_order(
symbol=NQ_lead_future,
odir=OrderDir.BUY,
quantity=Decimal(1),
order_type=OrderType.LIMIT,
execution_venue="CME",
post_only=True,
limit_price=midpoint_price,
account=accounts[0].account.name,
time_in_force=TimeInForce.IOC,
)
|
API Docs |
IBKR API Docs
No search functionality.
|
Architect Python Docs
Cleaner docs with search.
|
Async and Sync Version? |
No – you’ll manage threading/async, pacing, and limited type hints yourself. |
Both synchronous and native async clients available. |
Customer Support |
Customer-service live chat (see Reddit for responsiveness complaints). |
Ultra-responsive, including a dedicated Slack channel. |