数据获取与清洗:交易所API对接、历史数据获取、数据清洗与对齐、Tick级与K线级数据
做市策略回测,第一步就是搞数据。这事儿听起来简单,但坑特别多。我见过不少团队,策略逻辑写得漂漂亮亮,结果一跑回测,收益曲线漂亮得不像话——后来发现是数据没对齐,把未来的信息算进去了。嗯,这种错误我也犯过,一次就长记性了。
交易所API对接:没那么简单
对接交易所API,说白了就是跟交易所的服务器打交道。你得知道它什么时候给你数据,给你什么格式的数据。
我个人习惯先看文档,再看代码。很多新手上来就写代码,结果被限流、被断开连接,一脸懵。
核心要点:
- REST API:适合拉取历史数据,请求-响应模式,简单直接
- WebSocket:适合实时数据流,交易所主动推送,延迟低
- 限频控制:每个交易所都有请求频率限制,超了会被封IP
举个例子,币安的REST API请求频率是每分钟1200次。你想想看,如果你写个循环去拉数据,每秒发20个请求,不到一分钟就被封了。我刚开始做的时候,就因为这个被币安封了三次IP,后来老老实实加了限速逻辑。
import time
import requests
def fetch_klines(symbol, interval, limit=500):
url = "https://api.binance.com/api/v3/klines"
params = {
"symbol": symbol,
"interval": interval,
"limit": limit
}
response = requests.get(url, params=params)
# 限速控制:每请求一次,休息0.1秒
time.sleep(0.1)
return response.json()
小技巧:用WebSocket接收实时数据时,记得处理断线重连。我曾经有一次没做重连逻辑,结果策略跑了三天,数据断了24小时,回测结果完全不能用。
历史数据获取:从哪里来,到哪里去
历史数据是回测的基石。你拿到的数据质量,直接决定了回测的可信度。
数据来源主要有三个:
- 交易所官方API:最可靠,但有限制,拉取大量数据很慢
- 第三方数据提供商:比如Kaiko、CoinMetrics,数据全但收费
- 社区数据集:比如Kaggle上的数据集,免费但质量参差不齐
我个人建议,初期先用交易所API拉数据,够用了。等策略成熟了,再考虑付费数据。
拉取历史数据时,要注意时间范围。做市策略通常需要至少3个月的数据,最好是6个月以上。为什么?因为市场有周期性,3个月可能只覆盖了一个趋势,6个月才能看到震荡、趋势、回调等各种情况。
注意:有些交易所的历史数据API只提供最近几个月的数据。比如币安的K线数据,最多能拉1000根。如果你需要1分钟级别的数据,1000根只够16个小时。这时候就得用循环拉取,每次拉500根,然后拼接起来。
def fetch_historical_klines(symbol, interval, start_time, end_time):
all_klines = []
current_start = start_time
while current_start < end_time:
klines = fetch_klines(symbol, interval, limit=500)
if not klines:
break
all_klines.extend(klines)
# 更新起始时间
current_start = klines[-1][0] + 1
return all_klines
数据清洗与对齐:脏数据是回测的毒药
数据拿到手,别急着用。先洗一洗。
数据清洗,说白了就是去掉那些明显不对的数据。我遇到过的情况:
- 缺失值:某根K线数据为空,可能是交易所宕机了
- 异常值:价格突然跳涨100倍,明显是数据错误
- 重复值:同一时间戳出现两条数据
- 时间戳错乱:数据的时间顺序不对
清洗逻辑其实不复杂,但一定要做。我曾经有一次没做清洗,结果回测里出现了一根K线,开盘价100,收盘价10000,策略在那根K线上赚了100倍——后来发现是数据错误。
def clean_klines(klines):
cleaned = []
for k in klines:
# 检查缺失值
if None in k:
continue
# 检查异常值:价格不能为0或负数
if k[1] <= 0 or k[2] <= 0:
continue
# 检查重复值
if cleaned and k[0] == cleaned[-1][0]:
continue
cleaned.append(k)
return cleaned
数据对齐,是另一个容易踩坑的地方。不同交易所的数据,时间戳可能不一样。有的用毫秒,有的用秒。有的用UTC时间,有的用本地时间。
我习惯把所有数据统一成毫秒级时间戳,并且全部转成UTC时间。这样在做多交易所回测时,数据才能对齐。
对齐规则:
- 统一时间单位:毫秒
- 统一时区:UTC
- 统一时间粒度:比如都用1分钟K线
- 缺失时间戳:用前一根K线填充,或者直接丢弃
Tick级与K线级数据:精度与效率的权衡
做市策略对数据精度要求很高。K线数据虽然方便,但丢失了很多细节。Tick级数据记录了每一笔交易,信息最完整。
但Tick级数据也有问题:数据量太大。一天的数据可能就有几百万条,处理起来很慢。
我个人建议:
- 策略开发阶段:用K线数据,速度快,方便调试
- 策略验证阶段:用Tick级数据,精度高,能发现K线数据看不到的问题
- 实盘模拟阶段:必须用Tick级数据,因为做市策略的利润来自买卖价差,K线数据根本体现不出来
举个例子,你在K线数据里看到某根1分钟K线的收盘价是100.5,开盘价是100.0。但实际Tick数据可能显示,这一分钟内价格在100.0到100.5之间来回跳了20次。做市策略如果只看K线数据,会以为价格很平稳,但实际上波动很大,策略可能早就被止损了。
经验之谈:如果你刚开始做做市策略,先用K线数据跑通逻辑,再用Tick数据做精细回测。别一上来就搞Tick数据,数据量太大,处理起来很痛苦。
知识体系总览
下面这张图,概括了本章的核心内容。你可以把它当作一个检查清单,看看自己有没有遗漏什么。
数据获取与清洗,是整个回测流程中最枯燥但最重要的一环。你花80%的时间做数据,可能只占20%的工作量。但正是这80%的数据工作,决定了回测结果是否可信。
我个人觉得,做量化交易,数据能力比策略能力更重要。策略可以抄,数据能力抄不来。你想想看,同样的策略,用不同的数据跑,结果可能天差地别。所以,别嫌麻烦,把数据搞扎实了,后面的路才好走。