Interactive Brokers è uno dei principali broker utilizzati dai trader algoritmici retail a causa dei suoi relativamente bassi requisiti minimi di capitale sul conto (10.000 USD) e la robusta API. In questo articolo faremo uso di un account demo per automatizzare gli ordini con l’API di Interactive Brokers, tramite Python e il package IBPy.
Nota: non ho alcuna affiliazione con Interactive Brokers. Ho avuto modo di usarlo in molti contesti e quindi ho familiarità con il loro software.
L' API di Interactive Brokers
Interactive Brokers è una grande azienda e in quanto tale si rivolge a una vasta gamma di operatori, che vanno dai trader retail discrezionali agli istituzionali automatizzati. Questo a fatto in modo che questo broker abbia sviluppato un’interfaccia GUI completa e robusta, la Trader Workstation (TWS).
Oltre a TWS c’è anche un semplice componente chiamato IB Gateway, che fornisce lo stesso accesso ai server di IB ma senza le funzionalità extra della GUI. Per i nostri scopi di trading automatico non avremo realmente bisogno della GUI TWS, ma penso che possa essere utile utilizzarla per questo tutorial dimostrativo.
L’architettura sottostante si basa su un modello client / server che offre sia feed di dati di esecuzione e di mercato (storici e in tempo reale) tramite un’API. Utilizzeremo questa API per inviare ordini automatici, tramite IBPy.
IBPy è stato scritto per “avvolgere” l’API Java nativa e renderla semplice da essere chiamata tramite Python. Le due principali librerie a cui siamo interessati all’interno di IBPy sono ib.ext
e ib.opt
. Quest’ultimo è di livello superiore e fa uso della funzionalità nel primo.
Nella seguente implementazione creeremo un esempio estremamente semplice, che invierà semplicemente un singolo ordine di mercato per acquistare 100 unità di azioni Google, utilizzando il routing intelligente degli ordini. Quest’ultimo è progettato per ottenere il miglior prezzo, anche se in determinate situazioni può non essere ottimale. Tuttavia, sarà sufficiente per gli scopi di questo tutorial.
Implementazione in Python
Prima di iniziare è necessario aver attivato un account su Interactive Brokers. Inoltre è necessario disporre di uno ambiente di lavoro in in modo da poter installare IBPy, che ti consentirà di legare insieme altri aspetti del tuo codice. Per creare un ambiente Python puoi leggere il mio precedente articolo su come installare di un ambiente di backtesting in Python.
Installare IBPy
sudo apt-get install git-core
mkdir ~/ibapi
git clone
cd ~/ibapi/IbPy
python setup.py.in install
Trading Automatico
Il seguente codice implementa una semplice gestione degli ordine basato sulle API. Il codice è lontano dall’essere usato in produzione, ma dimostra la funzionalità essenziale dell’API di Interactive Brokers e come utilizzarla per l’esecuzione degli ordini.
Tutto il seguente codice è contenuto nel file ib_api_demo.py
. Il primo passaggio consiste nell’importare gli oggetti Contract
e Order
dalla libreria ib.ext
. Inoltre importiamo gli oggetti Connection
e message
dalla libreria ib.opt
.
# ib_api_demo.py
from ib.ext.Contract import Contract
from ib.ext.Order import Order
from ib.opt import Connection, message
IB ci offre la possibilità di gestire gli errori e le risposte del server tramite un meccanismo di callback. Le seguenti due funzioni non fanno altro che stampare il contenuto dei messaggi restituiti dal server. Un sistema di produzione più sofisticato dovrebbe implementare la logica per assicurare il funzionamento continuo del sistema nel caso di generazione di eccezioni:
# ib_api_demo.py
def error_handler(msg):
"""Gestione per la cattura dei messagi di errori"""
print("Server Error: %s" % msg)
def reply_handler(msg):
"""Gestione delle risposte dal server"""
print("Server Response: %s, %s" % (msg.typeName, msg))
Le seguenti due funzioni completano la creazione degli oggetti Contract
e Order
, impostando i rispettivi parametri:
# ib_api_demo.py
def create_contract(symbol, sec_type, exch, prim_exch, curr):
"""
Crea un oggetto Contract definendo cosa sarà
acquistato, in quale exchange e in quale valuta.
symbol - Il simbolo del ticker per il contratto
sec_type - Il tipo di asset per il contratto ("STK" è "stock")
exch - La borsa su cui eseguire il contratto
prim_exch - Lo scambio principale su cui eseguire il contratto
curr - La valuta in cui acquistare il contratto
"""
contract = Contract()
contract.m_symbol = symbol
contract.m_secType = sec_type
contract.m_exchange = exch
contract.m_primaryExch = prim_exch
contract.m_currency = curr
return contract
def create_order(order_type, quantity, action):
"""
Crea un oggetto Ordine (Market/Limit) per andare long/short.
order_type - "MKT", "LMT" per ordini a mercato o limite
quantity - Numero intero di asset dell'ordine
action - 'BUY' o 'SELL'
"""
order = Order()
order.m_orderType = order_type
order.m_totalQuantity = quantity
order.m_action = action
return order
La funzione __main__
inizialmente crea un oggetto Connection
verso Trader Workstation, che deve essere in esecuzione affinché il codice funzioni. Le funzioni di gestione degli errori e di risposta vengono quindi registrate con l’oggetto di connessione. Successivamente viene definita una variabile order_id
. In un sistema di produzione questo deve essere incrementato per ogni ordine.
I passi successivi sono la creazione di un Contract
e di un Order
che rappresenta un market-order per acquistare 100 unità di azioni Google. L’ultimo compito è quello di piazzare quell’ordine tramite il metodo placeOrder dell’oggetto Connection. Quindi ci disconnettiamo da TWS:
# ib_api_demo.py
if __name__ == "__main__":
# Collegarsi alla Trader Workstation (TWS) in esecuzione
# sulla solita porta 7496, con un clientId di 100
# (Il clientId è scelto da noi e avremo bisogno di
# ID separati sia per la connessione di esecuzione che per
# connessione dati di mercato)
tws_conn = Connection.create(port=7496, clientId=100)
tws_conn.connect()
# Assegna la funzione di gestione degli errori definita
# sopra alla connessione TWS
tws_conn.register(error_handler, 'Error')
# Assegna tutti i messaggi di risposta del server alla
# funzione reply_handler definita sopra
tws_conn.registerAll(reply_handler)
# Crea un ordine ID che sia "globale" per questa sessione. Questo
# dovrà essere incrementato una volta inviati nuovi ordini.
order_id = 1
# Crea un contratto in stock GOOG tramite il routing degli ordini SMART
goog_contract = create_contract('GOOG', 'STK', 'SMART', 'SMART', 'USD')
# si va long di 100 azioni di Google
goog_order = create_order('MKT', 100, 'BUY')
# Uso della connessione per inviare l'ordine a IB
tws_conn.placeOrder(order_id, goog_contract, goog_order)
# Disconnessione da TWS
tws_conn.disconnect()
python ib_api_demo.py
Immediatamente si può vedere che si apre un tab “API” su Trader Workstation, mostrando il market order per andare long di 100 azioni su Google
Per il codice completo riportato in questo articolo utilizzando il modulo di backtesting vettoriale VectorBacktest si può consultare il seguente repository di github:
https://github.com/datatrading-info/VectorBacktest