数据源接入:交易所API对接、行情数据格式解析、交易数据格式解析
做市业务里,数据源接入是第一步,也是最容易踩坑的一步。
我见过不少团队,策略模型写得漂漂亮亮,结果一上线就亏钱。查到最后,发现是API对接时数据就错了。嗯,数据源不对,后面全是白搭。
交易所API对接:别小看这层通信
每个交易所的API风格都不一样。有的用REST,有的用WebSocket。我个人习惯是:行情走WebSocket,交易走REST。为什么?
- WebSocket:全双工通信,适合高频行情推送。延迟低,带宽省。
- REST:请求-响应模式,适合下单、撤单、查余额。逻辑清晰,容易调试。
我在项目中遇到过一个问题:某交易所的WebSocket每隔30秒会发一个ping帧,如果客户端没及时回复pong,连接就被断开了。当时我们的重连逻辑没写好,导致行情断了整整3分钟。嗯,那3分钟里策略还在按旧数据下单,亏了不少。
行情数据格式解析:别被字段名骗了
行情数据,说白了就是交易所告诉你「现在市场上发生了什么」。常见的格式有:
| 数据类型 | 典型字段 | 说明 |
|---|---|---|
| 深度数据 | bids, asks, price, size | 买卖盘口,按价格排序 |
| Ticker | last, volume, high, low | 最新成交价、成交量等 |
| K线 | open, high, low, close, volume | 时间窗口内的聚合数据 |
| 逐笔成交 | price, size, side, timestamp | 每一笔真实的成交记录 |
你想想看,深度数据里的bids和asks,不同交易所的排序方向可能相反。有的bids从高到低,有的从低到高。如果你没注意,直接拿过来用,策略算出来的中间价可能就是错的。
交易数据格式解析:订单状态机是关键
交易数据比行情数据复杂得多。因为它涉及状态变化。一个订单从提交到成交,中间可能经历:
- NEW:刚提交,还没进撮合引擎
- PARTIALLY_FILLED:部分成交
- FILLED:完全成交
- CANCELED:被撤销
- REJECTED:被拒绝
我在项目中遇到过最头疼的事:某交易所的订单状态更新有延迟。订单明明已经成交了,但API返回的还是PARTIALLY_FILLED。如果你这时候去撤单,可能会把已经成交的部分也撤掉——嗯,那就会产生「撤单失败」的报错。
数据清洗:脏数据比你想的要多
数据接入后,第一件事不是存起来,而是清洗。我总结了几类常见脏数据:
- 重复数据:同一个成交记录被推送了两次。需要根据交易ID去重。
- 乱序数据:后发生的成交先到达。需要根据时间戳重新排序。
- 缺失数据:某段时间的行情断了。需要做插值或标记为无效。
- 异常数据:价格突然跳变100倍。可能是交易所的bug,也可能是数据解析错误。
说白了,数据清洗就是「把垃圾挡在门外」。我见过有人把脏数据直接喂给模型,结果模型学了一堆错误规律。你想想看,那能赚钱吗?
实战:一个简单的行情解析示例
下面是一个简化版的深度数据解析代码。注意,我用了异常处理和格式校验:
def parse_orderbook(raw_data):
try:
bids = raw_data['bids']
asks = raw_data['asks']
# 校验排序方向
if bids[0][0] < bids[1][0]:
bids = sorted(bids, key=lambda x: x[0], reverse=True)
if asks[0][0] > asks[1][0]:
asks = sorted(asks, key=lambda x: x[0])
# 提取价格和数量
bid_prices = [b[0] for b in bids[:10]]
bid_sizes = [b[1] for b in bids[:10]]
ask_prices = [a[0] for a in asks[:10]]
ask_sizes = [a[1] for a in asks[:10]]
return {
'bid_prices': bid_prices,
'bid_sizes': bid_sizes,
'ask_prices': ask_prices,
'ask_sizes': ask_sizes,
'timestamp': raw_data.get('timestamp', 0)
}
except Exception as e:
log.error(f"解析深度数据失败: {e}")
return None
这段代码看起来简单,但我在生产环境里加了不少细节。比如排序校验、异常捕获、日志记录。嗯,这些细节往往决定了系统的稳定性。
数据存储:选对工具省一半力气
数据解析完了,存哪里?我个人推荐分层存储:
| 层级 | 存储工具 | 用途 |
|---|---|---|
| 热数据 | Redis / 内存 | 当前盘口、最新成交,毫秒级访问 |
| 温数据 | InfluxDB / TimescaleDB | 分钟级K线、历史深度快照 |
| 冷数据 | Parquet / HDFS | 全量历史数据,用于回测和分析 |
我在项目中遇到过一个问题:把全量逐笔成交数据都存到关系型数据库里,结果查询一次要等几十秒。后来改成用Parquet按天分区存储,查询速度提升了100倍。说白了,选对工具比优化代码更重要。
本章小结
数据源接入这件事,看起来是体力活,其实藏着不少门道。API对接要注意心跳和重连,行情解析要注意格式和排序,交易解析要注意状态机,数据清洗要防脏数据。每一步都马虎不得。
我记得刚入行时,觉得这些基础工作没什么技术含量。后来吃了不少亏才明白:数据质量决定了策略的上限。如果你的数据源是错的,再牛的模型也救不了你。
公众号:蓝海资料掘金营,微信deep3321