数据获取与清洗:交易所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数据,数据量太大,处理起来很痛苦。

知识体系总览

下面这张图,概括了本章的核心内容。你可以把它当作一个检查清单,看看自己有没有遗漏什么。

数据获取与清洗知识体系 数据来源 数据获取 数据处理 交易所API REST / WebSocket 第三方数据商 社区数据集 历史数据拉取 限频控制 循环拼接 时间范围选择 数据清洗 缺失值处理 异常值过滤 重复值去重 数据对齐 Tick级 vs K线级 高质量回测数据

数据获取与清洗,是整个回测流程中最枯燥但最重要的一环。你花80%的时间做数据,可能只占20%的工作量。但正是这80%的数据工作,决定了回测结果是否可信。

我个人觉得,做量化交易,数据能力比策略能力更重要。策略可以抄,数据能力抄不来。你想想看,同样的策略,用不同的数据跑,结果可能天差地别。所以,别嫌麻烦,把数据搞扎实了,后面的路才好走。

专注资料整理