In [1]:
from ib_insync import *
util.startLoop()
ib = IB()
ib.connect('127.0.0.1', 7497, clientId=15)
Out[1]:
In [2]:
contracts = [Forex(pair) for pair in ('EURUSD', 'USDJPY', 'GBPUSD', 'USDCHF', 'USDCAD', 'AUDUSD')]
ib.qualifyContracts(*contracts)
eurusd = contracts[0]
Request streaming ticks for them:
In [3]:
for contract in contracts:
ib.reqMktData(contract, '', False, False)
Wait a few seconds for the tickers to get filled.
In [4]:
ticker = ib.ticker(eurusd)
ib.sleep(2)
ticker
Out[4]:
The price of Forex ticks is always nan. To get a midpoint price use midpoint()
or marketPrice()
.
The tickers are kept live updated, try this a few times to see if the price changes:
In [5]:
ticker.marketPrice()
Out[5]:
The following cell will start a 30 second loop that prints a live updated ticker table. It is updated on every ticker change.
In [6]:
from IPython.display import display, clear_output
import pandas as pd
df = pd.DataFrame(
index=[c.pair() for c in contracts],
columns=['bidSize', 'bid', 'ask', 'askSize', 'high', 'low', 'close'])
def onPendingTickers(tickers):
for t in tickers:
df.loc[t.contract.pair()] = (
t.bidSize, t.bid, t.ask, t.askSize, t.high, t.low, t.close)
clear_output(wait=True)
display(df)
ib.pendingTickersEvent += onPendingTickers
ib.sleep(30)
ib.pendingTickersEvent -= onPendingTickers
New tick data is available in the 'ticks' attribute of the pending tickers. The tick data will be cleared before the next update.
To stop the live tick subscriptions:
In [7]:
for contract in contracts:
ib.cancelMktData(contract)
The ticks in the previous section are time-sampled by IB in order to cut on bandwidth. So with reqMktdData
not every tick from the exchanges is sent. The promise of reqTickByTickData
is to send every tick, just how it appears in the TWS Time & Sales window. This functionality is severly nerfed by a total of just three simultaneous subscriptions, where bid-ask ticks and sale ticks also use up a subscription each.
The tick-by-tick updates are available from ticker.tickByTicks
and are signalled by ib.pendingTickersEvent
or ticker.updateEvent
.
In [8]:
ticker = ib.reqTickByTickData(eurusd, 'BidAsk')
ib.sleep(2)
print(ticker)
ib.cancelTickByTickData(ticker.contract, 'BidAsk')
In [9]:
import datetime
start = ''
end = datetime.datetime.now()
ticks = ib.reqHistoricalTicks(eurusd, start, end, 1000, 'BID_ASK', useRth=False)
ticks[-1]
Out[9]:
In [10]:
ib.disconnect()