3. 数据获取:使用API获取实时汇率数据

做跨币种套利,第一步就是搞定数据。没有实时、准确的价格,后面所有策略都是空中楼阁。我个人习惯把数据获取比作「做饭前的买菜」——菜买不好,厨艺再好也白搭。

这一章,咱们就聊聊怎么从交易所和外汇市场拿到实时汇率数据。我会用 Binance、OKX 和 Forex 三个典型来源做例子,把代码和坑都摆出来。

3.1 为什么数据获取是套利策略的命门?

你想想看,价差套利赚的就是那零点几秒的差价。如果数据延迟了1秒,可能利润就没了,甚至变成亏损。我在项目中遇到过好几次,因为API调用频率限制,导致数据更新不及时,策略开仓后价格已经变了。

说白了,数据获取要满足三个核心要求:

  • 实时性:延迟越低越好,最好在毫秒级
  • 准确性:价格不能有偏差,尤其是深度数据
  • 稳定性:API不能动不动就断,要有重连机制

核心原则:宁可错过一次交易机会,也不要因为错误数据做一次错误交易。

3.2 交易所API:Binance 和 OKX

加密货币交易所的API是最常用的数据源。它们都提供REST和WebSocket两种方式。我个人建议:用WebSocket拿实时行情,用REST做下单和查询

3.2.1 Binance 实时行情获取

Binance的API文档写得挺清楚。我一般用 python-binance 这个库,省事。下面是一个获取BTC/USDT实时价格的例子:

from binance.client import Client
from binance.websockets import BinanceSocketManager
import time

# 初始化客户端(不需要API Key也能获取行情)
client = Client()

# REST方式:获取最新价格
def get_latest_price(symbol='BTCUSDT'):
    ticker = client.get_symbol_ticker(symbol=symbol)
    return float(ticker['price'])

# WebSocket方式:实时推送
def handle_socket_message(msg):
    if msg['e'] == '24hrTicker':
        print(f"最新价格: {msg['c']}")

# 启动WebSocket
bm = BinanceSocketManager(client)
conn_key = bm.start_symbol_ticker_socket('BTCUSDT', handle_socket_message)
bm.start()

# 保持运行
time.sleep(60)
bm.stop_socket(conn_key)

我的经验:WebSocket虽然实时性好,但偶尔会断连。一定要加心跳检测和自动重连。我曾经因为没处理断连,策略空跑了半小时,亏了不少手续费。

3.2.2 OKX 实时行情获取

OKX的API和Binance大同小异,但有个细节要注意——它的交易对命名是 BTC-USDT(用横杠),而Binance是 BTCUSDT(无分隔符)。这个坑我踩过,代码里一定要统一处理。

import requests
import json

# REST方式获取OKX行情
def get_okx_price(symbol='BTC-USDT'):
    url = f"https://www.okx.com/api/v5/market/ticker?instId={symbol}"
    response = requests.get(url)
    data = response.json()
    return float(data['data'][0]['last'])

# WebSocket方式
import websocket

def on_message(ws, message):
    data = json.loads(message)
    if 'data' in data:
        print(f"OKX {data['data'][0]['instId']}: {data['data'][0]['last']}")

ws = websocket.WebSocketApp(
    "wss://ws.okx.com:8443/ws/v5/public",
    on_message=on_message
)
ws.run_forever()

注意:OKX的WebSocket需要发送订阅消息,不像Binance那样直接连接就能收到数据。具体格式参考官方文档,别搞错了。

3.3 外汇数据:Forex 实时汇率

做跨币种套利,免不了要涉及法币汇率。比如你交易的是BTC/USDT,但最终要换算成USD计价,那就需要USD/CNY的汇率。

外汇数据源我常用的是 Alpha VantageOANDA。前者免费但有调用限制,后者收费但更稳定。

import requests

# 使用Alpha Vantage获取EUR/USD实时汇率
def get_forex_rate(from_currency='EUR', to_currency='USD'):
    api_key = 'YOUR_API_KEY'
    url = f"https://www.alphavantage.co/query"
    params = {
        'function': 'CURRENCY_EXCHANGE_RATE',
        'from_currency': from_currency,
        'to_currency': to_currency,
        'apikey': api_key
    }
    response = requests.get(url, params=params)
    data = response.json()
    rate = data['Realtime Currency Exchange Rate']['5. Exchange Rate']
    return float(rate)

# 示例:获取EUR/USD
eur_usd = get_forex_rate('EUR', 'USD')
print(f"EUR/USD: {eur_usd}")

避坑指南:Alpha Vantage免费版每分钟只能调用5次。如果你同时监控多个货币对,很容易超限。我建议用缓存策略——每10秒更新一次,而不是每次策略循环都去请求。

3.4 数据获取的核心逻辑框架

下面这张图是我自己总结的数据获取流程。说白了,就是「统一接入、统一清洗、统一输出」。

数据获取核心逻辑框架 Binance API OKX API Forex API 统一数据接入层(Adapter模式) 数据清洗与标准化(去重、对齐、校验) 统一数据输出(DataFrame格式)

这个框架的好处是:不管底层换了哪个交易所,上层策略代码都不用改。我一开始没做这层抽象,后来换了数据源,改代码改到崩溃。嗯,吃一堑长一智。

3.5 数据对齐:跨交易所的时间同步

做价差套利,最怕的就是时间不同步。比如Binance的BTC价格是10:00:00.100,OKX的是10:00:00.200,这100毫秒的偏差可能让价差信号完全失真。

我的做法是:

  1. 统一使用UTC时间,避免时区转换错误
  2. 每个数据点都带上时间戳,精确到毫秒
  3. 在策略层做时间对齐,只比较时间戳相差小于50ms的数据
import pandas as pd
from datetime import datetime

# 假设从两个交易所拿到数据
data_binance = {
    'price': 50000.0,
    'timestamp': datetime.utcnow().timestamp()  # 精确到秒
}

data_okx = {
    'price': 50001.0,
    'timestamp': datetime.utcnow().timestamp()
}

# 时间对齐检查
def is_aligned(data1, data2, max_diff_ms=50):
    diff_ms = abs(data1['timestamp'] - data2['timestamp']) * 1000
    return diff_ms <= max_diff_ms

if is_aligned(data_binance, data_okx):
    spread = data_okx['price'] - data_binance['price']
    print(f"价差: {spread}")
else:
    print("数据时间不同步,跳过本次计算")

重要提醒:不要相信交易所返回的时间戳!有些交易所的时间戳是服务器时间,和你本地时间可能有偏差。我建议用本地时间戳覆盖,或者用NTP同步所有机器的时间。

3.6 实战中的避坑指南

做数据获取这几年,我踩过的坑能写一本书。挑几个最典型的说说:

  • API限频:Binance的REST接口每分钟最多1200次请求。别傻乎乎地每秒请求一次,用WebSocket代替。
  • 网络抖动:跨境访问交易所API,延迟可能从50ms跳到500ms。加个超时重试机制,超时时间设3秒就够了。
  • 数据缺失:偶尔会有某个交易所的数据没返回。别让整个程序崩溃,用上次有效数据填充,或者直接跳过。
  • 小数点精度:不同交易所对价格的小数位数要求不同。Binance的BTC价格是2位小数,OKX可能是5位。统一格式化,避免计算误差。

我的习惯:每次启动策略前,先跑一个「数据健康检查」——确认所有数据源都能正常返回,延迟在可接受范围内。这步花不了几秒钟,但能避免很多坑。

3.7 小结

数据获取是套利策略的基石。记住三个关键词:实时、准确、稳定。用WebSocket拿实时数据,用REST做辅助查询,用统一框架管理多数据源。时间对齐和异常处理是重中之重,别在这上面省功夫。

下一章,咱们会把这些数据用起来,开始真正的价差计算和信号生成。但在此之前,先把数据获取这关过了——毕竟,巧妇难为无米之炊嘛。


公众号:蓝海资料掘金营,微信deep3321