From latency-hunter
行情数据质量"照妖镜"——用户把订单簿/K线/tick 行情数据或数据采集/解析/落库/读取代码丢过来,逐项审查"会让数据悄悄变脏、进而毒害策略和回测"的工程坑(盘口交叉、深度缺口、checksum 失配、snapshot/增量衔接错误、序列缺口、K线缺失/重复/乱序、未闭合 bar 泄漏、时间戳单位混淆/漂移/时区、未来时间戳、symbol 归一化、幸存者偏差),定位到 文件:行,按严重度(致命/高危/中/低)输出一张"数据体检报告"。 触发词(中):订单簿审查、行情数据质量、数据照妖镜、交叉盘口、深度缺口、checksum 校验、增量衔接、K线缺失、时间戳乱序、重复 bar、未闭合 bar、未来 bar、时间戳单位、时区错误、时钟漂移、symbol 归一化、幸存者偏差。 触发词(英):orderbook sanity、market data quality、crossed book、checksum mismatch、snapshot delta splice、sequence gap、kline gap、duplicate bar、out-of-order timestamps、unit confusion、clock skew、survivorship bias、orderbook-sanity。 不适用:策略 alpha/信号逻辑/调参(那是策略层)、非数据问题的通用代码审查、实盘下单/风控逻辑本身的 bug、要你承诺数据"绝对干净/零脏数据"(工程审查只能降低风险,不能背书数据完美)。
How this skill is triggered — by the user, by Claude, or both
Slash command
/latency-hunter:orderbook-sanityThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
脏数据是**静默杀手**。盘口交叉、checksum 失配、K线缺口、时间戳漂移这类问题**不会抛异常、不会让程序崩溃**——它们只会让你的因子、信号和回测悄悄建在沙子上:回测曲线漂亮得不像话,实盘却怎么也对不上。
脏数据是静默杀手。盘口交叉、checksum 失配、K线缺口、时间戳漂移这类问题不会抛异常、不会让程序崩溃——它们只会让你的因子、信号和回测悄悄建在沙子上:回测曲线漂亮得不像话,实盘却怎么也对不上。
最危险的不是"明显坏掉"的数据(那种一眼能看出来),而是数值仍然合法、类型仍然正确、却语义错误的数据:一个落在 1970 年的毫秒时间戳、一根还在形成中的未闭合 bar、一个序列号连续却被错误应用、checksum 已经对不上的本地订单簿。它们能静默通过所有"非空校验",一路污染到 PnL。
本 skill 不写策略、不调 alpha。它只做一件事:像照妖镜一样,把会让数据悄悄变脏的工程坑逐个照出来,定位到 文件:行,告诉你为什么会脏、怎么自测确认、怎么修。
更高一层的铁律:命中可疑模式只是"线索"不是"判决"。 行情里大量"看起来脏"的现象其实是真实市场状态——停牌的真缺口、冷门 symbol 的零量桶、极速行情里一瞬的锁价、跨所聚合时 A 所买价高于 B 所卖价的真实套利。每条陷阱都标注了"合法例外",审查时务必读上下文区分真坑与真实行情,否则报告会被假阳性淹没、失去可信度。
不适用:求策略 alpha、信号调参、实盘下单/风控逻辑 bug、非数据的通用代码审查、要你保证数据"绝对干净"。
path/to/file.py:行号,并贴出触发的代码片段(code smell),不要泛泛说"可能有问题"。找不到证据的项标"未发现/需人工确认",绝不脑补。df['open_time'].is_monotonic_increasing、df.duplicated(subset=['symbol','open_time']).sum()),让用户自己在真实数据上确认,而非只听你口述。每一类的完整陷阱清单、检测代码与修复方案见 references/orderbook-pitfalls.md,下面只列每类最致命的几条作为审查锚点。
详细的检测代码、code smell、修复方案见 references/orderbook-pitfalls.md,这里只给每类最该先抓的几条。每条格式:陷阱名 — 怎么发现(含合法例外) — 修复方向。
U/u/pu)衔接即可,不算漏校验——只对确实下发 checksum 的交易所判该坑。修:按交易所文档逐字复现 checksum(档数、价×量拼接顺序、定点格式化),每次应用增量后比对,失配即丢弃本地簿重拉 snapshot;价格用定点整数当 key 避免浮点拼接误差。u <= lastUpdateId 的增量 → 首条应用的增量必须满足 U <= lastUpdateId+1 <= u,否则中间漏/重一段,本地簿从第一根就偏。合法例外:不同交易所衔接规则不同(OKX/Bybit 的 seq 字段语义、首帧是否含 snapshot 都不一样),按该所文档核对,别用 Binance 规则硬套别家。修:严格按交易所衔接规则,首条增量做 U/u/lastUpdateId 区间断言,断言失败即重拉。best_bid >= best_ask。增量更新丢包/乱序后本地簿失同步的典型症状,任何基于盘口的报价、midprice、价差信号全错。合法例外:① snapshot 拼接窗口内、极速行情一瞬的锁价(locked, bid==ask) 在个别撮合/聚合口径下可短暂出现,需看是否瞬时自愈;② 跨交易所聚合簿里 A 所 best_bid > B 所 best_ask 是真实跨所套利机会,不是脏数据——只对单一交易所同一本地簿判交叉为坑。修:每次应用 update 后断言 best_bid < best_ask;单簿持续交叉即丢弃本地簿重拉 snapshot。qty==0 / size==0 / 空数组表示删除该价格档,不是"把价格置 0"、也不是"保留一个零数量档"。处理错会在簿里留下幽灵档 / 深度缺口,midprice、深度加权价全错。修:qty==0 一律 del book[price](档不存在则忽略),绝不写入零档。U/u/pu 序列号跳号,意味着漏掉了 update,本地簿必然偏离真实状态。修:逐条断言 next == prev+1(或该所衔接规则),缺口即丢弃本地态 + 重拉 snapshot;重快照本身也要退避+限频防死循环。盘口类陷阱以本地簿失同步为核心,检测优先级:checksum 失配 > 衔接错误 > seq 缺口 > 交叉 > 深度缺口。有 checksum 的交易所务必优先校 checksum——它能抓到前几项都漏掉的"静默脏簿"。详见 references。
is_closed=false / Binance WS 的 k.x=false)当终值用——回测里是典型未来函数,实盘会用一个"close 还会变"的 bar 触发交易,回测虚高、实盘对不上。合法例外:做实时盘中展示/监控(画当前正在走的那根)时用 forming bar 合法——只对"forming bar 的值进入信号/落库为终值/喂回测"判致命。修:仅 k.x==true 才采纳为终值;forming bar 标 provisional,永不入信号、永不当终值落库。ffill/回补把真空洞填成假数据。修:用期望时间网格 reindex 找缺口,先分类:真缺口(交易所有数据但你没采到)走 REST 回补;停牌/休市/无量(交易所也没有)标 halted/NaN 并在下游显式跳过,不参与 rolling 相邻关系。open_time 多条、同 tradeId 多次。成交量被重复累加,VWAP 虚高。合法例外:REST 翻页边界重叠、WS 重连后重推本就是预期行为,正确姿势是幂等去重而非报警——别把"收到重复帧"本身当 bug,只对"重复数据被累加/重复计量"判坑。修:以 (symbol,interval,open_time) / tradeId 做幂等去重 + DB 唯一约束,入库 upsert 而非 append。tradeId 跳号。所有 rolling/shift/diff 假设有序,乱序则相邻关系全错;tradeId 缺口意味着成交永久丢失。合法例外:同一毫秒内多笔成交,transact_time 相等但 tradeId 递增属正常,需用 (transact_time, tradeId) 复合键判序而非单看时间戳。修:入库前强制按复合键排序,tradeId 缺口走 REST 回补。low <= min(open,close) 且 high >= max(open,close) 被破坏,通常是字段映射 o/h/l/c 错位或聚合 bug。下游突破/ATR/止损全错。修:向量化断言硬性 reject 并定位映射代码。tick 级额外关注:成交乱序需用
(transact_time, tradeId)复合键;重复成交按 tradeId 幂等;活跃 symbol 的零量 bar 多为合成占位 bar(可疑),但冷门 symbol 的零量桶是真实无成交(合法)——按流动性区分,别一刀切。详见 references。
pd.to_datetime 永远带 unit,转换后跑年份范围 sanity check(2020s 秒级约 1.7e9、毫秒约 1.7e12、微秒约 1.7e15)。ts > now 的记录(本地写错单位、时钟漂移、交易所事件时间与接收时间混用都会造成)必须隔离待查,绝不能进训练/回测(等于看到未来)。数据为空时区分两种相反情形:交易所维护/停牌/休市(标 halted,不交易、不回补)vs 采集丢数据(真缺口,需回补)——两者处理完全相反,认错方向要么填进假数据、要么丢掉真信号。修:入口加 ts <= now()+容差 断言;空数据分类前不做任何 ffill/回补。-1021)、延迟测量失真。修:周期请求交易所 /time 测 offset = serverTime - localTime,签名补偿,本机 NTP 校时。event_time 与 recv_time,聚合/对齐用 event,延迟监控用差值。BTCUSDT vs BTC-USDT vs XBTUSD,spot vs perp)不同。合法例外:跨所聚合时盘口"交叉"是真实套利(见 ①),按 UTC 时间戳 join 时不同所同一时刻数据本就有差异,别把真实价差当对齐错误。修:按 UTC 时间戳 join 而非行号 zip,建符号映射表区分市场类型(spot/perp/季度),映射缺失 fail-loud 而非静默归并。审查结论按下面格式输出,可直接截图。严重度用 emoji + 中文档级(与本工具集
commands/orderbook-sanity.md一致),每条带文件:行和实测校验,致命在前。命中可疑模式但读上下文后判为真实行情/合法用法的,写入"已排除"小节而非问题清单。
══════════════════════════════════════════
数据体检报告 · orderbook-sanity
══════════════════════════════════════════
数据流: 采集(__) → 解析(__) → 落库(__) → 读取(__)
审查范围: <文件/数据样本清单> 扫描文件: N 个
总评: 🔴 致命 a 项 · 🟠 高危 b 项 · 🟡 中 c 项 · 🔵 低 d 项
判语: 「<这是干净行情,还是建在沙子上的脏数据?>」
—— 一句不留情面但克制的整体结论;不背书"绝对干净"
────────────── 问题清单(按严重度) ──────────────
[🔴 致命] checksum 未校验(本地簿可能已静默失同步)
位置: src/feed/orderbook_okx.py:––(订阅 books 频道但全文件无 crc32 比对)
现象: OKX books 频道每帧带 checksum,代码只按 seq 衔接、从不比对 checksum
毒害: seq 连续但档位被错误应用/精度截断时无法察觉 → 本地簿静默偏离
实测: 复现 OKX 文档的 CRC32(top-25 档、bid/ask 价×量拼接)与帧内 checksum 比对;
持续失配率 > 0 即本地簿有脏
修复: 逐字复现 checksum,失配即丢弃本地簿重拉 snapshot;价格用定点整数当 key
[🔴 致命] 使用未闭合 bar 泄漏
位置: src/feed/kline_ws.py:88
现象: k.x 字段未判断,forming bar 的 close 直接入信号
毒害: 回测未来函数 → 实盘对不上回测
实测: last_bar.close_time > now() 即被使用了未闭合 bar
修复: 仅 k.x==true 才采纳为终值;forming bar 标 provisional 永不入信号
[🔴 致命] 时间戳单位混淆
位置: src/parse/ts.py:23
现象: pd.to_datetime(ts) 未带 unit,秒级时间戳被当纳秒,bar 落到 1970
实测: df['open_time'].dt.year.between(2017,2030).all() 为 False 即中招
修复: 入口统一 epoch ms,to_datetime 永远带 unit,转换后跑年份 sanity check
[🟠 高危] snapshot/增量衔接未做区间断言 ...
[🟠 高危] K线缺口未分类(停牌真缺口 vs 采集丢包混处理) ...
[🟡 中] 活跃 symbol 零量占位 bar ...
[🔵 低] 缺缺口率/失配率监控埋点 ...
────────────── 已排除(命中但判为真实行情/合法用法) ──────────────
- 跨所聚合簿 A.bid > B.ask: 真实套利价差,非单簿交叉(aggregate.py:54)
- BTCUSDT 周末日线缺口: 该所 7×24 无此问题 / 或确认为休市非丢数据
- REST 翻页边界重复 bar: 已 upsert 幂等去重,非计量重复
────────────── 实测建议(请在真实数据上跑) ──────────────
说明: 以上是"代码里会让数据变脏的结构性坑 + 样本可静态看出的异常",
不等于全量数据扫描。命中是否成立、多严重,以你在真实数据上的实测数字为准。
建议断言: checksum 失配率、best_bid<best_ask 违例数、open_time 单调性与重复数、
年份范围 sanity、ts<=now 违例数、缺口分类后真缺口/停牌占比。
优先处置: 先堵致命(checksum/未闭合 bar/单位混淆/衔接错误)→ 再修缺口分类与去重 → 最后补监控埋点。
══════════════════════════════════════════
报告原则:每条必带 位置;找不到证据的项标"未发现/需人工确认",不硬凑;命中可疑模式但读上下文后判为真实行情/合法用法的,写进"已排除"而非问题清单;判语克制、不羞辱、不夸张;绝不承诺"修完就绝对干净"——结论以实测数字为准。
| 严重度 | 含义 | 处置 |
|---|---|---|
| 🔴 致命 | 静默注入未来函数或让数据语义彻底错乱,直接导致回测虚高/实盘对不上(未闭合 bar、单位混淆、幸存者偏差、checksum 失配、snapshot/增量衔接错误、未来 bar) | 必须修,修前别信任何基于该数据的回测结论 |
| 🟠 高危 | 数据会偏离真实状态,污染因子/信号但不一定全错(序列/深度缺口、重复/乱序、盘口交叉、qty==0 删档错误、OHLC 破坏、时区错误);注:纯 K 线缺口须先做"停牌真缺口 vs 采集丢包"分类——分类前不直接定高危,误把真实休市当丢数据回补本身就是新的脏数据源 | 应尽快修,修前对受影响区间的结论打折 |
| 🟡 中 | 边缘场景或可恢复的质量问题(活跃 symbol 零量占位 bar、时钟漂移测量、离群尖刺隔离) | 建议修,至少加监控指标 |
| 🔵 低 | 健壮性 / 可观测性欠缺(缺数据质量埋点、缺缺口率/checksum 失配率统计) | 可选,有余力再补 |
判定基准:"这个值在该时点真能算出来吗?这根盘口/这桶 bar 是本地簿真实状态,还是失同步/采集错误的产物?这个时间戳单位/时区对吗?" ——同时反问"它会不会其实是真实市场状态(停牌/无量/极速/跨所)?" 两问交叉后再定罪。
Searches MemPalace before answering questions about past work, people, projects, or prior decisions. Returns verbatim stored content instead of guessing from model memory.
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Implements vector databases with Pinecone, Weaviate, Qdrant, Milvus, pgvector for semantic search, RAG, recommendations, and similarity systems. Optimizes embeddings, indexing, and hybrid search.
npx claudepluginhub paidaxing1234/latency-hunter-toolkit --plugin latency-hunter