2. 回测系统搭建:Python环境准备、数据源获取(Tick级数据)、回测引擎架构设计

做抢单策略,最怕什么?

怕回测结果漂亮,实盘一跑就崩。我见过太多人,拿着日线级别的回测曲线,兴冲冲杀进高频战场,结果被Tick级的数据噪声打得鼻青脸肿。说白了,抢单策略的回测,必须从Tick级数据开始。

这一章,咱们就把回测系统的地基打牢。我会把我在搭建这套系统时踩过的坑、总结的经验,一股脑倒出来。

2.1 Python环境准备:别在工具上翻车

我个人习惯用Python 3.9+,太老的版本有些库不支持,太新的又怕兼容性问题。嗯,这里要注意,别用Anaconda自带的那个Python,版本经常落后。

核心依赖清单

  • 数据处理:pandas(必须2.0+)、numpy
  • 高性能计算:numba、cython(可选)
  • 数据存储:h5py(HDF5格式)、pyarrow(Parquet格式)
  • 时间处理:arrow、datetime
  • 回测框架:自己写(推荐),或者用backtrader(改起来费劲)

我曾经在项目里直接用pip install一把梭,结果numba和pandas版本冲突,跑个回测报错半小时。后来学乖了,用虚拟环境隔离。

# 创建虚拟环境
python -m venv tick_backtest_env

# 激活(Windows)
tick_backtest_env\Scripts\activate

# 激活(Mac/Linux)
source tick_backtest_env/bin/activate

# 安装核心库
pip install pandas==2.0.3 numpy==1.24.3 numba==0.58.1 h5py==3.9.0 pyarrow==12.0.0

小技巧:把依赖写进requirements.txt,团队协作时直接pip install -r requirements.txt,省心。

2.2 数据源获取:Tick级数据,贵但值得

抢单策略的命根子就是数据。日线、分钟线?那都是给趋势策略玩的。咱们要的是每一笔成交的细节——价格、数量、时间戳、买卖方向。

数据来源,我主要用这几个:

数据源 特点 成本 推荐指数
交易所官方API 最原始、最准确,但需要自己攒 免费(但有流量限制) ⭐⭐⭐⭐
第三方数据商(如Wind、聚宽) 清洗过,但可能有延迟 贵(年费几万起) ⭐⭐⭐
开源数据集(如Binance历史数据) 免费,但质量参差不齐 免费 ⭐⭐

我个人建议,起步阶段用交易所的WebSocket接口自己攒数据。虽然麻烦,但你能确保数据是原汁原味的。我刚开始做的时候,图省事买了第三方数据,结果回测时发现时间戳被四舍五入到了毫秒级,抢单策略直接废了。

数据格式,我推荐用Parquet。为什么?

  • 压缩率高,Tick级数据一天几个GB,Parquet能压到几百MB
  • 读取速度快,pandas直接读,不用转格式
  • 支持列式存储,你只取需要的字段就行
import pandas as pd
import pyarrow.parquet as pq

# 读取Tick数据
df = pd.read_parquet('btc_usdt_tick_20240101.parquet')

# 看看数据结构
print(df.head())

# 输出示例:
#                     timestamp    price    volume  side
# 0 2024-01-01 00:00:00.123456  42350.2  0.0015    buy
# 1 2024-01-01 00:00:00.124001  42350.1  0.0020    sell
# 2 2024-01-01 00:00:00.124500  42350.3  0.0018    buy

注意:Tick数据的时间戳一定要精确到微秒级(6位小数)。毫秒级(3位小数)对于抢单策略来说,太粗糙了。我曾经因为数据商只提供毫秒级时间戳,导致回测里出现了大量「同时成交」的假象,策略看起来无敌,实盘一跑就亏。

2.3 回测引擎架构设计:别把引擎做成「铁板一块」

回测引擎,说白了就是一个模拟器。你把历史数据喂进去,它模拟订单簿的变化,然后让你的策略在模拟环境里跑。

我见过很多人的回测引擎,代码全写在一个文件里,几千行,改个参数都要找半天。你想想看,这哪是引擎,分明是炸弹。

好的架构,应该是模块化的。我习惯分成三层:

  • 数据层:负责读取、清洗、对齐Tick数据
  • 引擎层:负责驱动时间推进、撮合订单、更新订单簿
  • 策略层:负责接收市场数据、生成交易信号、管理仓位

下面这张图,是我自己设计的回测引擎核心流程。你看一眼,心里就有数了。

回测引擎核心架构 数据层 Tick数据读取 & 清洗 引擎层 时间推进 & 订单撮合 策略层 信号生成 & 仓位管理 循环处理每个Tick 订单簿(Order Book) 性能监控 & 日志 数据流方向:从左到右,每个Tick循环一次 虚线表示模块间的依赖关系

引擎层的核心,是时间推进机制。说白了,就是按时间顺序,一个一个Tick地处理。每个Tick进来,先更新订单簿,然后问策略:「现在这个行情,你要不要下单?」

代码骨架大概是这样的:

class BacktestEngine:
    def __init__(self, data_path, strategy):
        self.data = self._load_data(data_path)
        self.strategy = strategy
        self.order_book = OrderBook()
        self.positions = {}
        self.equity_curve = []
    
    def _load_data(self, path):
        # 读取Parquet文件
        df = pd.read_parquet(path)
        # 按时间排序,确保顺序正确
        df = df.sort_values('timestamp')
        return df
    
    def run(self):
        for idx, tick in self.data.iterrows():
            # 1. 更新订单簿
            self.order_book.update(tick)
            
            # 2. 检查是否有未成交订单
            self._check_pending_orders(tick)
            
            # 3. 调用策略,生成信号
            signal = self.strategy.on_tick(tick, self.order_book)
            
            # 4. 执行信号
            if signal:
                self._execute_order(signal, tick)
            
            # 5. 记录权益曲线
            self._record_equity(tick)
    
    def _execute_order(self, signal, tick):
        # 这里要处理滑点、手续费等
        # 我习惯在回测里加一个「滑点模型」
        fill_price = tick.price + signal.direction * self.slippage
        # ... 执行逻辑

核心要点

  • 每个Tick都要更新订单簿,不能跳过
  • 滑点模型必须加,抢单策略对滑点极其敏感
  • 记录每个Tick的权益变化,方便后续分析

2.4 避坑指南:我踩过的那些坑

做回测系统,有几个坑是绕不开的。我一个个说。

坑一:未来函数

这是最常见的坑。比如你在回测里用了「当根K线收盘价」来判断开仓,但实际交易中,收盘价是走完才知道的。Tick级回测里,这个问题更隐蔽——你可能不小心用了「下一个Tick」的数据。

我曾经在写订单簿更新逻辑时,把当前Tick的成交价当成了下一个Tick的买入价,结果回测收益翻倍,实盘直接腰斩。后来我加了一条铁律:每个Tick只能使用它之前的数据

坑二:数据对齐

如果你同时回测多个品种,一定要确保它们的时间戳是对齐的。我见过有人把BTC和ETH的Tick数据直接拼在一起,结果因为两个交易所的时间戳差了0.1秒,策略在回测里频繁套利,实盘根本不存在这种机会。

坑三:性能瓶颈

Tick级数据量巨大,一天可能上百万条。如果用纯Python循环,一个月的回测可能要跑几个小时。我的解决方案是用numba加速核心循环,或者用Cython把撮合逻辑编译成C代码。

from numba import jit

@jit(nopython=True)
def match_order(order_book, tick):
    # 用numba加速撮合逻辑
    # 速度能提升10倍以上
    pass

小技巧:先用小数据量(比如1天的Tick)调试逻辑,确认没问题了,再跑全量数据。别一上来就跑一个月,等半天发现有个bug,心态会崩。

好了,回测系统的地基就打到这里。数据准备好了,引擎搭起来了,下一步就是往里面填策略逻辑了。记住,回测系统是你的实验室,实验设备越精密,实验结果越可信。

专注资料整理