质量治理与维护债务¶
status: active owner: quant-market-data-platform audience: human and agent last_verified: 2026-09-25 source_of_truth: yes superseded_by: n/a
Raw L2 quality profiling¶
The platform owns reusable, read-only structural checks for raw market data. Profile explicit Parquet files without modifying them:
marketdata quality profile \
--file /path/to/order_2024-12-13.parquet \
--output /tmp/l2-quality.json
For a large tree, use the resumable CPU scanner. It writes one checkpoint update per file and keeps the raw Parquet files unchanged:
marketdata quality scan \
--root /path/to/raw-l2 \
--checkpoint /tmp/l2-quality.checkpoint.json \
--output /tmp/l2-quality-summary.json
Before materializing a larger derived dataset, run a low-copy pilot on explicit files. The pilot writes keep-only canonical samples and sparse labels for rows that need review:
marketdata quality pilot \
--file /path/to/deal_2024-12-13.parquet \
--file /path/to/order_2024-12-13.parquet \
--file /path/to/snapshot_2024-12-13.parquet \
--output-dir /tmp/l2-pilot
The pilot does not delete or rewrite its inputs. canonical/ contains rows currently safe for a
downstream sample, while labels/ contains only tag and exclude rows with a source row number.
Install the optional dependency with uv sync --extra quality. Model-input, label, leakage,
alpha, and portfolio checks remain in their downstream research projects.
Before creating directories or writing, the pilot checks every input Parquet footer and the complete output plan. Inputs must not collide on canonical or labels filenames. Repeated source identities, existing output files (including symlinks or hardlinks), and symlinked output subdirectories are rejected. An existing output directory is allowed only when every planned leaf and manifest is new. Exclusive file creation also refuses a destination that appears after preflight.
Keep inputs stable while the pilot runs. Later I/O failures may leave partial derived files; this is not atomic publication or automatic resume. Inspect that output and select a fresh directory instead of deleting or replacing raw inputs.
For raw L2 files, duplicate identity checks are scoped by the resolved security column and ID
column when a security column is available. For example, SecuCode=000001, OrderID=7 and
SecuCode=000002, OrderID=7 are treated as different identities. The report exposes this
contract in id_scope_columns.
Check trade order references separately when both source files are available:
marketdata quality integrity \
--orders /path/to/order_2024-12-13.parquet \
--trades /path/to/trades_2024-12-13.parquet \
--output /tmp/l2-integrity.json
The reusable opening-auction accounting core is available as
quant_market_data_platform.quality_opening. It consumes explicit orders, trades, and cancels,
reconstructs remaining bid/ask levels, and reports unknown identities and overdrawn volume.
Raw-file discovery, event cutoffs, exchange-specific lag, and snapshot alignment remain in
downstream research projects because those rules are market- and experiment-specific.
本页记录 Ruff、ty 覆盖、维护性指标、兼容层生命周期和架构边界的本地治理命令。
这些检查用于暴露历史债务、阻止新增债务扩大,并指导分阶段收紧。
常规门禁¶
常规门禁:
uv run --extra dev python scripts/dev/run_pytest_isolated.py -- -q
uv run --extra dev python -m ruff check .
uv run --extra dev python -m ruff format --check .
uv run --extra dev ty check --error-on-warning
阻塞类型检查是 ty check --error-on-warning。pyproject.toml 中的
[tool.ty.src].include 合并了迁移前的日常检查与发布检查范围,并额外保护 symbols.py。工作区的发布类型检查与日常门禁使用同一配置。
代码健康与评审准则¶
本仓库参考 Google Engineering Practices / Code Review Guide 的代码健康取向,以及 Google Python Style Guide
的清晰 Python 写法。执行口径仍以本仓库 Ruff、ty、pytest、baseline 和公开数据契约为准。
参考资料:
- Google Engineering Practices / Code Review Guide:
https://google.github.io/eng-practices/review/ - Google Python Style Guide:
https://google.github.io/styleguide/pyguide.html
评审和重构时优先检查:
- 变更是否让被修改系统的整体代码健康变好,并避免只让当前 patch 勉强通过。
- 是否保持 CLI、资产键、数据提供方(provider)API、路径、当前数据契约、清单(manifest)schema 和历史产物兼容。
- 是否把新增逻辑放在正确职责边界内,例如数据提供方调用、分页 / 分区循环、清单 builder、options dataclass 和纯日期 helper 分开维护。
- 是否避免新增长函数、大文件、10 个及以上参数函数、隐式公开门面(facade)导出和无法解释的兼容层。
- 是否用聚焦测试覆盖数据提供方 adapter、清单内容、CLI 参数和跨仓契约,并减少对快照式大测试的依赖。
Google-style docstring 只用于公共入口和不显然的 helper。仓库内优先用类型标注、清晰命名、小函数和本地测试表达意图。 不要为了风格一致性做全仓 docstring、重命名或格式化 churn。
债务可见性¶
静态检查覆盖和非阻塞 Ruff debt:
uv run --extra dev python scripts/dev/quality_debt.py
uv run --extra dev python scripts/dev/quality_debt.py --complexity
uv run --extra dev python scripts/dev/quality_debt.py --json --skip-ruff
--complexity 单独使用时只报告 Ruff 的 C90,PLR0911,PLR0912,PLR0913,PLR0915
规则集。本地完整门禁会同时传入 --check-ratchet,阻止复杂度债务超过已接受基线。类型诊断由 ty 阻塞检查直接处理,不再维护另一套诊断债务。
当前仓库有两条活动 GitHub Actions 工作流。.github/workflows/quality.yml 在 PR 和
main 推送时运行公开快照边界检查、共享代码质量 ratchet、Ruff、pytest 和 pip-audit。
.github/workflows/docs.yml 对文档变更执行 strict MkDocs 构建,并在主分支发布 Pages。
PR 上的必需 CI 检查是合并门禁。开发者可按需运行本页列出的本地命令提前发现问题。发布前按目标模块运行 coverage。
维护性指标:
uv run --extra dev python scripts/dev/maintainability_metrics.py
uv run --extra dev python scripts/dev/maintainability_metrics.py --markdown
兼容层和架构边界:
uv run --extra dev python scripts/dev/compatibility_governance.py --check
uv run --extra dev python scripts/dev/architecture_governance.py --check
Baseline 更新¶
只有在变化是有意接受或有意改善时才更新 baseline:
uv run --extra dev python scripts/dev/quality_debt.py --skip-ruff --write-baseline
uv run --extra dev python scripts/dev/quality_debt.py --skip-ruff --check-baseline
uv run --extra dev python scripts/dev/quality_debt.py --skip-ruff --check-ratchet
uv run --extra dev python scripts/dev/maintainability_metrics.py --write-baseline
uv run --extra dev python scripts/dev/maintainability_metrics.py --check-baseline
--check-baseline 会阻止以下回退:
- Ruff 或
ty已检查源码行数下降。 - Ruff 或
ty排除的源码行数上升。 - Ruff 或
ty的源码排除列表新增但 baseline 未更新。 - 已纳入治理的边界模块重新进入 Ruff 或
tyexclude。 - Ruff complexity 诊断数量超过已接受 ratchet。
- 大文件、长函数、超长参数列表或 public facade export 数量超过已接受 baseline。
更新 baseline 的提交说明应包含:
quality_debt.py --json --skip-ruff的当前覆盖摘要。maintainability_metrics.py --json --limit 30的当前热点摘要。- 触发前滚的原因:真实重构、计数口径变化、测试覆盖增加,或明确接受的存量 debt。
- 下一步收紧对象和验证命令。
新增 src/ Python 文件默认进入 Ruff 覆盖。扩大 ty 范围时同步更新配置和 baseline。新增 ty 排除需要同步
scripts/dev/quality_baseline.json、docs/maintenance-audit.md 和提交说明。已列入
quality_debt.PROTECTED_INCLUDED_PATHS_BY_TOOL 的路径不能重新进入 Ruff 或 ty exclude。
长函数 waiver 规则:
- 单函数超过 150 行,提交说明需写出文件、函数、职责边界和后续切片计划。
- 单函数超过 250 行,需补 focused characterization test 或说明已有测试覆盖。
- 单文件超过 800 行,进入
docs/maintenance-audit.md热点表。 - 新增 10 个及以上参数的函数,需要说明调用方稳定性和后续 dataclass / config object 计划。
分阶段准入计划¶
当前优先级:
- Ruff /
ty:data_provider_contracts.py和symbols.py已纳入保护覆盖,并由quality_debt.PROTECTED_INCLUDED_PATHS_BY_TOOL防止重新排除。 2026-07-02 已退役无活跃调用的旧 helper:config_utils.py、pit_feature_stats.py、rebalance.py和rqdata_cli_common.py。 - Ruff:
data_providers.py、data_warehouse.py作为聚合入口与主要 A 股 provider helper 已恢复覆盖。data_providers_core.py已改为薄入口,目前实现位于data_providers_client.py,下一步继续拆分data_providers_client.py的 provider adapters 与 frame pipeline,再逐步加入 stricter 覆盖。 ty:保持已登记范围,新增诊断必须在合入前解决,并按边界模块逐步扩大覆盖。- 类型契约:provider contract 优先使用
Protocol、TypedDict或 dataclass 稳定接口。 - 类型承诺:扩大
ty覆盖并完成下游类型契约验证后再发布py.typed。 - RQData 与港股恢复控制面已在 2026-07-26 完全退役,相关代码与
freeze-hk/hydrate-hk命令已移除。
当前覆盖数据和维护热点见 docs/maintenance-audit.md。
兼容层规则¶
新增 console script alias、旧 import re-export 或 migration-only command 前,必须先更新
docs/compatibility.md,记录用途、风险、推荐替代、清理条件、当前状态和审计证据。
迁移类命令不承载新的平台业务能力。新能力应进入原生 marketdata tushare ... 工作流。RQData 入口已完全退役。
CLI 文档同步规则¶
quant_market_data_platform.cli.build_parser() 可达的所有公开叶子命令都会被治理测试扫描。
新增、移除或重命名 marketdata 命令时,必须同步更新 docs/ 下用户可见文档(包含命令示例或
--help 文本片段),否则 test_public_marketdata_cli_commands_are_documented 将阻塞本地 full gate。
生命周期捕获的 baseline 更新(2026-10-02)¶
共享检查的文件和行数清单从 456 个文件、110,174 行增至 459 个文件、110,790 行。 增加内容为保留引用扫描、独立输入捕获模块及行为测试。长行、复杂度、函数大小和文件大小 上限保持不变。只有完整测试、原有结构门禁和独立审查均通过才能接受本次增量。 以后删除或合并这些实现时,应同步降低文件和行数清单,本次调整不豁免复杂度要求。
QuantZone 直连选项清单(2026-10-03)¶
CLI 直连选项及环境恢复测试增加 83 行 Python(114,313 → 114,396),未增加文件,也未调整复杂度、长行或函数/文件大小预算。删除该选项或合并相关测试时必须相应降低清单基线。
显式研究面板清单更新(2026-10-16)¶
面板读取器及其行为回归测试新增两个 Python 文件。共享 baseline 仅更新实际文件数和行数, 复杂度、长行、函数长度和文件长度上限保持不变。新源码全部纳入 Ruff 和 ty,无新增排除项。 新增测试覆盖整数日期、重复索引、哈希校验和资产类型检查。这是功能与测试增长, 不豁免复杂度债务。未来合并或移除模块时应同步收紧文件和行数清单,并重跑共享 ratchet、 隔离全套测试和既有治理检查。
分钟非交易证据清单更新(2026-10-17)¶
新增独立的非交易证据模块与边界测试,共两个 Python 文件、213 行,文件清单从 486 调整到 488,行数从 115250 调整到 115463。增量用于日期核验、全天停牌与 暂停上市区间,覆盖日内停牌、复牌和未知缺失的拒绝路径。原有复杂度、长行、 函数与文件大小预算保持不变,无新增排除项。未来合并或移除这些模块时须同步 收紧文件和行数清单,退出条件为实际规模下降且完整测试与治理检查通过。
ETF 有界快照清单更新(2026-10-18)¶
有界采集、独立验收及两个行为测试模块增加四个 Python 文件、1249 行。 共享清单从 488 个文件、115463 行调整为 492 个文件、116712 行。 这些增量实现实际请求预算、历史因子核对、分页和收盘后接收凭证, 并覆盖不完整输入及独立复核发现的三个回归场景。 复杂度、长行、函数和文件大小预算保持不变,无新增排除项。 未来删除或合并相关实现时同步降低文件和行数清单。 退出条件为实际代码规模下降,且共享 ratchet、完整测试和治理检查通过。