如何学习盈透 api 的开发?
2016-9-4: 挖坑
2016-10-03 19:01:更新问答
2016-10-03 20:39:让更多人看到,修改了下问题的话题范围,希望题主不介意
2016-10-10 12:36:上知乎推荐了,补充一些代码相关的内容
谢邀,前段时间开发vn.ib的接口封装花了挺久研究ib接口的底层细节,这个问题先留个名,后面来细答。
为啥IB API这么火?
这段纯属个人的一些瞎BB,没兴趣的可以跳过,2008年刚进大学的时候就听说过了Interactive Brokers的大名(当时对量化还是一窍不通),和曾经一度热火但是现在几乎已经淡出主流量化圈的MT4平台不同,IB API的用户数量和相关的项目数量都是有增无减:
AlgoTrader:应该算是对接IB的最有名的开源量化交易平台,使用CEP作为核心策略引擎,主要应用领域是极为复杂的交易策略(比如全自动的Volatility Arbitrage)
Glean(过去的tradelink):使用图形化的方式来开发策略,同样对接IB实现量化交易,偏向于速度较快的日内交易策略
Matlab Trading Toolbox:Mathworks官方提供的量化交易工具
Quantopian:当下最火的在线量化交易平台,最近支持了实盘交易,也是首先选择对接了IB
究其原因,IB API能成为许多量化平台的首选对接通道,不外乎一个原因:Created by traders, for traders。 公司创始人Thomas Peterffy的传奇背景就不多介绍了,关键在于IB背后的高频交易公司TimberHill,有这么一家市场上顶尖的玩家在为公司经纪相关的业务提供建议和各种技术支持,IB才可能同时给客户提供:
- 提供强到变态的交易平台TWS
- 多到变态的全球产品覆盖
- 低到变态的交易费用
以上三点能做得比IB好的不能说没有,但是三点同时都能和IB竞争的似乎就不多见了:
- 高盛之类的投行太过高大上,不够亲民
- E*Trade之类的零售经纪商,费用较贵的同时,交易软件的功能还十分有限
- FXCM之类的外汇公司,经常留点头寸不对冲跟客户对赌,点差还特别高
所以综合来看,其实IB成功的原因和其他行业成功的公司也没多大区别,能够抓住客户的痛点并且长期提供高质来那个的服务才是关键。
背景介绍
时隔一个月终于有时间来填坑了。
IB API的开发是一个非常大的话题,尽管如此看到这个问题时立马决定无论如何要给出一个比较全面的回答,简单做一些背景介绍吧(一段痛苦的折腾经历)。
问题1的答案: API是由Interactive Brokers为了量化交易推出的一套交易接口,结合IB广泛的市场覆盖,使用IB API的用户可以轻松实现全球市场的量化交易,也是世界上应用最广泛的量化交易接口之一(或许这里都没必要说“之一”)
本人目前在开发vn.py项目中的IB API的Python封装接口vn.ib,目的是为了替代之前使用的IbPy项目。IbPy已经若干年没有更新了,且因为其纯Python实现的关系很多地方存在设计不合理的情况(比如底层socket触发异常就直接断开,不抛出任何错误或者异常)。
vn.ib选择基于IB官方推出的最新9.72 C++ API来开发,和vn.py框架中的其他接口一样使用boost.python封装的形式,以提供更好的稳定性和远胜IbPy的性能。在开发过程中掉坑无数,花了大约两周的时间才勉强把程序给跑通起来,所以大家如果在具体开发过程中遇到什么问题欢迎提问,大概率我之前也遇到过了。
IB API的特点
尽管都交交易接口,但是IB API和国内常见的接口(CTP类,恒生等)有着诸多不同,先来介绍几个比较关键的点:
- 使用IB API连接上的不是IB的交易服务器,而是运行于本机的TWS(带图形的交易平台)或者IB Gateway(只提供简单日志的交易路由,适合量化),即使对于FIX接口也是如此
(IB网关,由于没有复杂的图形界面,能够提供比TWS更高的交易性能)
- IB API提供了所有的底层源代码,用户在使用时需要自行编译底层API接口部分的组件,提供了一定灵活性的同时,也导致项目开发过程中容易遇到额外的编译问题
- IB API内建了一个比较大的内存缓冲区,回调函数即使阻塞一段时间也基本不会导致API崩溃,所以CTP类API开发时常用的一个回调函数推送的数据必须先进缓冲队列的设计模式就没有必要了,可以把一些可能耗时较长的逻辑直接写在回调函数中(出于程序代码架构的原因仍然不建议这么做,不过对于API封装来说省了很大的力气)
- 最大的坑:IB API里回调函数(负责向用户的程序中推送数据)的工作线程需要用户自行创建和管理(国内几乎所有的API都是内部实现的),提供了极大的灵活性(比如用户可以使用类似协程的模式轻松实现一个线程同时管理8个API连接的推送),但是由于官方文档和Demo的缺失导致用户一上来几乎不知道怎么去写这个线程!!!只能靠一步步试错的方式折腾,无比浪费时间。
使用IB API的开发流程(问题2的答案)
这里的内容针对使用Visual Studio开发C++接口,其他语言的大同小异:
- 从这里http://interactivebrokers.github.io下载最新的IB API,选择9.72 beta(比起9.71有了很大的改进,比如取消了Win32 C++ 接口,统一提供POSIX标准的C++接口)
- 安装后,进入TWS API文件夹下的source/CppClient, 把ssl lib client三个文件夹统一复制到你自己项目的文件夹中
- 把client文件夹下的.h和.cpp文件添加到你自己的Visual Studio项目中
- 在C++项目配置中的Preprocessor中添加_CRT_SECURE_NO_DEPRECATE和_WINSOCK_DEPRECATED_NO_WARNINGS,否则编译时会触发警告
- 在项目的General配置中,把Character Set设置为Use Multi-Byte Character Set,这里有可能报错,或者编译时报这个Character Set错误,提示用户需要安装一个补丁包,去Microsoft官网搜索后下载安装就行
- 后面就可以写自己程序的代码了,如果你不幸遇到各种问题,欢迎在评论里提问......
IB API的结构简介(问题3的答案)
据我所知目前市面上是没有关于IB API的开发书籍的,最好的参考资料就是官方的Reference Guide:TWS API v9.72: Trader Workstation API
这里简单介绍一下IB API的结构:
- EWrapper:类似CTP中的SPI类,提供回调函数
- EClientSocket:类似CTP中的API类,提供主动函数
- EReaderOSSignal:一个信号量,回调函数管理线程需要监听该信号量,当socket收到数据后该信号量会被触发
- EReader:当上面的信号量被触发后,用户需要调用EReader中的处理信息函数,来触发EWrapper中对应的回调函数
结构后是一个API的大体工作顺序:
- 继承EWrapper并实现回调函数//步骤1
class IbWrapper : public EWrapper
{
private:
VnIbApi *api;
public:
IbWrapper(VnIbApi *api)
{
this->api = api;
};
~IbWrapper()
{
};
void tickPrice(TickerId tickerId, TickType field, double price, int canAutoExecute);
...... - 创建EWrapper对象wrapper
- 创建EReaderOSSignal对象signal
- 创建EClientSocket对象client,传入wrapper和client的对象指针作为构造参数//步骤2、3、4
class VnIbApi
{
private:
//EClientSocket *client;
IbWrapper *wrapper;
EReaderOSSignal signal;
EReader *reader;
thread *worker;
public:
EClientSocket *client;
VnIbApi()
{
this->signal = EReaderOSSignal();
this->wrapper = new IbWrapper(this);
this->client = new EClientSocket(this->wrapper, &this->signal);
};
...... - 调用client的eConnect方法,连接TWS程序
- 连接成功后,创建EReader对象reader,传入client和signal的对象指针作为构造函数
- 调用reader的start方法,启动reader中的socket端口数据监听线程//步骤5、6、7
bool VnIbApi::eConnect(string host, int port, int clientId, bool extraAuth)
{
bool r = this->client->eConnect(host.c_str(), port, clientId, extraAuth);
if (r)
{
//启动EReader从socket读取信息
this->reader = new EReader(this->client, &this->signal);
this->reader->start();
//启动数据推送线程
function0<void> f = boost::bind(&VnIbApi::run, this);
thread t(f);
this->worker = &t;
};
return r;
}; - 启动回调函数管理线程,进入无限循环,首先调用signal的waitForSignal等待信号的触发
- socket收到数据后,信号被触发,调用reader的processMsgs函数,激发wrapper中对应的回调函数//步骤8、9
void VnIbApi::run()
{
while (this->client->isConnected())
{
this->reader->checkClient();
signal.waitForSignal();
this->reader->processMsgs();
}
}; - 用户可以调用client中的主动函数来实现其他的工作任务//步骤10
void IbWrapper::nextValidId(OrderId orderId)
{
PyLock lock;
this->api->nextValidId(orderId);
};
IB API的参考源代码(问题4的答案)
我这里主要介绍下Github上IB相关的一些项目吧:
- GitHub - blampe/IbPy: Python API for the Interactive Brokers on-line trading system., 著名的IbPy接口,欧美很多关于IB开发交易策略的文章都使用IbPy,但是问题上面也提过了
- GitHub - jamesmawm/High-Frequency-Trading-Model-with-IB: A high-frequency trading model using Interactive Brokers API with pairs and mean-reversion in Python, 一个关于使用IB实现高频交易模型的项目,策略本身只是展示目的,没有实际应用个价值,使用IbPy作为交易接口
- GitHub - Komnomnomnom/swigibpy: Third party Interactive Brokers Python API generated from TWS C++ API using SWIG.,使用SWIG开发的IB API的Python封装
- GitHub - JanBoonen/TwsApiCpp: Improved TWS API POSIX C++ library for the Interactive Brokers (IB) TWS (same project as TwsApiC++ in Yahoo TWSAPI).,这个项目改进了官方提供的C++ API代码,号称是降低了开发难度,同时提供更高的并发性能
- https://github.com/jamesmawm/IB-Trading-Models-And-Backtester,对于2中的策略模型的改进版
- GitHub - brotchie/ib-zmq: Interactive Brokers API to ZeroMQ proxy,把IB API和ZMQ进行对接实现了一个消息代理,用户可以直接使用ZMQ来进行交易
- vnpy/vn.ib at dev · vnpy/vnpy · GitHub,本人开发的vn.ib接口,目前尚未完成,不过自认代码质量还过得去,同时以上回答中提到的内容都基于该代码
- Trading with Interactive Brokers using Python,一个同样基于IB官方的C++接口做的Python封装项目,提供了和Quantopian兼容的策略开发API,但是github上的仓库里没有底层的封装代码,猜测可能作者是想做商业项目?
暂时想到的就是以上内容,还是回到开始的一句话;IB接口的开发是个非常大的话题,但是如果能掌握,基本国内大部分接口的开发也都没什么问题了。有问题欢迎在评论里提问,本答案预计后续还会有很多内容上的更新,欢迎关注吧。
往期高赞内容
量化方向文章:
量化方向回答:
- 如何学习盈透 api 的开发?
- 什么是隐含波动率 (Implied Volatility) ?
- 有哪些程序化交易方面的 GitHub 作者值得关注?
- Quant 是否是一个江河日下的职业?
- 有没有回测和实盘交易用同一份代码的量化交易框架?
- 如何搭建一个量化交易实验系统做教学用?
- 外汇收益真的有那么高吗?
- 你有哪些心中珍藏值得推荐的好书?