第二章:数据源与接口——Wind/QB/彭博终端数据获取、交易所行情API、银行间市场数据接口
做债券量化,第一步不是写模型,而是搞定数据。我见过太多人模型写得漂亮,结果数据源没接对,回测全是假的。今天咱们就把这事聊透。
数据源这块,说白了就三类:终端类(Wind、QB、彭博)、交易所API、银行间接口。每类都有自己的脾气,咱们一个个说。
2.1 Wind终端数据获取
Wind在国内债券圈,基本是标配。我个人习惯用Wind的Python接口——WindPy。这东西装起来不复杂,但有个坑:必须先打开Wind客户端,否则连不上。
核心要点:Wind的数据获取分两种——实时行情和历史数据。做市策略通常两个都要。
先看个最简单的例子,获取某只国债的历史收盘价:
from WindPy import w
w.start()
# 获取"21国债10"近30天的收盘价
data = w.wsd("210010.IB", "close", "2024-01-01", "2024-01-30")
print(data.Data[0])
嗯,这里要注意。wsd是历史数据,wst是实时数据。我刚开始做的时候,经常搞混这两个函数,导致回测数据对不上。后来养成了习惯:回测用wsd,实盘用wst。
个人经验:Wind的债券代码后缀有讲究。银行间债券用.IB,交易所债券用.SH或.SZ。我曾经因为代码后缀写错,跑了一整晚的回测,结果全是空数据。从那以后,我每次写代码前都会先手动查一下代码对不对。
2.2 QB(聚宽)数据接口
QB在债券圈的地位,有点像Wind的平价替代品。数据质量不错,而且接口更友好。我个人觉得,如果团队预算有限,QB是个好选择。
QB的数据获取方式更Pythonic:
import qb
# 获取"21国债10"的日线数据
df = qb.get_price(
"210010.IB",
start_date="2024-01-01",
end_date="2024-01-30",
frequency="1d"
)
print(df.head())
你看,代码比Wind简洁不少。但QB有个问题——它的债券数据覆盖度不如Wind全。特别是信用债、次级债这些品种,有时候会缺数据。
避坑指南:我曾经在做一个信用债利差策略时,发现QB的数据少了几个关键券种。后来不得不临时切回Wind补数据。所以我的建议是:主力用QB,但一定要留个Wind作为备胎。
2.3 彭博终端数据获取
彭博在境外债券市场是绝对的王者。如果你做跨境债券,彭博基本绕不开。它的API叫blpapi,用起来比Wind复杂一些。
看个例子:
import blpapi
# 连接彭博终端
session = blpapi.Session()
session.start()
# 获取某只国债的收益率
request = session.createRequest("HistoricalDataRequest")
request.getElement("securities").appendValue("US9128285M49 Govt")
request.getElement("fields").appendValue("YLD_YTM_MID")
request.getElement("startDate").setValue("20240101")
request.getElement("endDate").setValue("20240130")
session.sendRequest(request)
# 处理返回数据...(代码略)
说实话,彭博的API设计得有点啰嗦。但它的数据质量确实好,特别是收益率曲线、信用利差这些衍生数据,Wind和QB都比不了。
我的建议:如果你主要做国内债券,Wind+QB就够了。如果涉及跨境,彭博是必须的。但彭博终端贵啊,一年几十万,小团队要考虑清楚。
2.4 交易所行情API
交易所行情API,主要是上交所和深交所的实时数据。做市策略对实时性要求高,这个接口就派上用场了。
上交所的行情API是通过mdgw协议走的,代码大概长这样:
import socket
# 连接上交所行情网关
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("mdgw.sse.com.cn", 9001))
# 订阅某只债券的实时行情
subscribe_msg = build_subscribe_msg("210010")
sock.send(subscribe_msg)
# 循环接收行情数据
while True:
data = sock.recv(1024)
process_market_data(data)
嗯,这里要注意。交易所行情API的延迟通常在毫秒级,但网络波动会影响稳定性。我有个朋友,做高频做市时因为网络抖动,连续亏了三天。后来他加了双线冗余,才稳住。
个人经验:交易所行情API的带宽有限,别一股脑订阅所有券种。我一般只订阅流动性最好的前50只债券,其他的用Wind或QB补数据。
2.5 银行间市场数据接口
银行间市场是中国债券的主战场,交易量占大头。它的数据接口主要通过中国外汇交易中心(CFETS)提供。
CFETS的接口比较特殊,用的是FIX协议。看个简化版:
import quickfix as qf
# 创建FIX会话
settings = qf.SessionSettings("fix.cfg")
store = qf.FileStoreFactory(settings)
log = qf.ScreenLogFactory(settings)
app = MyApplication()
initiator = qf.SocketInitiator(app, store, settings, log)
initiator.start()
# 订阅债券行情
subscribe_request = """
8=FIX.4.4|9=XX|35=V|49=YOUR_FIRM|56=CFETS|55=210010.IB|...
"""
# 发送请求
qf.Session.sendToTarget(subscribe_request)
说实话,FIX协议的学习曲线有点陡。我当初啃了一个星期才跑通第一个例子。但一旦跑通了,后面就顺了。
避坑指南:银行间市场的接口有严格的权限控制。我曾经因为没申请对权限,导致生产环境连不上,被领导骂了一顿。所以,一定要提前和CFETS确认好你的权限范围。
2.6 数据源选择框架
说了这么多,到底怎么选?我画了个图,帮你理清思路:
你看,选择数据源的核心逻辑就两条:你的策略是偏实时还是偏历史?做市策略必须上实时接口,回测研究则优先保证数据完整。
2.7 数据源对比总结
最后,我整理了个对比表,方便你快速决策:
| 数据源 | 实时性 | 数据完整性 | 成本 | 适用场景 |
|---|---|---|---|---|
| Wind | 中 | 高 | 中 | 国内债券回测、研究 |
| QB | 中 | 中 | 低 | 中小团队、快速原型 |
| 彭博 | 高 | 极高 | 高 | 跨境债券、衍生品 |
| 交易所API | 极高 | 低 | 低 | 高频做市、实时交易 |
| 银行间FIX | 高 | 中 | 中 | 银行间市场做市 |
最后说一句:数据源没有绝对的好坏,关键看你的策略需要什么。我个人习惯是:主力用Wind做回测,实盘用交易所API+银行间FIX,彭博作为跨境数据的补充。这套组合拳,我用了三年,没出过大问题。