数据源与API对接:交易所API(REST/WebSocket)、数据供应商(Reuters/Bloomberg)、模拟撮合引擎搭建

做高频交易,第一件事不是写策略,而是搞定数据。我见过太多人一上来就研究什么神经网络、强化学习,结果连行情数据都接不稳,回测时用的还是假数据。说白了,数据源就是你的弹药库,API就是你的枪。枪都端不稳,打什么仗?

交易所API:REST vs WebSocket

交易所API主要分两种:REST和WebSocket。很多人问我哪个好,我的回答是:两个都得会。

REST API——适合做“查”和“下单”

REST是请求-响应模式。你问一句,它答一句。适合做查询账户余额、提交订单、拉历史K线这些操作。但有个致命问题——慢。一次请求怎么也得几十毫秒,高频场景下根本扛不住。

核心要点:REST只适合做非实时操作。千万别用它来刷行情,否则你会被交易所封IP。

我举个例子,用Python调币安的REST接口拿BTC/USDT的最新价:

import requests
import json

url = "https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT"
response = requests.get(url)
data = json.loads(response.text)
print(f"当前价格: {data['price']}")

这段代码很简单,但你看,每次调用都要建立HTTP连接、等待响应。在高频场景下,这种延迟是不可接受的。

WebSocket——真正的实时数据通道

WebSocket是长连接模式。你连上去,交易所就不断给你推数据。延迟可以做到毫秒级,甚至微秒级。这才是高频交易该用的东西。

我个人习惯用WebSocket接实时行情,用REST做交易执行。为什么分开?因为WebSocket的链路如果被大单阻塞,你的订单可能发不出去。嗯,这里要注意——交易指令走独立通道更安全。

来看一个WebSocket订阅深度数据的例子:

import websocket
import json

def on_message(ws, message):
    data = json.loads(message)
    # 处理深度数据
    bids = data['b'][:5]  # 前5档买单
    asks = data['a'][:5]  # 前5档卖单
    print(f"买一: {bids[0][0]} @ {bids[0][1]}")
    print(f"卖一: {asks[0][0]} @ {asks[0][1]}")

def on_error(ws, error):
    print(f"连接异常: {error}")

def on_close(ws, close_status_code, close_msg):
    print("连接关闭,准备重连...")

def on_open(ws):
    # 订阅BTC/USDT的深度数据
    subscribe_msg = {
        "type": "subscribe",
        "channel": "depth",
        "symbol": "BTCUSDT"
    }
    ws.send(json.dumps(subscribe_msg))

ws = websocket.WebSocketApp(
    "wss://stream.binance.com:9443/ws",
    on_open=on_open,
    on_message=on_message,
    on_error=on_error,
    on_close=on_close
)
ws.run_forever()

避坑指南:我曾经在生产环境遇到过WebSocket断连后没重连,导致策略空跑了3个小时。后来我加了个心跳检测和自动重连机制,每5秒检查一次连接状态。记住,网络不可靠,你的代码必须可靠。

数据供应商:Reuters与Bloomberg

做高频交易,光靠交易所的数据不够。你需要历史数据做回测,需要多市场数据做套利,需要新闻数据做事件驱动。这时候就得找数据供应商了。

供应商 优势 劣势 适用场景
Reuters (Refinitiv) 外汇、商品数据强;API灵活 价格贵;学习曲线陡 外汇高频、跨市场套利
Bloomberg 数据全面;终端好用 极其昂贵;API限制多 宏观对冲、事件驱动
其他(Polygon、Quandl等) 便宜;适合起步 数据质量参差不齐 个人研究、小团队

你想想看,Bloomberg一年要几万美金,Reuters也不便宜。我刚开始做量化时,根本用不起这些。后来发现,其实很多交易所自己就提供历史数据下载,虽然格式乱一点,但胜在免费。

注意:不同供应商的数据格式、时间戳精度、价格精度都不一样。做回测前一定要对齐数据。我曾经因为Reuters和交易所的时间戳差了1秒,导致回测结果完全失真。那叫一个惨。

模拟撮合引擎搭建

这是我最想强调的部分。很多人直接用历史数据来回测,觉得没问题。但你想过没有——你的订单真的能成交在那个价格吗?市场深度够吗?滑点多少?

模拟撮合引擎,说白了就是模拟交易所的订单簿,让你在回测时能更真实地模拟成交。我建议每个做高频的人都要自己搭一个。

核心逻辑

一个简单的撮合引擎需要做三件事:

  1. 维护订单簿——实时更新买盘和卖盘的深度
  2. 处理订单——限价单、市价单、撤单
  3. 计算成交——根据订单簿匹配买卖双方

来看一个简化版的实现:

class MatchingEngine:
    def __init__(self):
        self.bids = []  # 买单队列,价格降序
        self.asks = []  # 卖单队列,价格升序
        self.trades = []  # 成交记录
    
    def add_order(self, order):
        """添加订单并尝试撮合"""
        if order['side'] == 'buy':
            self._match_buy(order)
        else:
            self._match_sell(order)
    
    def _match_buy(self, buy_order):
        """撮合买单"""
        while self.asks and buy_order['quantity'] > 0:
            best_ask = self.asks[0]
            if buy_order['price'] >= best_ask['price']:
                # 可以成交
                trade_qty = min(buy_order['quantity'], best_ask['quantity'])
                trade_price = best_ask['price']
                
                # 记录成交
                self.trades.append({
                    'price': trade_price,
                    'quantity': trade_qty,
                    'time': buy_order['time']
                })
                
                # 更新订单
                buy_order['quantity'] -= trade_qty
                best_ask['quantity'] -= trade_qty
                
                if best_ask['quantity'] == 0:
                    self.asks.pop(0)
            else:
                break
        
        # 未成交部分加入订单簿
        if buy_order['quantity'] > 0:
            self.bids.append(buy_order)
            self.bids.sort(key=lambda x: -x['price'])
    
    def _match_sell(self, sell_order):
        """撮合卖单,逻辑类似"""
        # 实现略...
        pass

关键点:这个引擎虽然简单,但已经能模拟出基本的成交逻辑。实际生产中,你还需要考虑手续费、最小交易量、价格精度限制等。我建议先跑通这个基础版本,再逐步加功能。

知识体系总览

下面这张图概括了本章的核心内容。你可以把它当作一个路线图,看看自己现在在哪个位置。

数据源与API对接知识体系 交易所API • REST:查询/下单 • WebSocket:实时行情 • 延迟对比 • 重连机制 • 避坑:断连处理 数据供应商 • Reuters (Refinitiv) • Bloomberg • 其他供应商 • 数据对齐问题 • 避坑:时间戳精度 模拟撮合引擎 • 订单簿维护 • 限价单/市价单 • 成交计算 • 滑点模拟 • 避坑:深度不足 数据是基础,API是工具,撮合引擎是验证 三者缺一不可,顺序不可颠倒 REST WS Match 高频交易数据链路:从获取到验证的完整闭环

这张图把本章的三个核心模块串起来了。你看,从左到右,从数据获取到数据验证,是一条完整的链路。我个人建议你按这个顺序来学习,不要跳步。

我的经验:刚开始做高频交易时,我花了一个月时间专门研究API对接和撮合引擎。虽然看起来慢,但后来写策略时几乎没出过数据层面的问题。基础打牢了,上层建筑才稳。

好了,这一章的内容就到这里。数据源和API对接是高频交易的基石,别嫌它枯燥。你想想看,如果连数据都接不稳,后面那些花里胡哨的策略还有什么意义?

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