数据获取入门:用CCXT连接交易所

做价差捕捉,第一步就是拿到数据。

没有数据,什么策略都是空谈。我个人习惯把数据获取比作「做饭前的买菜」——菜买不好,厨艺再高也白搭。

为什么选CCXT?

市面上有很多交易所API库,但CCXT是我用得最顺手的。它统一了上百家交易所的接口,你写一套代码,就能对接币安、OKX、Bybit等等。

说白了,它就是个「翻译官」。把各家交易所不同的API格式,翻译成统一的Python调用方式。

核心优势:

  • 支持100+交易所
  • 统一接口,切换交易所只需改一行代码
  • 内置代理、限流、重试机制
  • 开源且持续维护

安装与初始化

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

pip install ccxt

然后初始化交易所对象。我以币安为例:

import ccxt

# 创建交易所实例
exchange = ccxt.binance({
    'apiKey': '你的API_KEY',
    'secret': '你的SECRET_KEY',
    'enableRateLimit': True,  # 自动限流,防止被封
    'options': {
        'defaultType': 'spot',  # 现货市场
    }
})

# 测试连接
markets = exchange.load_markets()
print(f"成功连接,共加载 {len(markets)} 个交易对")

小提示:如果你只是测试,可以不用API Key。但做实盘交易时,一定要在交易所后台生成API,并绑定IP白名单。

获取实时Ticker数据

Ticker就是当前市场的快照。包含最新价、买一卖一价、24小时成交量等。

我经常用它来判断「当前市场是否活跃」。比如价差策略需要高流动性,如果某个币的24小时成交量太小,我一般会直接跳过。

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

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

嗯,这里要注意:Ticker是「瞬时数据」,每次调用都返回当前快照。如果你需要连续监控,建议用WebSocket,而不是轮询。不过那是后面章节的内容了。

获取K线数据

K线才是价差分析的核心。它包含了开盘、最高、最低、收盘、成交量五个维度。

我个人习惯用1分钟K线做高频价差,用15分钟K线做日内趋势。

# 获取BTC/USDT的1分钟K线,最近100根
ohlcv = exchange.fetch_ohlcv('BTC/USDT', timeframe='1m', limit=100)

# 返回格式:[[timestamp, open, high, low, close, volume], ...]
for candle in ohlcv[:5]:  # 只打印前5根
    timestamp = candle[0]
    open_price = candle[1]
    high_price = candle[2]
    low_price = candle[3]
    close_price = candle[4]
    volume = candle[5]
    
    print(f"时间: {timestamp}, 开: {open_price}, 高: {high_price}, 低: {low_price}, 收: {close_price}, 量: {volume}")

避坑指南:我曾经在项目里直接用时间戳当索引,结果发现不同交易所的时间戳精度不一样。币安是毫秒级,有些交易所是秒级。建议统一转成datetime对象再处理。

数据频率选择

做价差捕捉,频率选择很关键。我总结了一个经验表:

策略类型 推荐频率 适用场景
高频价差 1秒 - 1分钟 期现套利、跨所套利
日内价差 5分钟 - 15分钟 趋势跟踪、均值回归
中低频价差 1小时 - 4小时 统计套利、配对交易

你想想看,如果你做的是期现套利,价差可能在几秒内就消失了。用1小时K线根本抓不住。反过来,如果你做的是跨品种价差,用1秒K线反而会被噪音干扰。

我的建议:刚开始做策略时,先用1分钟K线跑回测。等策略稳定了,再逐步降低频率。别一上来就搞高频,数据量太大,调试起来很痛苦。

完整示例:获取现货与期货的价差数据

这是我最常用的一个脚本,同时获取现货和永续合约的K线,然后计算价差:

import ccxt
import pandas as pd
from datetime import datetime

# 初始化现货和合约交易所
spot = ccxt.binance({'options': {'defaultType': 'spot'}})
future = ccxt.binance({'options': {'defaultType': 'future'}})

# 获取数据
symbol = 'BTC/USDT'
timeframe = '1m'
limit = 100

spot_ohlcv = spot.fetch_ohlcv(symbol, timeframe, limit=limit)
future_ohlcv = future.fetch_ohlcv(symbol, timeframe, limit=limit)

# 转成DataFrame
spot_df = pd.DataFrame(spot_ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
future_df = pd.DataFrame(future_ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])

# 计算价差
spot_df['future_close'] = future_df['close']
spot_df['spread'] = spot_df['future_close'] - spot_df['close']

# 打印最新价差
latest = spot_df.iloc[-1]
print(f"时间: {datetime.fromtimestamp(latest['timestamp']/1000)}")
print(f"现货价: {latest['close']:.2f}")
print(f"期货价: {latest['future_close']:.2f}")
print(f"价差: {latest['spread']:.2f}")

注意:永续合约的symbol有时和现货不一样。比如币安现货是BTC/USDT,永续合约是BTC/USDT:USDT。具体格式可以打印exchange.markets查看。

本章知识体系

下面这张图,是我做数据获取时的核心流程:

数据获取核心流程 1. 初始化交易所 2. 选择数据类型 3. 获取数据 Ticker(实时快照) K线(历史数据) 订单簿(深度数据) 4. 频率选择(1s / 1m / 5m / 1h) 5. 计算价差(现货 - 期货)

这张图展示了从初始化到计算价差的完整链路。你跟着这个流程走,基本不会出错。

常见问题

  • 连接超时怎么办?——加代理,或者换节点。我一般用交易所的备用域名。
  • 数据对不上?——检查时间戳。现货和合约的K线时间可能不同步,需要对齐。
  • 频率太高被封?——开启enableRateLimit,或者用多个API Key轮询。

最后说一句:数据获取是整个价差策略的基石。我见过太多人花大量时间优化策略,结果数据源就有问题。先把数据搞干净,后面会省很多事。

专注资料整理