3、套利工具与平台:主流交易平台对比、数据源获取、API接口基础
做期现套利,说白了就是跟市场抢时间差。你策略再牛,工具选不对,数据拿不到,API调不通,一切都是白搭。这一章咱们就聊聊实战中怎么选平台、怎么搞数据、怎么接API。
我入行那会儿,国内量化平台还没这么成熟,自己写爬虫、自己搭服务器,踩坑踩到怀疑人生。现在条件好多了,但选择多了反而容易眼花。嗯,这里要注意——工具不在多,顺手最重要。
3.1 主流交易平台对比
目前国内做期现套利,绕不开这几个平台。我按自己的使用体验,给你排个序:
| 平台 | 期货支持 | 现货支持 | API稳定性 | 费率 | 我的评价 |
|---|---|---|---|---|---|
| CTP(上期技术) | 全品种 | 无 | ★★★★★ | 交易所+0.5元 | 期货首选,没有之一 |
| 中泰XTP | 部分 | 股票+ETF | ★★★★☆ | 万1.5起 | 做ETF套利很香 |
| 华泰MATIC | 全品种 | 无 | ★★★★ | 交易所+0.3元 | 速度不错,但门槛高 |
| 币安/OKX | 永续合约 | 数字货币 | ★★★★ | 0.02%-0.04% | 数字货币套利专用 |
我的建议:如果你做商品期货期现套利,CTP是绕不开的。它虽然接口老、文档烂,但稳定性和速度没得挑。我曾经在CTP上跑过百万级的套利单,连续三个月没出过一次断连。
数字货币这边,币安和OKX的API文档写得比CTP好太多,但要注意——交易所的API限频很严格,做高频套利的话,得提前申请VIP权限。
3.2 数据源获取
做套利,数据就是你的眼睛。我见过太多人策略写得漂亮,结果数据源一塌糊涂,回测跑得飞起,实盘直接崩。
数据源分两类:实时行情和历史数据。咱们一个一个说。
3.2.1 实时行情
期货这边,CTP的行情接口是首选。它推送的是Tick级数据,延迟在10ms以内。我习惯用CTP的MdApi,订阅合约后,OnRtnDepthMarketData回调里直接拿数据。
// CTP行情订阅示例(伪代码)
CThostFtdcMdApi* pMdApi = CThostFtdcMdApi::CreateFtdcMdApi();
pMdApi->RegisterSpi(this);
pMdApi->RegisterFront("tcp://180.168.146.187:10010");
pMdApi->Init();
// 订阅合约
char* instruments[] = {"rb2410", "hc2410"};
pMdApi->SubscribeMarketData(instruments, 2);
// 回调处理
void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField* pData) {
// 这里拿到最新行情
double lastPrice = pData->LastPrice;
double bidPrice = pData->BidPrice1;
double askPrice = pData->AskPrice1;
}
避坑指南:CTP的行情服务器有主备之分,我曾经因为只连了主服务器,结果主服宕机,数据断了整整5分钟。后来我改成同时连主备,用心跳检测自动切换,再没出过问题。
数字货币这边,WebSocket是主流。币安的wss://stream.binance.com:9443/ws,订阅深度数据,延迟在50ms以内,够用了。
3.2.2 历史数据
历史数据我推荐三个渠道:
- 天勤(TQ):国内期货历史数据最全,支持1分钟、5分钟、日线,下载方便。我回测时基本都用它。
- 聚宽(JoinQuant):股票+期货都有,但期货数据只到2015年,做长周期回测可能不够。
- 币安历史数据:官方提供CSV下载,按日期分文件,写个脚本批量拉就行。
我个人习惯把历史数据存到本地数据库里,用InfluxDB或者ClickHouse。为什么?因为回测时反复从网上下载太慢了,本地查起来快得多。
3.3 API接口基础
API接口这块,我把它分成三层:行情接口、交易接口、账户接口。做套利,行情和交易是核心。
3.3.1 行情接口
刚才说了CTP的MdApi,这里再补充一个——如果你不想用CTP,可以考虑用万得(Wind)的API。Wind的Python接口叫WindPy,用起来简单,但速度慢,适合做分析,不适合做高频。
# WindPy获取实时行情示例
from WindPy import w
w.start()
# 获取rb2410的最新价
error, data = w.wsq("rb2410.SHF", "rt_last")
if error == 0:
print(f"最新价: {data.Data[0][0]}")
注意:Wind的行情延迟在1-3秒,做套利的话,只能用来做辅助判断,不能用来做下单依据。我见过有人用Wind数据做高频套利,结果滑点吃到哭。
3.3.2 交易接口
交易接口是套利系统的核心。CTP的TraderApi是标准选择,但它的接口设计比较老,需要自己处理重连、心跳、报单状态机。
我分享一个我自己写的报单封装函数,简化了CTP的调用:
# Python封装CTP报单(简化版)
class CtpTrader:
def __init__(self):
self.api = None
self.front_id = 0
self.session_id = 0
def send_order(self, instrument, direction, offset, price, volume):
"""发送报单"""
field = CThostFtdcInputOrderField()
field.InstrumentID = instrument
field.Direction = direction # '0'买 '1'卖
field.CombOffsetFlag = offset # '0'开仓 '1'平仓
field.LimitPrice = price
field.VolumeTotalOriginal = volume
field.OrderPriceType = '2' # 限价单
# 这里要处理报单引用编号
field.OrderRef = self._get_order_ref()
result = self.api.ReqOrderInsert(field, 0)
if result != 0:
print(f"报单失败,错误码: {result}")
return result
我的经验:CTP的报单引用编号(OrderRef)必须保证唯一,我习惯用时间戳+自增序号来生成。曾经有个同事直接用自增序号,结果程序重启后序号重置,报单重复,被交易所罚了钱。
3.3.3 账户接口
账户接口主要用来查资金、持仓、成交。CTP的ReqQryTradingAccount和ReqQryInvestorPosition是常用的两个。
我建议在套利系统里单独开一个线程,每5秒查询一次账户信息,用来监控保证金和持仓变化。为什么是5秒?因为CTP的查询接口有频率限制,太频繁会被封IP。
3.4 知识体系总览
说了这么多,我画了一张图,把这一章的核心逻辑串起来。你一看就明白:
你看这张图,从左到右,平台、数据、API三个模块是串联的。平台选好了,数据才能稳定;数据拿到了,API才能发挥作用。最终所有东西都汇到底部的核心逻辑里——行情驱动,价差计算,信号生成,报单执行。
嗯,这一章的内容就这些。工具和平台是套利系统的骨架,骨架搭好了,后面加策略、加风控才稳当。我当年就是在这上面吃了不少亏,现在把这些经验写出来,希望你少走弯路。