第二章:数据源与接口——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 数据源选择框架

说了这么多,到底怎么选?我画了个图,帮你理清思路:

债券数据源选择框架 你的策略类型? 做市策略 → 实时性要求高 交易所行情API 银行间FIX接口 Wind实时行情 回测/研究 → 数据完整性优先 Wind历史数据 QB历史数据 彭博历史数据 注:实际项目中,通常需要组合使用多个数据源

你看,选择数据源的核心逻辑就两条:你的策略是偏实时还是偏历史?做市策略必须上实时接口,回测研究则优先保证数据完整。

2.7 数据源对比总结

最后,我整理了个对比表,方便你快速决策:

数据源 实时性 数据完整性 成本 适用场景
Wind 国内债券回测、研究
QB 中小团队、快速原型
彭博 极高 跨境债券、衍生品
交易所API 极高 高频做市、实时交易
银行间FIX 银行间市场做市

最后说一句:数据源没有绝对的好坏,关键看你的策略需要什么。我个人习惯是:主力用Wind做回测,实盘用交易所API+银行间FIX,彭博作为跨境数据的补充。这套组合拳,我用了三年,没出过大问题。


蓝海数据掘金营,专注资料整理