第四节:数据获取——用CCXT库拉取实时行情

做跨市场套利,第一步就是搞定数据。没有数据,策略就是空中楼阁。

我个人习惯用CCXT这个库。它支持上百家交易所,API接口统一。说白了,你学会一套代码,就能对接币安、OKX、Bybit这些主流平台。省心。

4.1 为什么选CCXT?

我刚开始做套利时,每个交易所都单独写一套数据接口。币安一套,OKX一套,火币又一套。维护起来简直想骂人。后来发现CCXT,嗯,真香。

它的好处很明显:

  • 统一接口:不管哪家交易所,获取Ticker、OrderBook、K线的方法都一样
  • 支持广泛:100+交易所,主流的基本全覆盖
  • 活跃维护:社区更新快,交易所改API了,CCXT很快跟进
  • Python原生:直接pip install ccxt就能用,跟pandas、numpy无缝配合

核心观点:CCXT不是最快的,但绝对是最省事的。做套利策略,开发效率比那几毫秒的延迟更重要。

4.2 安装与初始化

安装很简单,一行命令搞定:

pip install ccxt

初始化交易所对象时,我建议把参数配全。别偷懒。

import ccxt

# 初始化币安交易所
exchange = ccxt.binance({
    'apiKey': 'YOUR_API_KEY',
    'secret': 'YOUR_SECRET',
    'enableRateLimit': True,  # 自动限速,防止被封
    'options': {
        'defaultType': 'spot',  # 现货市场
    }
})

# 打印交易所状态
print(exchange.name, '已连接')
print('是否支持websocket:', exchange.has['watchTicker'])

小技巧:enableRateLimit一定要设为True。我曾经没开这个,结果请求太频繁,被交易所封了IP。嗯,血的教训。

4.3 获取实时行情数据

套利最常用的数据有三种:Ticker、OrderBook、K线。我们一个一个来。

4.3.1 Ticker——最新成交价

Ticker就是当前的最新成交价。做价差监控时,我一般先拿Ticker快速判断。

# 获取BTC/USDT的Ticker
ticker = exchange.fetch_ticker('BTC/USDT')

print('最新价:', ticker['last'])
print('买一价:', ticker['bid'])
print('卖一价:', ticker['ask'])
print('24h涨跌:', ticker['percentage'], '%')
print('成交量:', ticker['baseVolume'])

输出示例:

最新价: 67500.0
买一价: 67499.0
卖一价: 67501.0
24h涨跌: 2.35 %
成交量: 125000.0

注意:Ticker的bid和ask是市场最优买卖价,不是你的成交价。做套利时,实际成交价要看OrderBook的深度。

4.3.2 OrderBook——深度数据

OrderBook是套利的核心。价差能不能吃到,全看深度够不够。

# 获取订单簿,限制深度为10档
orderbook = exchange.fetch_order_book('BTC/USDT', limit=10)

bids = orderbook['bids']  # 买单,格式 [[价格, 数量], ...]
asks = orderbook['asks']  # 卖单,格式 [[价格, 数量], ...]

print('=== 买单深度 ===')
for price, amount in bids[:5]:
    print(f'价格: {price:.2f}, 数量: {amount:.4f}')

print('=== 卖单深度 ===')
for price, amount in asks[:5]:
    print(f'价格: {price:.2f}, 数量: {amount:.4f}')

# 计算买卖价差
best_bid = bids[0][0]
best_ask = asks[0][0]
spread = (best_ask - best_bid) / best_bid * 100
print(f'当前价差: {spread:.4f}%')

避坑指南:我曾经在流动性差的币对上做套利,看着价差很大,一进去就被滑点吃掉了。记住,深度不够的价差是陷阱。

4.3.3 K线——历史行情

K线数据用来做回测和趋势判断。CCXT支持各种时间周期。

# 获取最近100根1小时K线
ohlcv = exchange.fetch_ohlcv('BTC/USDT', timeframe='1h', limit=100)

# 转换成DataFrame方便分析
import pandas as pd

df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')

print(df.head())

输出示例:

            timestamp      open      high       low     close     volume
0 2024-01-01 00:00:00  67000.0  67200.0  66950.0  67100.0  1250.0
1 2024-01-01 01:00:00  67100.0  67300.0  67000.0  67250.0  1100.0
2 2024-01-01 02:00:00  67250.0  67400.0  67150.0  67300.0  980.0

4.4 多交易所数据对比

跨市场套利的核心就是对比不同交易所的价格。我们同时拉取币安和OKX的Ticker。

import ccxt

# 初始化两个交易所
binance = ccxt.binance({'enableRateLimit': True})
okx = ccxt.okx({'enableRateLimit': True})

# 同时获取Ticker
symbol = 'BTC/USDT'
ticker_binance = binance.fetch_ticker(symbol)
ticker_okx = okx.fetch_ticker(symbol)

# 计算价差
price_binance = ticker_binance['last']
price_okx = ticker_okx['last']
spread = (price_binance - price_okx) / price_okx * 100

print(f'币安价格: {price_binance:.2f}')
print(f'OKX价格: {price_okx:.2f}')
print(f'价差: {spread:.4f}%')

if abs(spread) > 0.1:
    print('发现套利机会!')

实战经验:我一般设置价差阈值0.05%作为预警线。低于这个值,扣除手续费基本没利润。高于0.2%就要快速行动,因为套利者会瞬间抹平价差。

4.5 数据获取的常见坑

做数据获取这几年,我踩过的坑不少。列几个典型的:

  • 限频问题:交易所都有请求频率限制。CCXT的enableRateLimit能帮你自动控制,但如果你同时跑多个策略,还是要自己算好总请求量。
  • 网络延迟:国内访问海外交易所,延迟可能几百毫秒。做高频套利时,建议用服务器托管在海外机房。
  • 数据对齐:不同交易所的K线时间戳可能不一致。我习惯统一转成UTC时间再对比。
  • 异常处理:交易所偶尔会返回空数据或报错。代码里一定要加try-except,别让一个异常搞崩整个策略。
# 带异常处理的数据获取
def safe_fetch_ticker(exchange, symbol):
    try:
        ticker = exchange.fetch_ticker(symbol)
        return ticker
    except ccxt.NetworkError as e:
        print(f'网络错误: {e}')
        return None
    except ccxt.ExchangeError as e:
        print(f'交易所错误: {e}')
        return None
    except Exception as e:
        print(f'未知错误: {e}')
        return None

4.6 知识体系总览

下面这张图,把数据获取的核心逻辑串起来了。你照着这个框架走,不会乱。

CCXT数据获取核心流程 交易所API CCXT库 统一接口 Ticker 最新价、买卖价 OrderBook 深度、价差 K线 历史行情、趋势 价差监控 套利信号 回测分析

4.7 实战建议

最后,给你几个实在的建议:

  • 先测试再上线:用模拟盘跑几天数据,确认接口稳定、数据准确。
  • 做好日志:每次数据请求都记录时间戳和返回状态。排查问题全靠它。
  • 数据缓存:如果多个策略需要同一份数据,别重复请求。用Redis或内存缓存一下,能省不少流量。
  • 监控告警:数据源断了要能及时发现。我一般用钉钉或飞书机器人发告警。

记住:数据获取是套利策略的基石。这块做扎实了,后面的策略逻辑才能跑得稳。别图快,先求稳。


专注资料整理