关于 fxview-parquet-consumer
面向 FXView MT5 行情数据的技能,说明如何读取和查询 Parquet 格式的 tick 文件,并提供已核实的架构与文件布局。适合构建数据适配器、DuckDB 查询及 Python 或 Rust 数据管道。
主要功能
- 01说明 tick 数据的列类型与含义
- 02描述 Parquet 文件目录和命名规则
- 03提供 DuckDB 查询示例
- 04解释 flags 位掩码及历史编码变化
- 05涵盖分段文件与常见问题
适用场景
- 01用 DuckDB 查询指定交易日的 tick
- 02计算买卖价差统计
- 03将 tick 数据接入 Python 或 Rust 管道
- 04排查文件布局或 flags 解读问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ terrylica/ cc-skills --skill fxview-parquet-consumer安装后在 Claude Code 中输入/fxview-parquet-consumer确认已加载。
详细介绍
FXView Tick Parquet 消费者
从 MT5 tick 收集系统生成的 Parquet 文件中读取 FXView tick 数据。
自我演进技能:此技能会在使用过程中不断改进。如果指令有误、参数发生偏移或需要采用变通方案,请立即修复此文件,不要拖延。仅针对真实且可复现的问题进行更新。
何时使用此技能
在以下情况下使用此技能:
- 读取或查询 FXView tick Parquet 文件
- 为 FXView tick 数据构建适配器或流水线
- 针对 tick 数据编写 DuckDB 查询
- 将 tick 数据集成到 Python 或 Rust 流水线中
- 检查 tick 数据架构或文件布局
权威来源
https://github.com/terrylica/mql5/blob/05f7c82/docs/tick_research/SCHEMA_VERIFIED.md
此技能概述了已验证的架构。如需完整的验证详情、标志分布和行组内部信息,请参阅源文档。
架构
所有 6 列均不可为空。EURUSD 和 XAUUSD 文件的架构相同。
| 列 | Arrow 类型 | DuckDB 类型 | 可为空 | 备注 |
|---|---|---|---|---|
| time_msc | Int64 | BIGINT | 否 | Unix 纪元毫秒数 |
| bid | Float64 | DOUBLE | 否 | 买价 |
| ask | Float64 | DOUBLE | 否 | 卖价 |
| last | Float64 | DOUBLE | 否 | FXView 外汇中始终为 0.0——忽略 |
| volume | Int64 | BIGINT | 否 | FXView 外汇中始终为 0——忽略 |
| flags | UInt8 | UTINYINT | 否 | MqlTick 标志位掩码(历史上有 6 种取值;应检查掩码位,绝不要匹配字面值) |
Parquet 页脚元数据
嵌入每个文件页脚中的键值对:
| 键 | 示例值 | 用途 |
|---|---|---|
| symbol | EURUSD | 裸符号名称(无 FXVIEW_ 前缀) |
| digits | 5 (EURUSD) / 2 (XAUUSD) | 价格小数位数 |
| broker | FXView | 经纪商名称 |
| created_at | 2026-03-24T10:32:35.101090+00:00 | 文件创建时间戳(RFC3339 UTC) |
文件布局
目录模式: {base_path}/FXVIEW_{SYMBOL}/{YYYY}/{SYMBOL}_{YYYYMMDD}.parquet
示例: ~/.cache/opendeviationbar/ticks/FXVIEW_EURUSD/2026/EURUSD_20260323.parquet
重要的不对称之处: 目录使用 FXVIEW_ 前缀(带经纪商标识),但文件名和元数据使用裸符号名称。请勿混淆。
崩溃恢复文件: {SYMBOL}_{YYYYMMDD}_1.parquet、_2.parquet 等。当 EA 重启并发现当天已有文件时创建。所有分段都是有效、完整且带有页脚的 Parquet 文件。
XAUUSD 差异
| 属性 | EURUSD | XAUUSD |
|---|---|---|
| digits | 5 | 2 |
| 价格尺度 | ~1.15 | ~4400 |
| 每日 tick 数 | ~416K | ~929K |
| last/volume | 始终为 0 | 始终为 0 |
| 标志分布 | 53% bid+ask、24% bid、23% ask | 98% bid+ask、bid/ask 各约 1% |
XAUUSD 的 tick 密度约为 EURUSD 的 2.2 倍。
DuckDB 使用示例
读取单日数据
SELECT * FROM read_parquet('~/.cache/opendeviationbar/ticks/FXVIEW_EURUSD/2026/EURUSD_20260323.parquet');
通过 glob 读取某个符号的所有文件
SELECT * FROM read_parquet('~/.cache/opendeviationbar/ticks/FXVIEW_EURUSD/**/*.parquet');
将时间戳转换为易读格式
SELECT make_timestamp(time_msc * 1000) AS ts, bid, ask, ask - bid AS spread
FROM read_parquet('~/.cache/opendeviationbar/ticks/FXVIEW_EURUSD/2026/EURUSD_20260323.parquet');
点差统计
SELECT avg(ask - bid) AS avg_spread, max(ask - bid) AS max_spread
FROM read_parquet('~/.cache/opendeviationbar/ticks/FXVIEW_EURUSD/2026/EURUSD_20260323.parquet');
标志分布
SELECT flags, count(*) AS cnt, round(count(*) * 100.0 / sum(count(*)) OVER (), 2) AS pct
FROM read_parquet('...')
GROUP BY flags
ORDER BY cnt DESC;
反模式
- 不要使用 FXView 外汇数据的
last或volume列(始终为零) - 不要假设文件名带有
FXVIEW_前缀——该前缀只出现在目录名中 - 不要在 Rust 生产代码中使用 f64 表示价格(根据 digits 元数据使用 i64 定点数)
- 不要以秒为单位理解 time_msc——它的单位是毫秒
- 不要硬编码机器路径——使用模式
{base_path}/FXVIEW_{SYMBOL}/{YYYY}/{SYMBOL}_{YYYYMMDD}.parquet
Parquet 内部结构
- 压缩: ZSTD level 3
- time_msc 编码: DELTA_BINARY_PACKED(适用于单调时间戳的最优编码,禁用字典编码)
- flags 编码: 字典编码(基数较低;完整历史中有六个不同值,典型日期有三个)
- bid、ask、last、volume: 默认(PLAIN + ZSTD)
- 行组: 每组约 65,536 行(最后一组包含余数)
- 文件大小: EURUSD 每日约 416K 个 tick 时约为 1.35 MB
Flags 位掩码参考
请对文档所述的位进行掩码运算,绝不要匹配字面值。 对于 bid 更新,使用 flags & 2 <> 0;对于 ask 更新,使用 flags & 4 <> 0。这两种编码及两个历史转换时期都适用。WHERE flags = 130 或 flags IN (130, 134) 在 2026-04-23 至 2026-08-13 的整个时间范围内都会返回 零个 bid tick。
整个数据湖的统计(2018-04 至 2026-08,所有交易品种,测量于 2026-08-29;issue #155)。完整历史中,该列有六个取值:
| 事件 | 第 7 位形式(通常) | 裸值形式 |
|---|---|---|
| bid 更新 | 130 (=128|2) | 2 |
| ask 更新 | 132 (=128|4),仅截至 2018-06-15 | 4 |
| bid+ask 更新 | 134 (=128|6) | 6 |
- 截至 2018-06-15,每天的取值集合都恰好是
[130, 132, 134];从 2018-06-17 起则为[4, 130, 134],且132不再出现。 - 裸值
2和6首次出现于 2021-07-01,之后间歇性出现,并从 2026-04-23 至 2026-08-13 连续出现。取值集合为[2, 4, 6]的日期(例如 2021-07-02)并非数据中断或文件损坏:所有 tick 都存在,只是采用了裸值编码。 - 第 7 位(128)没有文档说明。 MQL5 的
MqlTick参考 明确定义了六种 tick 标志(TICK_FLAG_BID、TICK_FLAG_ASK、TICK_FLAG_LAST、TICK_FLAG_VOLUME、TICK_FLAG_BUY、TICK_FLAG_SELL),其中没有一个是 128。该经纪商会在大多数 tick 上设置第 7 位,但其含义尚未确定;不要称它为“首个 tick 标记”(因为不存在TICK_FLAG_FIRST)。
故障排除
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 找不到文件 | 基础路径或交易品种错误 | 检查带有 FXVIEW_ 前缀的目录模式 |
| last/volume 全为零 | FXView 外汇数据的正常情况 | 外汇货币对请忽略这些列 |
| 时间戳看起来不正确 | 使用了秒而非毫秒 | time_msc 的单位是毫秒——乘以 1000 可转换为微秒 |
| 架构不匹配 | 经纪商或版本不同 | 对照 SCHEMA_VERIFIED.md 永久链接进行验证 |
| 同一天有多个文件 | 崩溃恢复分段 | 所有带 _N 后缀的文件都有效,请将它们合并 |
执行后反思
此技能执行完毕后,关闭前请检查:
- 命令是否成功? — 如果没有,修复导致失败的指令或错误表。
- 参数或输出是否发生变化? — 如果底层工具的接口发生偏移,请更新 Usage 示例和 Parameters 表以保持一致。
- 是否需要变通方案? — 如果你不得不临时调整(更换标志、增加步骤),请更新此 SKILL.md,以便下次调用时无需采用相同的变通方案。
只有问题确实存在且可复现时才进行更新,不要基于猜测更新。