Market depth (order book)

In [1]:
from ib_insync import *
util.startLoop()

ib = IB()
ib.connect('127.0.0.1', 7497, clientId=16)
Out[1]:
<IB connected to 127.0.0.1:7497 clientId=16>

To get a list of all exchanges that support market depth data and display the first five:

In [2]:
l = ib.reqMktDepthExchanges()
l[:5]
Out[2]:
[DepthMktDataDescription(exchange='DTB', secType='OPT', listingExch='', serviceDataType='Deep', aggGroup=2147483647),
 DepthMktDataDescription(exchange='LSEETF', secType='STK', listingExch='', serviceDataType='Deep', aggGroup=2147483647),
 DepthMktDataDescription(exchange='SGX', secType='FUT', listingExch='', serviceDataType='Deep', aggGroup=2147483647),
 DepthMktDataDescription(exchange='IDEALPRO', secType='CASH', listingExch='', serviceDataType='Deep', aggGroup=4),
 DepthMktDataDescription(exchange='ARCA', secType='STK', listingExch='', serviceDataType='Deep', aggGroup=2147483647)]

Let's subscribe to market depth data for EURUSD:

In [3]:
contract = Forex('EURUSD')
ib.qualifyContracts(contract)
ticker = ib.reqMktDepth(contract)

To see a live order book, an event handler for ticker updates is made that displays a dynamically updated dataframe:

In [4]:
from IPython.display import display, clear_output
import pandas as pd

df = pd.DataFrame(index=range(5),
        columns='bidSize bidPrice askPrice askSize'.split())

def onTickerUpdate(ticker):
    bids = ticker.domBids
    for i in range(5):
        df.iloc[i, 0] = bids[i].size if i < len(bids) else 0
        df.iloc[i, 1] = bids[i].price if i < len(bids) else 0
    asks = ticker.domAsks
    for i in range(5):
        df.iloc[i, 2] = asks[i].price if i < len(asks) else 0
        df.iloc[i, 3] = asks[i].size if i < len(asks) else 0
    clear_output(wait=True)
    display(df)

ticker.updateEvent += onTickerUpdate

IB.sleep(15);
bidSize bidPrice askPrice askSize
0 15500000 1.12265 1.12275 21500000
1 10200000 1.1226 1.1228 9000000
2 1000000 1.12255 1.12285 1000000
3 1000000 1.1225 1.1232 50000
4 0 0 0 0

Stop the market depth subscription:

In [5]:
ib.cancelMktDepth(contract)
In [6]:
ib.disconnect()