2. 时间戳的精度陷阱:毫秒与微秒的抉择

做量化回测,时间戳这东西,看着简单,坑却不少。

我见过太多人,策略逻辑写得漂漂亮亮,一跑回测,结果对不上实盘。查来查去,最后发现——时间戳精度不对。毫秒和微秒,就差三个数量级,但带来的问题,能让你怀疑人生。

2.1 为什么时间戳精度这么重要?

说白了,回测就是模拟历史行情。行情数据里,每一笔成交、每一个报价,都带着时间戳。这个时间戳,就是你的「时间坐标」。

你想想看,如果坐标本身是歪的,你画出来的图能对吗?

我个人习惯,拿到行情数据第一件事——先看时间戳的精度。是毫秒?微秒?还是纳秒?不同交易所、不同数据源,给的精度完全不一样。

  • 毫秒级(ms):1秒 = 1000毫秒。大部分国内期货、股票行情是这个级别。
  • 微秒级(μs):1毫秒 = 1000微秒。高频交易、部分数字货币数据会用。
  • 纳秒级(ns):1微秒 = 1000纳秒。极少数场景,比如FPGA直接抓的行情。

嗯,这里要注意:精度越高,数据量越大,处理起来也越慢。但精度不够,又会丢失细节。

2.2 我在项目中遇到的「毫秒陷阱」

有一次,我帮一个团队优化回测系统。他们的策略在A股上跑,回测结果总是比实盘差一截。我查了三天,最后发现——

他们的行情数据是毫秒级的,但策略里判断「是否在同一秒内成交」,用的是int(time.time())。这玩意儿返回的是秒级时间戳!

同一秒内的多笔订单,被当成「同时发生」,导致成交顺序全乱了。

核心问题:时间戳精度不匹配,导致事件顺序错乱。

举个例子:

# 错误做法:秒级精度
t1 = int(time.time())  # 返回 1699000000
t2 = int(time.time())  # 返回 1699000000(同一秒内)
# 两笔订单被当成同时发生

# 正确做法:毫秒级精度
t1 = int(time.time() * 1000)  # 返回 1699000000123
t2 = int(time.time() * 1000)  # 返回 1699000000456
# 顺序清晰可见

2.3 微秒级精度,真的有必要吗?

这个问题,我经常被问到。

我的回答是:看你的策略类型。

策略类型 推荐精度 原因
日频/低频策略 秒级 一天就几笔交易,精度要求不高
分钟级策略 毫秒级 分钟K线内,毫秒够用
高频/算法交易 微秒级 订单簿变化在微秒级别
做市商策略 纳秒级 竞争激烈,差一纳秒就抢不到单

我个人建议:能用毫秒,就别用微秒。微秒级数据,存储成本高,处理也慢。除非你的策略真的需要那么精细。

小技巧:如果你不确定,可以先拿毫秒级数据跑一遍回测。如果结果和微秒级差异小于0.1%,那就用毫秒。省下来的时间,够你多跑几十次回测了。

2.4 时间戳处理的「避坑指南」

我曾经踩过一个坑,说出来你可能不信——

某交易所的行情数据,时间戳用的是本地时间,不是UTC。而且,他们的毫秒部分,是从0开始计数的,不是从Unix纪元开始。

结果呢?我拿这个数据直接跟其他交易所对比,时间完全对不上。折腾了两天,才发现是时区问题。

所以,处理时间戳,我有几个铁律:

  1. 统一转成UTC:所有数据,不管来源,先转成UTC时间。避免时区干扰。
  2. 明确精度单位:在代码里用变量名或注释标明精度。比如timestamp_mstimestamp_us
  3. 不要用浮点数:浮点数精度有限,存时间戳容易出问题。用整数,毫秒就用int,微秒就用int64
  4. 对齐采样频率:如果你的策略是1秒采样一次,那时间戳精度到毫秒就够了。没必要用微秒。
# 推荐的时间戳处理方式
import pandas as pd

# 假设原始数据是毫秒级时间戳
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')

# 如果需要微秒级,先转成微秒再处理
df['timestamp_us'] = df['timestamp'].astype('int64') // 1000

# 统一索引
df.set_index('timestamp', inplace=True)

2.5 知识体系:时间戳精度决策树

为了让你更直观地理解,我画了一张图。这张图展示了如何根据策略类型和数据源,选择合适的时间戳精度。

时间戳精度决策树 策略类型是什么? 低频/日频策略 推荐:秒级精度 中频/分钟级策略 推荐:毫秒级精度 高频/算法交易 推荐:微秒级精度 数据源支持该精度吗? 支持 → 使用该精度 不支持 → 降级到数据源最高精度 最终:精度够用就好,别盲目追求高精度

2.6 性能与精度的平衡

你可能会问:微秒级精度,性能开销大吗?

答案是:非常大

我做过测试,同样一段回测代码:

  • 毫秒级数据:处理100万行,耗时约0.8秒
  • 微秒级数据:处理100万行,耗时约3.2秒
  • 纳秒级数据:处理100万行,耗时约12秒

你看,精度每提升一级,耗时翻4倍。如果你的回测数据有上亿行,这个差距就是天壤之别。

警告:不要为了「看起来更精确」而盲目使用微秒级数据。先问自己:我的策略真的需要吗?如果不需要,就用毫秒。省下来的时间,你可以多跑几十次参数优化。

嗯,最后说一句:时间戳精度,本质上是个「够用就好」的问题。别追求极致,追求合适。


公众号:蓝海资料掘金营,微信deep3321