AllTick
什么是Tick数据?
逐笔数据量化交易行情数据Tick数据金融数据 策略回测

什么是逐笔数据(Tick Data)?

了解什么是 Tick Data(逐笔数据)、它对量化交易的重要性、如何验证历史逐笔记录,以及如何评估市场数据 API,从而提高回测的可靠性。

AllTick阅读 3 分钟

逐笔数据记录单个市场事件,例如成交记录或报价更新,而不是按照固定时间间隔汇总价格。对于量化交易者来说,逐笔数据能够更细致地呈现市场活动,帮助他们发现 K 线图可能掩盖的交易细节。

然而,数据量更大并不意味着分析结果一定更好。缺失记录、重复事件、时间戳不一致,以及对逐笔数据含义的误解,都可能扭曲回测结果。在构建和评估系统化交易策略时,理解这些问题至关重要。

什么是金融市场中的逐笔数据

逐笔数据是一种事件级市场数据。根据行情数据源的不同,一条 Tick 可能代表一笔已完成的交易、一次买价或卖价更新,或其他市场事件。具体定义取决于数据源。

假设某只股票在一分钟内发生了多次价格变化。一分钟 K 线会用四个数值概括这一时间段:

  • 开盘价(Open): 该时间段内记录的第一个价格。
  • 最高价(High): 该时间段内的最高价格。
  • 最低价(Low): 该时间段内的最低价格。
  • 收盘价(Close): 该时间段内记录的最后一个价格。

这些数值可以反映整体价格区间,但无法展示形成这一价格区间的完整事件顺序。

逐笔数据则可以保留这一事件顺序,包括事件价格和时间戳。根据数据源提供的字段,它还可能包含成交量、买卖报价或其他信息。

对于量化交易者来说,这一区别十分重要。两根一分钟 K 线可能拥有相同的 OHLC 数值,但实际价格走势却可能完全不同。因此,如果某个策略依赖分钟内的价格变化,那么使用逐笔数据而不是分钟 K 线进行回测,可能会得到不同的结果。

逐笔数据的时间间隔也并不固定。市场事件会随着实际交易活动发生,而不是按照固定时间间隔到达。事件之间的时间间隔可以提供有用的市场背景信息,但不应单独将其视为衡量市场流动性或波动性的指标。

为什么逐笔数据对量化交易很重要

当交易策略依赖市场事件发生的顺序和时间时,逐笔数据尤其有用。

回测日内交易策略

假设一个策略需要在价格突破某个阈值后入场,那么研究者可能需要知道突破发生的时间,以及突破后市场出现了哪些变化。只要数据集包含所需事件,逐笔记录就能比分钟 K 线提供更详细的历史信息。

评估交易执行与滑点

仅依赖 K 线价格进行回测,可能无法充分反映订单提交时实际可获得的价格。成交数据和报价数据可以帮助研究者更谨慎地设定交易执行假设。不过,只有逐笔数据并不意味着就能准确模拟成交结果、订单队列位置或市场冲击。

研究短期市场行为

逐笔成交和报价更新的顺序,可以帮助研究者分析价格变化、买卖价差和事件发生时间。如果研究需要了解可用订单簿深度,而不仅仅是成交价格,则可能还需要订单簿数据。

所需的数据粒度取决于策略本身。长期策略可能使用日线数据就足够,而对分钟内价格变化十分敏感的策略,则可能需要逐笔数据。

回测前如何检查逐笔数据质量

只有在充分了解历史逐笔数据的局限性后,才能更好地利用这些数据。在运行策略之前,量化交易者应检查数据集是否存在常见的数据完整性问题。

问题检查内容可能造成的影响
数据缺失活跃交易时段内是否存在异常时间间隔重要市场事件可能未被纳入回测
重复事件是否存在标识符或事件字段相同的重复记录重复记录可能扭曲事件数量
无效价格是否存在零值、负值或其他不符合该品种及字段定义的价格错误数值可能产生虚假交易信号
时间戳问题事件是否按时间排序,时区是否一致,时间戳精度是否异常事件顺序和持仓时间可能计算错误
字段不一致是否存在成交量缺失、数据格式变化或证券代码异常数据处理流程可能产生不易察觉的错误

并非所有相同时间戳的记录都是重复数据。由于时间戳精度有限,或者行情源采用特定的事件分组方式,多条有效事件可能拥有相同的时间戳。同样,连续出现相同价格也可能是正常交易现象。

验证时应结合事件类型、可用标识符、数据源规则和交易时段进行判断。数据间隔可能意味着记录缺失,但也可能是市场休市,或者该时间段内没有符合条件的事件。

实用的数据验证流程

下面的 Python 示例可以帮助研究者在回测前识别可疑记录。

text
import pandas as pd

df = pd.read_csv("ticks.csv")

df["timestamp"] = pd.to_datetime(
    df["timestamp"], utc=True, errors="coerce"
)
df["price"] = pd.to_numeric(
    df["price"], errors="coerce"
)

# 检查无效时间戳和价格
invalid = df[
    df["timestamp"].isna()
    | df["price"].isna()
    | (df["price"] <= 0)
]

# 分析事件间隔前,先按时间排序
df = df.dropna(subset=["timestamp", "price"])
df = df.sort_values("timestamp")

# 标记重复记录,以便进一步检查
duplicates = df[
    df.duplicated(keep=False)
]

print("Invalid records:", len(invalid))
print("Repeated records for review:", len(duplicates))

此示例假设 CSV 文件包含 timestamp 和 price 两列。它可以识别潜在问题,但不能证明所有被标记的记录都是错误数据。重复检查会比较所有列,因此在实际生产环境中,应根据数据源和交易品种选择合适的字段进行判断。

在计算事件间隔之前,还应考虑交易时段、时区和市场休市时间。不要通过人为生成交易记录或价格来自动填补缺失时段。如果策略需要完整的事件序列,而数据又不完整,则应排除受影响的时间段,或者明确记录相关限制。

不同市场的逐笔数据有什么区别

不同资产类别的逐笔数据并不完全相同。

在交易所交易的股票市场中,成交记录和报价可能来自集中式交易所行情源,但具体覆盖范围和可用权限取决于数据提供商。外汇市场属于场外交易市场,因此某个行情源可能只反映特定流动性提供商或交易场所的活动,而不是全球市场的所有交易。

因此,不同数据提供商的 Tick 数量可能存在差异,但这并不一定意味着其中某一方的数据遭到了破坏。事件定义、数据覆盖范围、时间戳精度和过滤规则都可能造成差异。

在选择量化策略所需的数据时,应确认行情源记录的是成交、报价还是两者兼有,覆盖哪些交易品种和交易时段,以及历史数据与实时数据是否采用相同的规则。

如何通过 AllTick 获取逐笔行情数据

AllTick 为股票、外汇、加密货币、贵金属和大宗商品等市场中的受支持品种提供行情数据 API。对于量化交易者而言,具体选择取决于任务是查询可用的市场数据,还是持续接收实时更新。

REST 接口支持通过请求查询市场数据,包括最新成交数据和历史 K 线数据。WebSocket 接口则支持订阅受支持市场事件的实时更新。这两种方式的功能不同:不能默认认为实时订阅接口能够提供无限期的历史逐笔数据。

你可以查看 AllTick API 文档 和 AllTick 开发者代码仓库,了解当前的接口、请求参数、支持的交易品种和集成示例。

在评估行情源时,应根据策略需求进行测试,检查时间戳处理、事件定义、交易品种覆盖范围、连接恢复机制,以及可用历史数据是否足以支持目标回测。请妥善保管 API 密钥,避免在公开代码中直接嵌入有效令牌。

构建更可靠的逐笔数据交易策略

逐笔数据为量化交易者提供了更详细的市场活动记录,但其价值取决于市场活动是否得到准确记录和正确解释。可靠的工作流程需要结合合适的数据粒度、数据质量验证、合理的交易执行假设,以及明确记录的数据限制。

在相信回测结果之前,应先验证事件字段,检查可疑的数据缺口和重复记录,并确认历史数据符合策略的实际需求。这些检查有助于区分真正有潜力的交易信号与由数据不完整或处理错误所产生的结果。

立即开始接入市场数据

几秒内生成免费 API 密钥,通过一个端点连接所有市场。