使用 Python、IBPy 和 Interactive Brokers API 实现交易自动化
不久前,我们讨论了如何设置 Interactive Brokers 模拟账户。Interactive Brokers 是零售算法交易者使用的主要经纪商之一,因为它的最低账户余额要求相对较低(10,000 美元)且 API(相对)简单。在本文中,我们将使用模拟账户通过 Python 和 IBPy 插件自动执行 Interactive Brokers API 交易。
披露:我与 Interactive Brokers 没有任何关系。我之前在专业基金环境中使用过它们,因此熟悉它们的软件。
盈透证券 API
Interactive Brokers 是一家大型企业,因此服务范围广泛,从自由散户到自动化机构。这使得他们的 GUI 界面 Trader Workstation (TWS) 拥有大量“花哨”的功能。
除了 TWS 之外,还有一个轻量级组件,称为 IB 网关,它提供对 IB 服务器的相同访问,尽管没有 GUI 的额外功能。对于我们的自动交易目的,我们实际上不需要 TWS GUI,但我认为在本教程中使用它具有示范作用。
底层架构基于客户端/服务器模型,通过 API 提供执行和市场数据(历史和实时)。在本教程中,我们将利用此 API 通过 IBPy 发送自动订单。
IBPy 的编写是为了“包装”原生 Java API,使其可以直接从 Python 调用。我们感兴趣的 IBPy 中的两个主要库是ib.ext
和ib.opt
。后者是更高级别的,并使用了前者中的功能。
在以下实施中,我们将创建一个非常简单的示例,该示例将使用智能订单路由简单地发送一个购买 100 股 Google 股票的市价订单。后者旨在在实践中实现最佳价格,尽管在某些情况下它可能不是最优的。然而,对于本教程的目的来说,这就足够了。
Python 中的实现
在开始之前,我们必须遵循先前教程中关于设置 Interactive Brokers 帐户的步骤。此外,还需要有一个先前的 Python 工作区,以便我们可以安装IBPy,这将允许您将代码的其他方面结合在一起。有关安装 Python 研究环境的教程将创建必要的工作区。
安装 IBPy
IBPy是一个基于 Java 的 Interactive Brokers API 编写的 Python 包装器。它使用 Python 开发算法交易系统变得不那么麻烦。它将被用作与 Interactive Brokers 的所有后续通信的基础,直到我们稍后考虑 FIX 协议。
由于 IBPy 在GitHub上作为git存储库维护,因此我们需要安装 git。在 Ubuntu 系统上,此操作由以下方式处理:
sudo apt-get install git-core
安装 git 后,您可以创建一个子目录来存储 IBPy。在我的系统上,我只是将其放在我的主目录下:

mkdir ~/ibapi
下一步是通过以下方式下载 IBPy git clone
:
cd ~/ibapi
git clone https://github.com/blampe/IbPy
确保进入 IbPy 目录并使用首选的 Python 虚拟环境进行安装:
cd ~/ibapi/IbPy
python setup.py.in 安装
这样就完成了 IBPy 的安装。下一步是打开 TWS(如上一个教程中所述)。
TWS 投资组合视图(Google Trade 之前)
自动交易
以下代码将演示一个非常简单的基于 API 的订单机制。该代码远未投入生产,但它确实演示了 Interactive Brokers API 的基本功能以及如何使用它来执行订单。
以下所有代码都应位于ib_api_demo.py
文件中。第一步是从较低级别的库导入Contract
和对象。此外,我们还从较高级别的库导入和对象:Order``ib.ext``Connection``message``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 为我们提供了通过回调机制处理错误和服务器响应的能力。以下两个函数的作用只是打印出从服务器返回的消息内容。更复杂的生产系统必须实现逻辑,以确保在出现异常行为时系统能够持续运行:
# ib_api_demo.py
def error_handler(msg):
"""Handles the capturing of error messages"""
print "Server Error: %s" % msg
def reply_handler(msg):
"""Handles of server replies"""
print "Server Response: %s, %s" % (msg.typeName, msg)
Contract
以下两个函数包装了和对象的创建Order
,并设置了各自的参数。函数文档分别描述了每个参数:
# ib_api_demo.py
def create_contract(symbol, sec_type, exch, prim_exch, curr):
"""Create a Contract object defining what will
be purchased, at which exchange and in which currency.
symbol - The ticker symbol for the contract
sec_type - The security type for the contract ('STK' is 'stock')
exch - The exchange to carry out the contract on
prim_exch - The primary exchange to carry out the contract on
curr - The currency in which to purchase the contract"""
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):
"""Create an Order object (Market/Limit) to go long/short.
order_type - 'MKT', 'LMT' for Market or Limit orders
quantity - Integral number of assets to order
action - 'BUY' or 'SELL'"""
order = Order()
order.m_orderType = order_type
order.m_totalQuantity = quantity
order.m_action = action
return order
该__main__
函数最初为 Trader Workstation 创建一个Connection
对象,该对象必须运行才能使代码发挥作用。然后,错误和回复处理程序函数将注册到连接对象。随后order_id
定义一个变量。在生产系统中,必须为每个交易订单增加该变量。
接下来的步骤是创建一个Contract
和一个代表购买 100 股 Google 股票的市价订单。最后的任务是通过对象的方法Order
实际下达该订单。然后我们断开与 TWS 的连接:placeOrder``Connection
# ib_api_demo.py
if __name__ == "__main__":
# Connect to the Trader Workstation (TWS) running on the
# usual port of 7496, with a clientId of 100
# (The clientId is chosen by us and we will need
# separate IDs for both the execution connection and
# market data connection)
tws_conn = Connection.create(port=7496, clientId=100)
tws_conn.connect()
# Assign the error handling function defined above
# to the TWS connection
tws_conn.register(error_handler, 'Error')
# Assign all of the server reply messages to the
# reply_handler function defined above
tws_conn.registerAll(reply_handler)
# Create an order ID which is 'global' for this session. This
# will need incrementing once new orders are submitted.
order_id = 1
# Create a contract in GOOG stock via SMART order routing
goog_contract = create_contract('GOOG', 'STK', 'SMART', 'SMART', 'USD')
# Go long 100 shares of Google
goog_order = create_order('MKT', 100, 'BUY')
# Use the connection to the send the order to IB
tws_conn.placeOrder(order_id, goog_contract, goog_order)
# Disconnect from TWS
tws_conn.disconnect()
最后一步是运行代码:
python ib_api_demo.py
可以立即看到 Trader Workstation 中打开了 API 选项卡,其中显示了做多 100 股 Google 股票的市价订单:
Google订单后的TWS API标签视图
如果我们现在查看投资组合选项卡,我们可以看到 Google 头寸。您还会注意到列表中有一个外汇头寸,这不是我生成的!我只能假设 IB 模拟账户以某种方式“共享”(由于登录信息相同)或 IB 向账户下达任意订单以使其看起来更“真实”。如果有人对这种行为有任何见解,我会很想了解更多:
Google 订单之后的 TWS API 投资组合视图
这是我们可以考虑的最基本的自动执行形式。在后续文章中,我们将构建一个更强大的事件驱动架构,以处理现实的交易策略。