第四节:数据获取——用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 知识体系总览
下面这张图,把数据获取的核心逻辑串起来了。你照着这个框架走,不会乱。
4.7 实战建议
最后,给你几个实在的建议:
- 先测试再上线:用模拟盘跑几天数据,确认接口稳定、数据准确。
- 做好日志:每次数据请求都记录时间戳和返回状态。排查问题全靠它。
- 数据缓存:如果多个策略需要同一份数据,别重复请求。用Redis或内存缓存一下,能省不少流量。
- 监控告警:数据源断了要能及时发现。我一般用钉钉或飞书机器人发告警。
记住:数据获取是套利策略的基石。这块做扎实了,后面的策略逻辑才能跑得稳。别图快,先求稳。