IBKR

Architect

Installation
  1. Download and install TWS or IB Gateway
  2. “Before spending precious development time troubleshooting on the API side,
    it is recommended to first experiment with the TWS directly.” – IBKR docs
  3. Configure TWS for API usage
  4. 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.

Having trouble using IBKR for your algorithmic trading strategy? We can make your life easier.

Sign up at app.architect.co or contact us by email: hello at architect.co!