feat: add Quant OS A-share baseline
This commit is contained in:
@@ -0,0 +1,274 @@
|
||||
# Quant OS architecture and trust boundaries
|
||||
|
||||
Quant OS 是项目;`quant60` 是第一版 A 股 Baseline 内核、CLI namespace
|
||||
和 artifact 协议前缀。当前形态是模块化单体:共享可移植计算和稳定合同,但把
|
||||
数据供应商、hosted 平台、QMT 专有运行时与券商事实放在不同信任边界内。
|
||||
|
||||
```text
|
||||
JQData (authorized account)
|
||||
get_bars(raw OHLCV/money, factor, pre_close, limits, paused)
|
||||
+ daily PIT is_st + daily PIT index membership
|
||||
|
|
||||
v
|
||||
canonical immutable snapshot
|
||||
exact-set/hash + semantic reconstruction
|
||||
|
|
||||
+---------+----------+
|
||||
| |
|
||||
v v
|
||||
snapshot-backtest snapshot-decision
|
||||
local event engine Signal -> Target -> Order Delta
|
||||
| |
|
||||
+---------+----------+
|
||||
|
|
||||
portable-momentum-v1
|
||||
|
|
||||
+------------+-------------+
|
||||
| | |
|
||||
JoinQuant bundle QMT bundle local contract oracle
|
||||
hosted backtest built-in/qmttools backtest-only
|
||||
|
||||
synthetic PIT/features -> purged walk-forward -> Ridge challenger
|
||||
(not deployment-frozen)
|
||||
|
||||
Qlib 0.9.7:
|
||||
native portable-momentum signal bridge
|
||||
Alpha158 + LightGBM + Recorder research workflow
|
||||
(no L3 target / L4 order-intent parity)
|
||||
|
||||
XtTrader:
|
||||
read-only broker observation -> HMAC account-bound shadow plan
|
||||
callback/mutation boundary remains uncertified and operator-inaccessible
|
||||
```
|
||||
|
||||
箭头表示数据或合同流,不表示平台能力等价。hosted 引擎拥有自己的时钟、行情
|
||||
和成交语义;broker snapshot/callback 才是现金、持仓、可卖量、订单和成交的
|
||||
事实权威。本地 ledger 不能用预测持仓覆盖券商事实。
|
||||
|
||||
## Runtime split
|
||||
|
||||
| Layer | Runtime | Rule |
|
||||
| --- | --- | --- |
|
||||
| Quant OS / `quant60` | Python ≥3.10 | 本地回测、snapshot pipeline、research、ledger、CLI |
|
||||
| JQData ingestion | 独立 Python 环境,`jqdatasdk==1.9.8` | 只从授权账户获取数据;凭据不进入快照 |
|
||||
| Qlib research | CPython 3.12.x,`pyqlib==0.9.7` | 与本地/QMT 环境隔离;provider 必须授权且版本化 |
|
||||
| Portable strategy core | Python 3.6-compatible source | 无第三方依赖;bundler 内联到 hosted 策略 |
|
||||
| JoinQuant hosted | 平台管理 | 上传生成的单文件;不能假设安装本地包 |
|
||||
| QMT built-in | QMT Python 3.6 | 只上传 bundle;模块全局 `g` 持久状态,避免 `ContextInfo` 用户属性回滚 |
|
||||
| qmttools / XtTrader | 券商分发的 native Python | `xtquant` 专有且 lazy import,不进入仓库 |
|
||||
| Colab | notebook runtime | 默认只跑无账号流程;JQData/Qlib 是显式可选 cell |
|
||||
|
||||
不要用一个 Python 环境强行兼容所有路径。
|
||||
|
||||
## Data plane and point-in-time semantics
|
||||
|
||||
JQData adapter 的输入合同是逐交易日历史指数成员和 `get_bars` 日线字段:
|
||||
|
||||
- 未复权 `open/high/low/close`、`volume`、`money`;
|
||||
- 复权因子 `factor`;
|
||||
- `pre_close`、`high_limit`、`low_limit`、`paused`;
|
||||
- 每个 member-date 的严格布尔 PIT `is_st`;
|
||||
- `skip_paused=False`,保留停牌日语义。
|
||||
|
||||
快照保存 `bars.jsonl`、`memberships.jsonl`、`quality.json` 和
|
||||
`manifest.json`。发布期间存在 incomplete marker;完成后 verifier 要求目录
|
||||
是精确 artifact 集、每个文件 hash 正确,并从 JSONL 重建领域对象,重算质量
|
||||
汇总、内容 hash 和 `data_version`。这比“下载成功”更强,但在授权真实账户运行
|
||||
并保存许可/lineage 前,仍不构成 G1 证据。
|
||||
|
||||
JQData 日线在 24:00 完成,因此 adapter 拒绝把 Asia/Shanghai retrieval
|
||||
当日作为 `T_CLOSE_COMPLETE`;请求 `end` 必须早于抓取日期。字段、ST 或成员
|
||||
覆盖不完整也不会被当成默认 false/空集合。
|
||||
|
||||
`snapshot-decision` 只用 `as_of` 当日精确 PIT 成员和截至当日的数据。
|
||||
执行/名义价格保持 raw;动量把每个历史 close 乘以当日可见 factor,再归一到
|
||||
决策日因子,因此后续公司行动不会改写已经形成的历史决策。held but
|
||||
untradable 标的不会从 Universe 消失,而会进入 frozen / hold-only /
|
||||
sell-only 状态。
|
||||
|
||||
若目标用于下一交易日开盘前 shadow,Signal 时钟仍是 T 日 15:00。snapshot
|
||||
冻结 JQData `get_trade_days` 与 `get_all_trade_days` 一致性校验后的完整
|
||||
交易日序列,并显式保存 end 日后的唯一 `next_trading_session`。decision、
|
||||
broker snapshot 和 shadow plan 必须绑定同一个相邻 session,以及
|
||||
Asia/Shanghai `[09:00,09:30)` 的 `first_executable_window`;elapsed-day
|
||||
阈值和 weekday 近似都不是权威。周末、T 日 15:01、错过 09:30、错误 session 或
|
||||
迟到多日全部 fail closed,国庆等长假只要下一 session 来自冻结日历即可。
|
||||
|
||||
账户绑定后还必须保持决策规模有效。shadow 对 `decision.equity` 和当前
|
||||
`total_asset` 使用固定的
|
||||
`max(1 元, 0.01% × abs(decision equity))` 包含边界容差;缺失、负数、
|
||||
非有限值或超差都不能进入 ready,超差原因码为
|
||||
`DECISION_EQUITY_DRIFT`。该合同进入 plan hash,verifier 会从原始两个权益值
|
||||
重新计算差额、阈值和 blocker。
|
||||
|
||||
QMT shadow verifier 使用 semantic replay,而不把 plan 当成事实来源。
|
||||
`broker_observation.json` 保存 query 后 adapter state、live flag、callback
|
||||
error/live-authorization history 计数、query 起止、原始记录数、校验结果及
|
||||
脱敏资产/持仓/委托/成交事实。原始 decision manifest 是 verify 的必需输入。
|
||||
纯 replay 从这两个输入独立重建 account binding、clock gate、资产和现金
|
||||
恒等式、open/order-stability、trade/fill identity、完整 blocker 集、
|
||||
snapshot-valid、完整 broker snapshot、逐 symbol target/weight/lot、
|
||||
board-lot/sellable feasible delta、proposal、portfolio 和 status,再与 plan
|
||||
exact compare。因而 plan 中同步改写多个派生字段或删除 blocker 不能形成新的
|
||||
`SHADOW_READY`;READY 也强制存在可重建 snapshot。
|
||||
|
||||
普通 artifact hash 之外,planner 使用既有 account HMAC key 和独立 domain
|
||||
签署 `QMT_SHADOW_EVIDENCE_V1` envelope。envelope 绑定完整 plan、
|
||||
broker observation、broker snapshot 的 canonical 内容 hash 和三份实际发布
|
||||
bytes 的 SHA-256、原始 decision manifest hash、planner/engine 及 operator
|
||||
entrypoint `tools/qmt_shadow_plan.py` source hash,以及 semantic version、
|
||||
10 秒/1 元 policy ceiling 和 equity drift policy。四个发布 JSON(包括
|
||||
不参与自签名的 manifest)还必须逐 byte 符合唯一 deterministic writer
|
||||
encoding。verifier 从当前真实输入与磁盘实际 bytes 重建
|
||||
envelope 并 constant-time 比较 MAC;缺失、错误或轮换后的 key 全部失败。
|
||||
这提供的是 Quant OS 本地 evidence publisher authenticity/完整性,不是
|
||||
QMT/券商对 query result 的原生签名,也不把 adapter 升级成 broker-certified。
|
||||
|
||||
策略安全阈值是 canonical policy:query window 上限 10 秒,资产/持仓市值和
|
||||
`cash + market_value = total_asset` 的绝对容差上限 1 元。CLI 只能使用等于
|
||||
或更严格的值,builder 与 replay 都拒绝更宽值。目标权重总和还必须不超过
|
||||
1,作为无报价条件下可独立证明的决策现金预算;实时 buying power(含成交价、
|
||||
费用和卖出先后)仍不作证明。
|
||||
|
||||
持仓 drift 不会复用旧持仓:每次 target diff 都从当前券商 positions 和
|
||||
sellable quantity 重算,且 open/变化中订单会阻断。因此数量 residual 不会
|
||||
因旧持仓静默失真。由于 shadow 没有实时执行价,现金购买力仍不能被证明;
|
||||
plan 明示该限制,ready 仅供人工审阅,不能升级为 live submission。
|
||||
`trade.amount` 当前会被标准化、认证和重放,但在缺少真实
|
||||
terminal/xtquant build 探针时不假设它与 `price × quantity` 的精确误差
|
||||
合同;它不参与 target diff,正式券商验收必须记录 build 并冻结字段容差。
|
||||
|
||||
`snapshot-backtest` 在每个历史决策日重新调用同一 decision path,并使用:
|
||||
|
||||
- 第一实际交易日完整收盘形成计划;
|
||||
- 紧接着下一实际交易日开盘尝试成交;
|
||||
- 当日供应商停牌/涨跌停/前收字段;
|
||||
- 上一交易日成交量参与率;
|
||||
- T+1、百股交易单位、显式费用和未成交撤销。
|
||||
|
||||
这是本地 fill model,不是 JoinQuant 或 QMT 的成交事实。
|
||||
|
||||
## Research and model boundary
|
||||
|
||||
synthetic research pipeline 已实现:
|
||||
|
||||
- PIT table 和未来值拒绝;
|
||||
- Universe 原因码;
|
||||
- 透明价量特征与 T+1-open 标签时钟;
|
||||
- train-only winsor/impute/standardize;
|
||||
- purge/embargo walk-forward;
|
||||
- deterministic Ridge、OOS IC/RankIC;
|
||||
- factor risk、dated cost/capacity 和 constrained target。
|
||||
|
||||
这些功能证明研究管线可执行。Ridge 尚未冻结成带版本、输入 schema 和推理
|
||||
hash 的 deployment bundle,也没有授权真实长样本 OOS 与四引擎推理验证,因此
|
||||
不是生产 champion。
|
||||
|
||||
Qlib 路径固定为 `0.9.7`。CPython 3.12 实际 fixture smoke 已得到:
|
||||
|
||||
- native momentum:24 条 signal;
|
||||
- Alpha158 + LightGBM:完成 fit、SignalRecord、SigAnaRecord、
|
||||
PortAnaRecord 和 model 保存;
|
||||
- 两条 workflow 都保存表级 hash、行列/时间边界和从 portfolio report
|
||||
重算的有限值指标,明确 `investment_value_claim=false`;
|
||||
- local MLflow file store 使用时,runner 以
|
||||
`os.environ.setdefault("MLFLOW_ALLOW_FILE_STORE", "true")` 显式确认。
|
||||
|
||||
该 fixture 只有两只股票和一个 benchmark,性能没有投资意义。Qlib 的单一
|
||||
`limit_threshold` 也不能表达逐日板块/ST 规则,所以它只参与 L1/L2 和诊断
|
||||
L6,不声称 L3 target 或 L4 order-intent parity。
|
||||
|
||||
## Portable strategy and platform boundary
|
||||
|
||||
当前可跨 hosted wrapper 冻结的共同基线是 `portable-momentum-v1`。平台 API
|
||||
不得进入 symbol normalization、momentum score、target weight、target
|
||||
quantity 和 order delta 计算。
|
||||
|
||||
canonical 股票代码采用 JoinQuant 形式:
|
||||
|
||||
| Canonical | QMT/XtQuant | Qlib |
|
||||
| --- | --- | --- |
|
||||
| `600000.XSHG` | `600000.SH` | `SH600000` |
|
||||
| `000001.XSHE` | `000001.SZ` | `SZ000001` |
|
||||
| `830799.XBSE` | `830799.BJ` | `BJ830799` |
|
||||
|
||||
转换权威是 `quant60.portable_core.normalize_symbol`。当前 XtTrader mutation
|
||||
边界只接受 `.SH` / `.SZ`,不能从转换覆盖推导北交所实盘覆盖。
|
||||
|
||||
QMT built-in bundle 和 qmttools runner 都硬限制为 backtest/history。built-in
|
||||
状态存放在模块全局 `g`,不写入可能在下个 `handlebar` 回滚的
|
||||
`ContextInfo` 用户属性。两条路径固定中证 500 benchmark、PIT 历史成分/ST
|
||||
与 baseline 费率;built-in 的 10% 参与率由 QMT GUI 设置,qmttools
|
||||
程序化传入。live mutation 只存在于外部 XtTrader adapter,并且默认关闭、
|
||||
未认证、没有 live 启动命令;operator 可运行的 shadow CLI 只接受查询边界。
|
||||
|
||||
## Stable artifacts and release integrity
|
||||
|
||||
最低交换合同是:
|
||||
|
||||
- [`signal.schema.json`](../schemas/signal.schema.json);
|
||||
- [`target.schema.json`](../schemas/target.schema.json);
|
||||
- [`order_event.schema.json`](../schemas/order_event.schema.json);
|
||||
- [`broker_snapshot.schema.json`](../schemas/broker_snapshot.schema.json)。
|
||||
|
||||
`verify-manifest` 不仅检查 ledger hash chain,还检查 incomplete marker、
|
||||
精确 artifact 集、SHA-256、ledger head、report/manifest identity、
|
||||
saved/current source aggregate、saved/current schema aggregate 和 payload
|
||||
schema。`verify-snapshot-decision` 与 data snapshot semantic verifier 承担
|
||||
各自边界的同类职责。
|
||||
|
||||
这些合同已有自动测试;最近一次标准库套件为 211 tests、OK、3 个可选路径
|
||||
skip。测试结果不能替代 schema 迁移演练、真实平台导出或券商回调认证。
|
||||
|
||||
## Clocks and reconciliation
|
||||
|
||||
canonical weekly clock 是:
|
||||
|
||||
```text
|
||||
ISO 周第一实际交易日:完整 close
|
||||
-> 使用 as_of 之前实际可得信息形成 signal/target/order intent
|
||||
紧接着下一实际交易日:open executable window
|
||||
-> 刷新市场规则与 broker snapshot
|
||||
-> pre-trade gate
|
||||
-> backtest/shadow submit 或 fail closed
|
||||
-> callback append + reconciliation
|
||||
```
|
||||
|
||||
“紧接着下一日”是交易日关系,不是固定星期几。每个真实平台 run 必须记录
|
||||
`signal_as_of`、`last_feature_bar`、`first_executable_time`、
|
||||
price adjustment 和 fill model。
|
||||
|
||||
完整 reconciliation 要同时比较 cash、positions、sellable quantities、
|
||||
open orders 和带时区的新鲜 `as_of/source_time`。legacy/partial snapshot
|
||||
即使数值碰巧平衡,也不能把 `safe_to_open` 设为 true。
|
||||
|
||||
## Facts and current claim
|
||||
|
||||
| Fact | Authority |
|
||||
| --- | --- |
|
||||
| canonical symbol、portable calculation | versioned source + config |
|
||||
| snapshot 内容 | semantic verifier 通过的 immutable snapshot + manifest |
|
||||
| historical provider entitlement | 实际数据账户许可与保存的 lineage 记录 |
|
||||
| hosted 回测时钟/成交 | 平台真实导出 |
|
||||
| cash、position、order、fill | broker snapshot/callback |
|
||||
| 程序化交易权限与报告 | 实际券商书面确认 |
|
||||
| Gate 状态 | [`gate_scorecard.json`](../gate_scorecard.json) |
|
||||
|
||||
synthetic/fake 数据是合同测试,不是市场证据;Qlib synthetic fixture 的真实
|
||||
运行是运行时证据,不是收益证据;mock parity exporter 是 wrapper 合同证据,
|
||||
不计 G9。
|
||||
|
||||
## Remaining production gaps
|
||||
|
||||
当前还缺:
|
||||
|
||||
- 授权 JQData 真实快照、基本面公告 PIT、完整公司行动/Security Master;
|
||||
- Ridge/LightGBM 冻结模型包和真实 OOS 证据;
|
||||
- 真实数据校准的风险、冲击、容量和 TCA;
|
||||
- 真实 JoinQuant/QMT 导出;
|
||||
- 券商状态映射、restart recovery daemon、20 日 shadow 与连续对账;
|
||||
- 运维监控、kill-switch 演练和程序化交易合规确认。
|
||||
|
||||
所以 Quant OS 是可执行、可继续填证据的生产候选框架,不是已经达到整体
|
||||
60 分的实盘系统。证据政策见
|
||||
[`AUDIT_2026-07-25.md`](AUDIT_2026-07-25.md)。
|
||||
@@ -0,0 +1,250 @@
|
||||
# 2026-07-25 复评:为什么原文还不是“整体 60 分”
|
||||
|
||||
审计对象:`个人 A 股量化系统机构级 60 分 Baseline 技术选型设计:从聚宽研究到 QMT 实盘(2026-07-22)`
|
||||
|
||||
结论先行:
|
||||
|
||||
| 刻度 | 分数 | 准确含义 |
|
||||
| --- | ---: | --- |
|
||||
| 设计覆盖度 | 约 70/100 | 原文已经讨论研究、数据、风险、成本、组合、执行、运维与合规的大部分责任边界 |
|
||||
| 可实施规格度 | 49/100 | 只有约一半内容足够明确,工程师无需继续发明字段、默认值、失败语义和验收口径 |
|
||||
| 原实现证据 | 6/100 | 截至 2026-07-22,主要证据是文章、架构图、外部资料与验收清单;没有可重放代码、数据、测试或平台运行记录 |
|
||||
| 硬门 | 0/10 | G1—G10 都缺少完整验收证据;不是“部分通过” |
|
||||
|
||||
这三条分数不能相加,也不能互相替代。设计覆盖 70 不代表系统得 70;代码文件存在也不代表 Gate 通过。依据原文自己的定义,达到 Baseline 60 必须同时满足:
|
||||
|
||||
```text
|
||||
证据评分 >= 60
|
||||
且 G1 ... G10 全部通过
|
||||
```
|
||||
|
||||
当前 Quant OS 代码交付是一个可执行、可测试的工程起点;`quant60` 是其第一版
|
||||
A 股 Baseline 内核。它的新增得分必须在授权数据、真实平台运行、QMT 影子盘、
|
||||
连续对账和券商合规确认完成后,逐项写回
|
||||
[`gate_scorecard.json`](../gate_scorecard.json)。本报告不预支这些分数。
|
||||
|
||||
截至 2026-07-26 的实现事实快照:
|
||||
|
||||
- 截至 2026-07-26 的最新标准库全量测试为 `Ran 211 tests`、`OK (skipped=3)`;
|
||||
- JQData raw/factor/pre-close/limits/paused + 每日 PIT `is_st`/指数成员
|
||||
已连接到 semantic snapshot verifier、`snapshot-backtest` 和
|
||||
`snapshot-decision`,并拒绝把抓取当日未到 24:00 的日线标成完整收盘,
|
||||
但尚未用用户授权账号跑真实快照;
|
||||
- CPython 3.12 + `pyqlib==0.9.7` native momentum fixture 已真实运行并产生
|
||||
24 条 signal;
|
||||
- Qlib Alpha158 + LightGBM + Recorder fixture smoke 已真实成功;两条
|
||||
Qlib workflow 均保存表级 hash、边界和从 portfolio report 重算的指标,
|
||||
runner 会为 local MLflow file store 显式设置
|
||||
`MLFLOW_ALLOW_FILE_STORE=true`;
|
||||
- fixture 只有两只 synthetic 股票,任何性能数字都没有投资意义;
|
||||
- JoinQuant/QMT mock parity exporter 已实现,但
|
||||
`real_platform_pass=false` 且不计 G9;
|
||||
- 2026-07-26 已完成一次 2024 全年真实 JoinQuant hosted smoke,可见日志
|
||||
无 ERROR;它证明 runtime/path,但尚无完整同输入导出和本地 strict peer;
|
||||
- XtTrader 已有严格只读、HMAC 账户绑定的 observation/snapshot/shadow
|
||||
plan 与 verifier,但真实 QMT、broker callback/shadow 均未运行,
|
||||
G1—G10 仍全部 `not_passed`。
|
||||
|
||||
## 1. 审计方法
|
||||
|
||||
本次没有按“名词是否出现”评分,而是对原文每个责任域检查六类问题:
|
||||
|
||||
1. 是否明确输入、输出和时钟;
|
||||
2. 是否给出机器可校验的数据契约;
|
||||
3. 是否处理异常、恢复和幂等;
|
||||
4. 是否给出确定默认值或明确标记待确认;
|
||||
5. 是否有可运行实现和自动化测试;
|
||||
6. 是否有来自目标平台、真实数据或券商的运行证据。
|
||||
|
||||
“设计覆盖度”主要看第 1 类及责任域是否齐全;“可实施规格度”要求前 4 类足够清楚;“实现证据”只认可第 5、6 类已保存的产物。外部文档说明某 API 有能力,不等于本系统已经正确调用它。
|
||||
|
||||
## 2. 原文做对了什么
|
||||
|
||||
原文比常见的“因子 + 回测净值”方案完整得多,70 分设计覆盖主要来自:
|
||||
|
||||
- 明确拆开 `Forecast → Target → Order → Fill`,避免预测、仓位和成交混为一谈;
|
||||
- 意识到 PIT、历史指数成分、退市样本、公告可得时间和公司行动;
|
||||
- 把风险、成本、换手和流动性放到事前组合决策,而不是只在绩效末尾扣滑点;
|
||||
- 讨论部分成交、撤改单、乱序回报、重启、三账对账和 kill switch;
|
||||
- 把本地、聚宽、Qlib、QMT 定位为不同角色,而不是追求单一平台全包;
|
||||
- 给出十道硬门,且明确“目标 66”只有在实现、模拟和券商确认后才成立;
|
||||
- 对深模型、混合整数优化、逐笔队列与多券商容灾做了合理的 V1 边界控制。
|
||||
|
||||
因此问题不是方向错误,而是大量段落仍处于“正确的架构意图”,没有下降为可执行合同和证据。
|
||||
|
||||
## 3. 不足全景
|
||||
|
||||
| 责任域 | 原文已有 | 阻止整体 60 的主要缺口 | 最低补证 |
|
||||
| --- | --- | --- | --- |
|
||||
| 数据/PIT | 分层目录、`available_time`、数据版本思想 | 无真实字段字典、供应商字段到 canonical 的映射、公告时区/盘前盘后规则、历史修订样例、许可边界和 PIT 注入测试 | 固定数据快照、manifest、字段级时点规范、反未来函数测试 |
|
||||
| Security Master / Universe | PIT 成分、开/持/卖/冻结状态 | 无状态 schema、生效区间合并优先级、代码变更与退市/重组样例;指数成分来源和发布日期语义未冻结 | 历史 fixture 与逐原因码重放 |
|
||||
| 特征/标签/验证 | LightGBM + Ridge、purge/embargo、walk-forward | 无特征公式和缺失值策略的完整注册表;标签价格与可执行时钟未机器化;无 purge 算法、切分日历和未触碰测试集 | 训练配置、切分测试、冻结 OOS 报告 |
|
||||
| 风险 | 透明行业/风格风险模型与收缩思想 | 因子定义、估计窗、缺失暴露、协方差清洗、特异风险下限、行业映射版本和压力场景均未定 | 风险快照 schema、数值稳定性测试、压力报告 |
|
||||
| 成本/容量 | 日期化费用、价差与冲击公式 | 参数没有账户交割单或真实成交校准;最低佣金的非凸性如何进入候选/rounding 未实现;机会成本缺失 | 费率版本、逐笔 TCA、low/base/high 校准 |
|
||||
| 组合 | 连续优化 + rounding/repair 方向正确 | 目标函数量纲、风险厌恶系数、约束优先级、不可行诊断、冻结仓位与现金联立细节未形成求解器规格 | 可解释优化输出、不可行/rounding 回归测试 |
|
||||
| 本地回测 | 要求与执行器同源 | 没有事件时钟、公司行动、现金结算、价格基准、成交量切片和可重放输出合同 | 小型确定性 fixture、黄金输出、费用/T+1/涨跌停测试 |
|
||||
| 聚宽 | 定位为第二引擎 | 无可上传入口、参数表、调度回调、`avoid_future_data` 设置、结果导出和平台限制清单 | 上传包、平台回测记录、canonical 差异报告 |
|
||||
| QMT 内置 Python | 只笼统写 QMT/XtQuant | 没有处理内置 Python 3.6 与本地现代环境的边界;未说明 GUI 启动方式、回调入口和产物导出 | Python 3.6 薄核心、QMT 内置回测记录 |
|
||||
| qmttools | 未与其他 QMT 路径清楚分层 | 原文没有说明 `run_strategy_file` 是原生 Python 驱动 QMT 策略文件的独立运行形态,不能等同于 XtTrader OMS | 独立入口、版本/参数记录、回测结果导出 |
|
||||
| XtTrader | 异步 OMS 方向正确 | 无券商状态码映射、session/account 配置、连接恢复、查询与回调竞态、撤单确认、未知单处置 | 脱敏回调回放、重启/乱序/重复测试、20 日影子盘 |
|
||||
| Qlib | 工作流选型合理 | “接 Qlib”与“由 Qlib 完成本系统回测”边界模糊;无 provider URI、dataset handler、workflow YAML、canonical 转换和 Records 产物 | Python 3.12 锁定环境、固定数据、Qlib smoke/OOS 报告 |
|
||||
| 跨引擎 | 提出双引擎一致性 | 未定义到底比较输入、信号、目标、订单还是净值;没有容差、舍入、交易日历和差异原因码 | 见 [`CROSS_ENGINE_CONSISTENCY.md`](CROSS_ENGINE_CONSISTENCY.md) 的逐层合同 |
|
||||
| Schema/版本迁移 | 列出九类对象 | 原文只有字段清单,不是 JSON Schema;无 `schema_version`、兼容策略、正反例与验证命令 | 版本化 schema、fixture 和 CI 验证 |
|
||||
| 可复现 | Git/config/data/model/rules 版本思想 | 无 run manifest 格式、环境锁、随机源清单、原子发布、干净机复跑或 hash 容差 | 可保存 manifest、两次重放差异 |
|
||||
| 运维/安全 | 提到单机、告警、runbook | 无部署命令、目录权限、凭据注入、日志脱敏、磁盘满/时钟偏差/重复调度/损坏账本处置 | [`SECURITY.md`](SECURITY.md) 与故障演练记录 |
|
||||
| 合规 | 正确设为硬门 | 只链接通用法规;没有实际券商对账户、软件、频率、报告状态的确认 | 券商书面确认索引与“先报告、后交易”记录 |
|
||||
|
||||
## 4. 可实施规格为什么只有 49
|
||||
|
||||
原文的伪代码和目录树提供了良好边界,但工程实现仍需自行决定很多会改变结果的事实。例如:
|
||||
|
||||
- `AlphaForecast` 写了“分数/预期超额”,却没有决定两者是否都必填、单位是什么、是否允许空值;
|
||||
- “按公告可得时间进入”没有定义 15:00 后公告应进入哪个交易日、时区和供应商延迟如何处理;
|
||||
- “Guarded TWAP/POV”没有冻结子单切片、限价、超时、撤单确认和窗口结束残单政策;
|
||||
- “差异在数值容差内”没有给各层容差,也没有区分浮点误差与平台成交机制差异;
|
||||
- “QMT adapter”没有区分 QMT 内置 Python、`qmttools.run_strategy_file` 与外部 `XtTrader` 三条生命周期不同的路径;
|
||||
- “Qlib workflow”没有给 provider、handler、dataset、model、record 和数据转换的可运行组合;
|
||||
- “三本账”没有定义事件唯一键、追加一致性、崩溃点、重复回调去重和 broker snapshot 的事实优先级。
|
||||
|
||||
当实现者必须自行补完这些选择时,文章仍是设计说明,不是完整实施规格。新仓库中的四个 JSON Schema 只是把一小部分边界机器化,不能倒推原文在 7 月 22 日已经拥有这些证据。
|
||||
|
||||
## 5. 原实现证据为什么只有 6
|
||||
|
||||
6 分不是对文章质量的否定,而是严格区分“说明”和“运行事实”。原文当时可认可的证据主要是:
|
||||
|
||||
- 一份结构完整、明确承认条件性的设计文章;
|
||||
- 一张架构图和可编辑源图;
|
||||
- 外部官方资料链接;
|
||||
- 评分公式、Gate 定义、阶段计划与手工验收清单。
|
||||
|
||||
缺失的是:
|
||||
|
||||
- 可安装仓库与固定 Python 环境;
|
||||
- 可运行本地回测和确定性 fixture;
|
||||
- 聚宽/QMT/Qlib 平台入口;
|
||||
- 自动化测试、schema 验证、run manifest;
|
||||
- 数据质量、PIT、walk-forward、风险、成本和 TCA 报告;
|
||||
- 连续模拟、QMT 影子盘、故障演练和券商确认。
|
||||
|
||||
因此原实现证据只能落在“文档/原型前期”,不能用文章中的目标分 66 回填。
|
||||
|
||||
## 6. Quant OS 当前实现的正确能力边界
|
||||
|
||||
当前已经不只是目录骨架,以下链路可运行、可测试、可扩展:
|
||||
|
||||
- 本地 deterministic event backtest、ledger hash chain、manifest verifier;
|
||||
- A 股 canonical symbol、T+1 可卖量、百股单位、费用、停牌/涨跌停、
|
||||
部分成交和未成交撤销;
|
||||
- PIT table、Universe 状态/原因码、透明特征、train-only 预处理、
|
||||
purge/embargo walk-forward、deterministic Ridge、IC/RankIC;
|
||||
- 日期化费用、impact/capacity、因子风险、约束 target 与失败诊断;
|
||||
- JQData adapter 使用 `get_bars` 获取 raw OHLCV/money、factor、
|
||||
`pre_close`、`high_limit`、`low_limit`、`paused`,使用 `get_extras`
|
||||
获取 PIT `is_st`,并逐交易日获取历史指数成员;
|
||||
- canonical snapshot 采用 incomplete marker + exact artifact hash,
|
||||
verifier 会重建领域对象、重算质量汇总和 `data_version`;
|
||||
- verified snapshot 可直接进入历史 `snapshot-backtest` 或单日
|
||||
`snapshot-decision`,后者可接完整 canonical broker snapshot 并
|
||||
fail closed;
|
||||
- 聚宽/QMT 单文件 bundle、fake harness 与 mock parity exporter;
|
||||
- Qlib 0.9.7 native momentum CLI,以及 Alpha158/LightGBM/Recorder CLI;
|
||||
- QMT/XtTrader 严格只读 shadow CLI:账户 HMAC、broker observation、
|
||||
T 日 Signal 与 T+1 broker fact 绑定、完整 artifact verifier;
|
||||
- Colab 默认无账号流程,以及显式可选的 JQData/Qlib cell。
|
||||
|
||||
最近一次 211-test suite 和两条 Qlib fixture smoke 证明上述代码路径能执行,
|
||||
但仍明确不证明:
|
||||
|
||||
- synthetic 数据或两股票 Qlib fixture 的收益具有投资价值;
|
||||
- 当前真实 JQData 账户的数据许可、PIT、质量与保存策略已验收;
|
||||
- 基本面公告、完整公司行动、Security Master 和退市链已生产化;
|
||||
- Ridge 或 LightGBM 已冻结为四引擎共同部署模型;
|
||||
- 聚宽与本地已在真实长样本上对齐;
|
||||
- QMT 客户端、`xtquant`、数据/账户权限或真实订单回调已经可用;
|
||||
- QMT 历史 ST 正例、官方 query API 的失败/空列表合同已在真实账号验证;
|
||||
- OMS 已达到断线恢复、未知单、持续对账和 20 日影子要求;
|
||||
- 程序化交易报告已经完成。
|
||||
|
||||
## 7. 平台事实应分开写
|
||||
|
||||
截至本次复评所依据的官方文档和本地运行记录:
|
||||
|
||||
- QMT 内置策略环境仍说明为 Python 3.6;它适合运行兼容的薄策略文件,不应直接加载要求 Python ≥3.10 的完整 `quant60` 包;
|
||||
- XtQuant 原生 Python 文档列出 3.6—3.12 的库,并要求运行前启动 MiniQMT;实际可用版本取决于券商分发;
|
||||
- qmttools 的 `run_strategy_file` 是从原生 Python 驱动策略回测/运行的路径,应与 XtTrader 的查询、报单、撤单和推送生命周期分开;
|
||||
- `pyqlib==0.9.7` 已有 CPython 3.12 的主流平台 wheel;本项目已经在该组合
|
||||
实际跑通 native momentum fixture(24 signals)和
|
||||
Alpha158/LightGBM/Recorder fixture;
|
||||
- Alpha158 runner 使用 `os.environ.setdefault` 自动确认
|
||||
`MLFLOW_ALLOW_FILE_STORE=true`,以兼容本地 MLflow file store;
|
||||
该确认只影响本地 tracking backend,不构成数据许可或模型有效性证明。
|
||||
|
||||
来源:[QMT 内置 Python 快速开始](https://dict.thinktrader.net/innerApi/start_now.html)、[XtQuant 原生 Python 快速开始](https://dict.thinktrader.net/nativeApi/start_now.html)、[原生 Python/qmttools 策略回测](https://dict.thinktrader.net/videos/touyan/ty_native_python.html)、[pyqlib 0.9.7 包与 wheel](https://pypi.org/project/pyqlib/)。
|
||||
|
||||
Qlib 的运行状态现在可以写成“固定运行时已通过 fixture smoke”,不能写成
|
||||
“真实 A 股研究已验收”或“与 portable target/order 一致”。两股票 synthetic
|
||||
fixture 的 model/portfolio 指标没有投资意义;真实 provider、冻结 OOS 和
|
||||
版本化 Recorder artifact 仍要单独补证。
|
||||
|
||||
对应的最小验证入口:
|
||||
|
||||
```bash
|
||||
python3.12 -m venv .venv-qlib312
|
||||
source .venv-qlib312/bin/activate
|
||||
python -m pip install -r requirements/research-py312.txt
|
||||
python tools/build_qlib_tiny_fixture.py artifacts/qlib-fixture --days 80
|
||||
PYTHONPATH=src:. python -m platforms.qlib_runner \
|
||||
--provider-uri artifacts/qlib-fixture \
|
||||
--market csi300 --benchmark SH000300 \
|
||||
--start 2024-02-01 --end 2024-04-19 \
|
||||
--lookback 20 --topk 1 --n-drop 1 --rebalance weekly \
|
||||
--output-json artifacts/qlib-native/result.json
|
||||
```
|
||||
|
||||
真实 JQData 验证则必须由用户授权登录:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src:. python tools/jqdata_snapshot.py \
|
||||
--index 000905.XSHG --start 2024-01-02 --end 2024-12-31 \
|
||||
--output data/snapshots/csi500-2024
|
||||
PYTHONPATH=src:. python -c \
|
||||
"from quant60.data_snapshot import verify_data_snapshot; verify_data_snapshot('data/snapshots/csi500-2024/manifest.json')"
|
||||
PYTHONPATH=src:. python -m quant60 snapshot-backtest \
|
||||
--snapshot data/snapshots/csi500-2024/manifest.json \
|
||||
--config configs/baseline.json --output artifacts/csi500-2024-backtest
|
||||
```
|
||||
|
||||
## 8. 证据更新纪律
|
||||
|
||||
更新 [`gate_scorecard.json`](../gate_scorecard.json) 时必须遵守:
|
||||
|
||||
1. 先保存不可变证据,再改状态;
|
||||
2. 每条 evidence 至少包含路径、生成命令、时间、代码版本、配置 hash 和数据版本;
|
||||
3. `mock`、合成 fixture 和单元测试可证明代码语义,不能证明真实数据、券商或合规;
|
||||
4. Gate 只有 `passed` 与 `not_passed` 两种对外结论;“完成 80%”仍是未通过;
|
||||
5. G9 需要真实跨引擎产物,G6/G8 需要券商认证环境或脱敏真实回调,G10 只能由实际券商材料证明;
|
||||
6. 任何代码变更使旧证据超出适用版本时,必须重新降为 `not_passed`;
|
||||
7. 总分达到 60 但任一 Gate 未通过,系统仍必须标记 `NOT_BASELINE_60`。
|
||||
|
||||
## 9. 下一条最短路径
|
||||
|
||||
按错误成本排序,而不是按模型新颖度排序:
|
||||
|
||||
1. 用户授权登录 JQData,生成不可变真实 snapshot,保存许可/lineage,并通过
|
||||
semantic verifier、`snapshot-backtest` 和 `snapshot-decision`;
|
||||
2. 基于已完成的聚宽 hosted smoke,冻结一个小型 canonical 平台输入并导出
|
||||
close arrays/hash、plan、orders/fills;
|
||||
3. 用本地与聚宽对相同输入逐层比较 L1—L4,而不是先比较净值;mock parity
|
||||
只作为回归辅助;
|
||||
4. 把基本面公告 available-time、完整公司行动/Security Master 加入真实
|
||||
PIT data contract;
|
||||
5. 在授权真实 provider 上运行 Qlib OOS,并把 Ridge/LightGBM 中选定的候选
|
||||
冻结成 versioned model bundle;现有 synthetic Recorder 不能承担这一步;
|
||||
6. 取得实际券商 QMT client、`xtquant`、数据与账户权限,分别验证 built-in、
|
||||
qmttools 与 XtTrader;
|
||||
7. 完成 60 个交易日模拟、20 个交易日 QMT shadow、故障演练、连续零未知账差;
|
||||
8. 由实际券商确认程序化交易报告、接口权限、频率和软件要求,再讨论小资金
|
||||
canary。
|
||||
|
||||
在第 7、8 步完成前,正确表述是“可执行、可继续填证据的 Quant OS 生产候选
|
||||
框架”,不是“已达到机构级 60 分”。
|
||||
@@ -0,0 +1,252 @@
|
||||
# Quant OS cross-engine consistency contract
|
||||
|
||||
“本地、聚宽、QMT、Qlib 都能跑”不等于四条净值曲线必须逐点相同。跨引擎
|
||||
一致性按层比较:相同信息集应产生相同计算;平台特有的日历、价格语义和成交
|
||||
差异必须被记录、归因和限制。
|
||||
|
||||
## 1. Comparison levels
|
||||
|
||||
| Level | Compared artifact | Same canonical input required | Pass rule |
|
||||
| --- | --- | --- | --- |
|
||||
| L0 | Source/config manifest | Git state、portable-core hash、strategy/model version、symbol map | Exact |
|
||||
| L1 | Data/universe | `as_of`、sessions、symbols、PIT membership、raw/factor/declared adjusted prices、tradability | Exact values or explicit provider reason |
|
||||
| L2 | Signal | symbol、horizon、lookback/skip、score、model bundle | Exact symbol set;numeric tolerance below |
|
||||
| L3 | Target | target weight/quantity、frozen/sellable state | weight tolerance;exact lot quantity |
|
||||
| L4 | Order intent | ID、side、quantity、limit、type、TIF、timing、reason | Identical broker snapshot/rules 时 exact |
|
||||
| L5 | Order/fill/portfolio | status、fills、fees、cash、positions | Semantic invariants;相同 fill fixture 才要求 exact |
|
||||
| L6 | Performance | return、turnover、drawdown、cost | Diagnostic;不能代替 L1—L5 |
|
||||
|
||||
只比较 L6 不会通过 G9。Alpha158/LightGBM 与 portable momentum 是不同 model
|
||||
spec,本来就不是 L2 peer;可做研究比较,不能冒充同策略 parity。
|
||||
|
||||
## 2. Canonical snapshot is the L1 handoff
|
||||
|
||||
JQData ingestion 通过官方 `get_bars` 保存:
|
||||
|
||||
- raw `open/high/low/close/volume/money`;
|
||||
- `factor`、`pre_close`、`high_limit`、`low_limit`、`paused`;
|
||||
- 每个 member-date 的 PIT `is_st`;
|
||||
- 每个交易日的历史指数成员。
|
||||
|
||||
快照必须保持 `adjustment=none`,front-adjusted feature history 在每个
|
||||
decision `as_of` 时由当时已保存的 raw close + factor 构造。这样执行价仍是
|
||||
raw,且后来的 factor 不能改写旧决策。
|
||||
|
||||
L1 verifier 不只比文件 hash,还要:
|
||||
|
||||
1. 拒绝 incomplete marker;
|
||||
2. 要求目录是 manifest 声明的精确 artifact 集;
|
||||
3. 重建每个 bar/membership 领域对象;
|
||||
4. 重算质量统计、内容 hash 与 `data_version`;
|
||||
5. 拒绝重复键、非法 OHLC、停牌非零量、非法限价、缺失 factor 或非布尔/
|
||||
缺失 `is_st`;
|
||||
6. 拒绝 retrieval 当日仍未在 Asia/Shanghai 24:00 完成的日线。
|
||||
|
||||
验证入口:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src:. python -c \
|
||||
"from quant60.data_snapshot import verify_data_snapshot; verify_data_snapshot('data/snapshots/csi500-2024/manifest.json')"
|
||||
```
|
||||
|
||||
`snapshot-backtest` 和 `snapshot-decision` 都先通过该 verifier。它们能证明
|
||||
同一个 snapshot 的本地可重放性,但在真实授权 JQData run 和平台导出前,
|
||||
不能证明 provider entitlement 或 G9。
|
||||
|
||||
## 3. Required run manifest
|
||||
|
||||
每个 comparison 至少保存:
|
||||
|
||||
```json
|
||||
{
|
||||
"run_id": "unique-id",
|
||||
"engine": "local|joinquant|qmt_builtin|qmttools|xttrader|qlib",
|
||||
"mode": "fixture|provider_snapshot|backtest|simulation|shadow|live",
|
||||
"git_commit": "commit-or-DIRTY",
|
||||
"portable_core_sha256": "sha256",
|
||||
"strategy_or_model_version": "immutable-id",
|
||||
"python_version": "major.minor.patch",
|
||||
"platform_version": "value-or-unknown",
|
||||
"config_hash": "sha256",
|
||||
"data_version": "immutable-id",
|
||||
"rules_version": "immutable-id",
|
||||
"timezone": "Asia/Shanghai",
|
||||
"signal_as_of": "ISO-8601 timestamp",
|
||||
"last_feature_bar": "ISO-8601 date-or-time",
|
||||
"first_executable_time": "ISO-8601 timestamp",
|
||||
"price_adjustment": "raw|pre|post|front_ratio|PIT_FRONT_FROM_RAW_AND_FACTOR",
|
||||
"fill_model": "declared-name",
|
||||
"evidence_class": "fake|synthetic|provider-snapshot|real-platform|broker"
|
||||
}
|
||||
```
|
||||
|
||||
unknown platform version 可用于 smoke,但阻止 release certification。
|
||||
|
||||
本地 execution/provider snapshot run 保存后执行:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src:. python -m quant60 verify-manifest \
|
||||
artifacts/<run-id>/manifest.json
|
||||
```
|
||||
|
||||
它检查 incomplete marker、精确 artifact set/hash、ledger chain/head、
|
||||
report/manifest identity、saved/current source/schema aggregate 和 payload
|
||||
schema。snapshot decision 使用:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src:. python -m quant60 verify-snapshot-decision \
|
||||
artifacts/<decision-id>/manifest.json
|
||||
```
|
||||
|
||||
## 4. Numeric and semantic tolerances
|
||||
|
||||
对传入 `portable_core.py` 的同一固定 close arrays:
|
||||
|
||||
| Field | Tolerance |
|
||||
| --- | --- |
|
||||
| canonical symbol、rank、selected set | Exact |
|
||||
| momentum score | absolute error ≤ `1e-12` |
|
||||
| target weight | absolute error ≤ `1e-10` |
|
||||
| target quantity | Exact integer |
|
||||
| order delta | Exact signed integer |
|
||||
|
||||
真实 provider 数据先比较输入数组。不同复权约定、停牌填充、成分股日期或
|
||||
feature cutoff 导致的 score 差异是 L1 failure,不是浮点噪声。
|
||||
|
||||
本地货币 ledger 按配置的 currency quantum 比较。hosted NAV 只有在 bars、
|
||||
company actions、fees 和 fill events 都相同时才要求相同;否则必须分类:
|
||||
|
||||
- `input-price difference`;
|
||||
- `timing difference`;
|
||||
- `tradability/fill difference`;
|
||||
- `explicit-fee difference`;
|
||||
- `residual unexplained difference`。
|
||||
|
||||
residual 必须为零或低于 release-specific bound,不能静默并入 slippage。
|
||||
|
||||
## 5. Clock alignment
|
||||
|
||||
canonical weekly clock 是 ISO 周第一实际交易日完整 close,紧接着下一实际
|
||||
交易日 open。它不是固定星期几;单交易日长假周会自然跨到下一 ISO 周。
|
||||
|
||||
comparison key 必须包含:
|
||||
|
||||
```text
|
||||
(signal_as_of, last_feature_bar, first_executable_time, adjustment_mode)
|
||||
```
|
||||
|
||||
任一元素不同就不是 strict peer,只能做诊断 comparison。
|
||||
|
||||
本地 snapshot backtest 使用:
|
||||
|
||||
- exact daily PIT membership;
|
||||
- decision date raw close + factor 构造 point-in-time front-adjusted signal;
|
||||
- next session raw open 执行;
|
||||
- provider daily pause/limit/pre-close;
|
||||
- provider daily PIT `is_st`:ST 不新买,已持有 ST 只卖;
|
||||
- prior-session volume capacity。
|
||||
|
||||
JoinQuant/QMT 必须导出相同输入或其 hash 才能进入 L2—L4 strict comparison。
|
||||
|
||||
## 6. Platform interpretation and current facts
|
||||
|
||||
- **Local**:固定 fixture 的 deterministic contract oracle,不自动等于市场
|
||||
真相。
|
||||
- **JoinQuant**:以前一交易日查询 PIT index/ST,以批量 `history` 读取完成
|
||||
日线,并显式设置费用、滑点和 10% 参与率;必须导出实际 close
|
||||
arrays/hash、plan、orders/fills 和平台配置。本地 fake harness 只证明
|
||||
wiring。2026-07-26 已完成一次 2024 全年真实 hosted smoke,运行日志无
|
||||
ERROR;但尚未导出上述相同输入与分层结果,所以它是 runtime evidence,
|
||||
不是 strict peer/G9 证据。
|
||||
- **QMT built-in / qmttools**:共享 bundle 但生命周期不同,均硬
|
||||
backtest-only;固定中证 500 benchmark,以历史 timetag 查询 PIT 成分/ST。
|
||||
built-in 的 10% 最大成交量占比需要 QMT UI 设置并取证,qmttools
|
||||
程序化传入。真实 QMT 环境尚未运行。qmttools 把 transfer fee 折入
|
||||
commission,minimum commission/fill 行为是声明差异。
|
||||
- **XtTrader**:比较 broker snapshot、order intent 与 normalized callback。
|
||||
当前已有只读 HMAC 账户绑定、broker observation/snapshot 和 exact
|
||||
shadow-plan verifier,但只有 fake broker contract,没有真实 shadow。
|
||||
- **Qlib momentum**:`pyqlib==0.9.7` 的 native fixture 已真实运行,产生
|
||||
24 条 signal;结果保存 signal/report hash、表边界和从 report 重算的
|
||||
portfolio 指标。它证明 runtime/path 可执行,不证明真实市场或 L3/L4。
|
||||
- **Qlib Alpha158/LightGBM**:fixture 上已真实完成 model + Recorder。
|
||||
runner 自动以 `setdefault` 设置 `MLFLOW_ALLOW_FILE_STORE=true` 以兼容本地
|
||||
MLflow file store,并读取 portfolio report 保存 hash、边界和重算指标。
|
||||
两股票 synthetic 性能没有投资意义,且该模型不是 portable momentum 的
|
||||
parity peer。
|
||||
- **Mock parity exporter**:当前能逐层比较 JoinQuant/QMT fake wrapper 的
|
||||
score、weight、quantity、delta,并校验 source hash。它明确是
|
||||
`mock_contract_only`、`real_platform_pass=false`、`gate_credit=[]`。
|
||||
|
||||
## 7. Difference reason codes
|
||||
|
||||
必须使用枚举 reason code,不能只写“平台差异”:
|
||||
|
||||
```text
|
||||
CALENDAR
|
||||
SYMBOL_MAP
|
||||
UNIVERSE
|
||||
MISSING_BAR
|
||||
SUSPENSION_FILL
|
||||
PRICE_ADJUSTMENT
|
||||
AS_OF_CLOCK
|
||||
ROUNDING
|
||||
FEE_SCHEDULE
|
||||
PRICE_LIMIT
|
||||
T_PLUS_ONE
|
||||
VOLUME_LIMIT
|
||||
FILL_MODEL
|
||||
BROKER_STATE
|
||||
FLOAT_TOLERANCE
|
||||
UNEXPLAINED
|
||||
```
|
||||
|
||||
symbol set、signal、target、order intent、cash 或 position 出现任何
|
||||
`UNEXPLAINED` 都阻止 release。
|
||||
|
||||
## 8. Runnable comparison support
|
||||
|
||||
mock-only exporter:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src:. python tools/export_mock_parity.py \
|
||||
export --output artifacts/mock-parity/report.json
|
||||
PYTHONPATH=src:. python tools/export_mock_parity.py \
|
||||
verify artifacts/mock-parity/report.json
|
||||
```
|
||||
|
||||
Qlib native momentum fixture:
|
||||
|
||||
```bash
|
||||
python3.12 -m venv .venv-qlib312
|
||||
source .venv-qlib312/bin/activate
|
||||
python -m pip install -r requirements/research-py312.txt
|
||||
python tools/build_qlib_tiny_fixture.py artifacts/qlib-fixture --days 80
|
||||
PYTHONPATH=src:. python -m platforms.qlib_runner \
|
||||
--provider-uri artifacts/qlib-fixture \
|
||||
--market csi300 --benchmark SH000300 \
|
||||
--start 2024-02-01 --end 2024-04-19 \
|
||||
--lookback 20 --topk 1 --n-drop 1 --rebalance weekly \
|
||||
--output-json artifacts/qlib-native/result.json
|
||||
```
|
||||
|
||||
两者都不是 G9 的真实平台证据。
|
||||
|
||||
## 9. What counts toward G9
|
||||
|
||||
| Evidence | Counts toward G9? |
|
||||
| --- | --- |
|
||||
| symbol/unit tests、fake JoinQuant/QMT harness | Supporting only |
|
||||
| mock parity exporter | No;contract regression only |
|
||||
| local snapshot twice with same hash | Supporting G7/L1 only |
|
||||
| Qlib 24-signal synthetic fixture smoke | Runtime evidence only |
|
||||
| Qlib Alpha158 synthetic Recorder smoke | Research runtime evidence only |
|
||||
| real JoinQuant export vs local canonical run | Yes,覆盖的 layers/dates |
|
||||
| licensed qmttools run with saved version/result | Yes,覆盖的 layers |
|
||||
| XtTrader shadow using real broker snapshot | Yes,pre-trade/order semantics |
|
||||
| ≥20 trading days QMT shadow, zero unexplained differences | 文章 G9 必需 |
|
||||
|
||||
真实 JoinQuant smoke 已运行;QMT 和 broker shadow 尚未运行,而且
|
||||
JoinQuant 仍缺同输入导出与 local peer,所以 G9 继续为 `not_passed`。
|
||||
状态权威是
|
||||
[`gate_scorecard.json`](../gate_scorecard.json)。
|
||||
@@ -0,0 +1,73 @@
|
||||
# JoinQuant hosted backtest evidence — 2026-07-26
|
||||
|
||||
This is a real hosted-runtime smoke record, not a cross-engine acceptance
|
||||
report and not an investment-performance claim.
|
||||
|
||||
## Run identity
|
||||
|
||||
- Strategy: `quant_os_portable_momentum_v1`
|
||||
- Hosted record:
|
||||
[JoinQuant backtest detail](https://www.joinquant.com/algorithm/backtest/detail?backtestId=62de09f1e0f9e81b260a18e0ee59e953)
|
||||
- Period: 2024-01-02 through 2024-12-31
|
||||
- Initial capital: CNY 1,000,000
|
||||
- Frequency/runtime: daily, Python 3
|
||||
- Benchmark: CSI 500 (`000905.XSHG`)
|
||||
- Uploaded bundle:
|
||||
`dist/joinquant_strategy.py`
|
||||
- Uploaded bundle SHA-256:
|
||||
`22ddb0546beb3bd4e4bbedecb271452111324c3903e45be1f4ac3d39f38cce4f`
|
||||
- Portable core SHA-256:
|
||||
`af29e4e5e10705cf6aff89874394c1e80d3780f093c19d90ed53ef9d0188a934`
|
||||
|
||||
## Hosted result
|
||||
|
||||
| Metric | Hosted value |
|
||||
| --- | ---: |
|
||||
| Strategy return | -19.98% |
|
||||
| Annualized return | -20.56% |
|
||||
| Excess return | -24.12% |
|
||||
| Benchmark return | 5.46% |
|
||||
| Alpha | -0.259 |
|
||||
| Beta | 0.830 |
|
||||
| Sharpe | -0.806 |
|
||||
| Win rate | 0.474 |
|
||||
| Profit/loss ratio | 0.816 |
|
||||
| Maximum drawdown | 32.45% |
|
||||
|
||||
The visible completed-run log contained zero `ERROR`, `Traceback`, or
|
||||
`订单委托失败` entries. These performance numbers are negative and are recorded
|
||||
only to prove that the hosted execution path completed; they provide no
|
||||
investment-value evidence.
|
||||
|
||||
## Defects found by the hosted runtime
|
||||
|
||||
The real platform run found three issues that fake wiring alone did not expose:
|
||||
|
||||
1. JoinQuant's hosted namespace shadowed Python's global `sum`. The portable
|
||||
core now uses its own deterministic numeric reducer.
|
||||
2. STAR Market market orders require worst-price protection. The wrapper now
|
||||
submits a documented `LimitOrderStyle`: daily upper limit for buys and daily
|
||||
lower limit for sells, and fails closed when that price is absent or invalid.
|
||||
3. STAR Market auction orders require at least 200 shares, except a complete
|
||||
sale of the remaining sub-200 balance. The rule now lives in the shared
|
||||
portable core and local simulator, so JoinQuant and QMT receive the same
|
||||
legal target/order delta.
|
||||
|
||||
The order API and limit-style contract are documented in the
|
||||
[official JoinQuant API PDF](https://cdn.joinquant.com/help/img/JoinQuantAPI.pdf).
|
||||
The 200-share minimum and remaining-balance exception are described by the
|
||||
[Shanghai Stock Exchange](https://edu.sse.com.cn/tib/).
|
||||
|
||||
## Evidence boundary
|
||||
|
||||
This record proves that one real JoinQuant daily backtest completed with the
|
||||
uploaded wrapper. It does **not** pass G9 because the following evidence is
|
||||
still missing:
|
||||
|
||||
- a complete hosted export containing input close arrays or hashes, the
|
||||
portable plan, orders and fills;
|
||||
- a local canonical run over the exact same frozen inputs;
|
||||
- layer-by-layer L1—L4 comparison with enumerated difference reasons;
|
||||
- a real QMT peer run and at least 20 trading days of broker shadow evidence.
|
||||
|
||||
Accordingly, `gate_scorecard.json` remains `NOT_BASELINE_60`.
|
||||
@@ -0,0 +1,116 @@
|
||||
# Quant OS platform capability matrix
|
||||
|
||||
“有入口”与“已在目标平台验证”必须分开。Quant OS 共享的是冻结计算合同,
|
||||
不是四个平台完全相同的时钟、行情和成交模型。
|
||||
|
||||
| Path | Intended use | Runtime / prerequisite | Current verified fact | Missing release evidence |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Local synthetic execution | 确定性事件回测、ledger/replay | Python ≥3.10,无账号 | 标准库套件最近记录为 211 tests、OK、3 skip;smoke + exact manifest verifier 可运行 | synthetic 不代表真实市场/收益 |
|
||||
| Local synthetic research | PIT/features/walk-forward/Ridge/risk/cost/target | Python ≥3.10,无账号 | research smoke + manifest verifier 可运行 | Ridge 未冻结部署,未做授权长样本 OOS |
|
||||
| JQData ingestion | 授权数据到 canonical immutable snapshot | `jqdatasdk==1.9.8` + 授权账号 | fake-provider 测试覆盖 raw/factor/pre-close/limits/paused/PIT `is_st`/membership、24:00 完整收盘约束和语义 verifier | 尚未登录真实账号保存快照、许可与 lineage |
|
||||
| Snapshot local backtest | PIT membership 的 provider-data 本地回测 | semantic verifier 通过的 snapshot | `snapshot-backtest` 复用 production decision path,输出普通 run manifest | 尚无授权真实 snapshot;仍是本地 fill model |
|
||||
| Snapshot decision | 某决策日 Signal/Target/Order Delta | snapshot + equity 或完整 broker snapshot | fail-closed broker state 与 exact decision manifest verifier 已实现 | 未接真实账户 snapshot,未冻结生产模型 |
|
||||
| Colab | clone、测试、bundle、本地两条 synthetic 链;可选 JQData/Qlib | Colab runtime | notebook 已可本地逐 cell 执行 | 可选账号/依赖 cell 仍需运行时授权;不是平台证据 |
|
||||
| JoinQuant local harness | wrapper API 合同 | Python ≥3.10,无账号 | fake lifecycle 与 mock parity 可运行 | 不证明 JoinQuant |
|
||||
| JoinQuant hosted bundle | hosted backtest | JoinQuant 登录/数据权限 | 真实 2024 全年 run 已完成且可见日志 0 ERROR;单文件、PIT index/ST、批量 history、费率/滑点/10% 参与率、科创板保护价/200 股约束已运行 | 尚无完整输入/plan/orders/fills 导出和同输入本地比较 |
|
||||
| QMT local harness | built-in wrapper 合同 | Python ≥3.10,无账号 | Python 3.6 source、`ContextInfo` 回滚模拟和 mock parity | 不证明 QMT |
|
||||
| QMT built-in bundle | GUI backtest-only | 授权 QMT 客户端/板块与历史 ST 数据 | bundle 硬限制 backtest;毫秒 timetag PIT 成分/ST;固定中证 500、费率/滑点;模块全局 `g` | 尚无真实 QMT run/export;10% GUI 配置与历史 ST 正例探针待取证 |
|
||||
| qmttools runner | native-Python QMT backtest/history | 券商分发 `xtquant` + 已登录 terminal | 固定中证 500/10% 参与率、参数、只读 preflight 和 hard backtest/history 合同已测 | 尚无专有运行时实跑 |
|
||||
| XtTrader read-only shadow | 账户绑定 target-diff 与 broker observation | MiniQMT/QMT、账户查询权限、既有本地 HMAC key | HMAC 账户绑定 + authenticated evidence envelope、decision/observation semantic replay、资产/持仓/委托/成交恒等式、fail-closed exact verifier 与 fake broker 合同 | HMAC 不是 broker attestation;仍缺官方 query 失败/空结果合同、callback/restart、20 日真实 shadow;not live-ready |
|
||||
| Qlib native momentum | signal/model research | CPython 3.12 + exactly `pyqlib==0.9.7` | 真实本地 fixture 成功,24 signal;保存 signal/report hash、表边界和重算 portfolio 指标 | synthetic 两股票;无真实数据/OOS,无 L3/L4 parity |
|
||||
| Qlib Alpha158/LightGBM | model fit + Recorder workflow | 同上 + LightGBM/MLflow stack | 真实 fixture 完成 model/Recorder;读取 portfolio report,保存表 hash、边界、重算指标与 artifact path | synthetic 两股票性能无意义;真实 provider/OOS 和冻结模型缺失 |
|
||||
| Mock parity exporter | JoinQuant/QMT wrapper 的 L2—L4 合同回归 | Python ≥3.10 | `mock_contract_only`、`real_platform_pass=false`、`gate_credit=[]` | 不计 G9;必须换成真实平台导出 |
|
||||
|
||||
G1—G10 当前都未通过。JoinQuant hosted smoke 与 Qlib fixture smoke 是真实
|
||||
runtime 证据,但不是市场有效性或跨平台 Gate 通过证据。
|
||||
|
||||
## Stable strategy boundary
|
||||
|
||||
当前四引擎共同可冻结的是 `portable-momentum-v1`:
|
||||
|
||||
- canonical symbol normalization;
|
||||
- momentum score/rank;
|
||||
- capped target weights;
|
||||
- lot-rounded target quantity;
|
||||
- T+1/sellable-aware order delta。
|
||||
- 科创板 200 股最小申报、余额一次性卖清与 hosted 最坏价保护。
|
||||
|
||||
本地 Ridge 与 Qlib Alpha158/LightGBM 是研究候选。没有 versioned model
|
||||
bundle、授权真实 OOS 和跨引擎推理结果前,不能称为已部署 champion。
|
||||
|
||||
Qlib 的单一 `limit_threshold` 是市场级近似,不能表达逐日板块/ST 限制;
|
||||
因此它只参加 L1/L2 和诊断 L6。XtTrader mutation 边界目前只接受 `.SH`
|
||||
和 `.SZ`,北交所 symbol conversion 覆盖不等于北交所实盘覆盖。
|
||||
|
||||
## Platform terms
|
||||
|
||||
- **QMT built-in**:`init` / `handlebar` 在 QMT 管理的 Python 3.6 环境执行。
|
||||
用户状态放在模块全局 `g`,避免 `ContextInfo` 用户属性在下个
|
||||
`handlebar` 回滚。
|
||||
- **qmttools**:native Python 通过 `run_strategy_file` 驱动策略文件。
|
||||
supplied runner 固定 backtest/history,不能等同于 XtTrader OMS。
|
||||
- **XtTrader**:连接 MiniQMT 的查询、报单/撤单与异步推送 API。存在 guarded
|
||||
mutation path 不代表券商认证或 live-ready;本项目对 operator 暴露的
|
||||
shadow CLI 严格只读,没有报单/撤单命令。
|
||||
- **fake harness**:函数名和生命周期匹配的本地对象,只用于合同回归。
|
||||
- **Qlib Recorder**:研究 artifact 记录机制。两股票 synthetic Recorder
|
||||
成功不等于模型有投资价值。
|
||||
|
||||
## Minimum verification commands
|
||||
|
||||
从 `quant-os` 项目根目录运行:
|
||||
|
||||
```bash
|
||||
# 核心和 Colab 默认流程
|
||||
make local
|
||||
|
||||
# JQData 快照与 semantic verifier(会交互式无回显读取密码)
|
||||
PYTHONPATH=src:. python tools/jqdata_snapshot.py \
|
||||
--index 000905.XSHG --start 2024-01-02 --end 2024-12-31 \
|
||||
--output data/snapshots/csi500-2024
|
||||
PYTHONPATH=src:. python -c \
|
||||
"from quant60.data_snapshot import verify_data_snapshot; verify_data_snapshot('data/snapshots/csi500-2024/manifest.json')"
|
||||
|
||||
# 快照回测和决策
|
||||
PYTHONPATH=src:. python -m quant60 snapshot-backtest \
|
||||
--snapshot data/snapshots/csi500-2024/manifest.json \
|
||||
--config configs/baseline.json --output artifacts/csi500-2024-backtest
|
||||
PYTHONPATH=src:. python -m quant60 snapshot-decision \
|
||||
--snapshot data/snapshots/csi500-2024/manifest.json \
|
||||
--config configs/baseline.json --as-of 2024-12-31 \
|
||||
--equity 1000000 --output artifacts/csi500-2024-decision
|
||||
|
||||
# hosted bundle 和 mock-only parity
|
||||
python tools/bundle_platforms.py
|
||||
PYTHONPATH=src:. python tools/export_mock_parity.py \
|
||||
export --output artifacts/mock-parity/report.json
|
||||
PYTHONPATH=src:. python tools/export_mock_parity.py \
|
||||
verify artifacts/mock-parity/report.json
|
||||
|
||||
# Colab notebook 本地合同/执行
|
||||
python tools/run_colab_notebook.py notebooks/quant_os_colab.ipynb
|
||||
python tools/run_colab_notebook.py notebooks/quant_os_colab.ipynb --execute
|
||||
|
||||
# QMT 环境就绪后:先运行未绑定账户的只读 bootstrap(预期 exit 2),再用
|
||||
# 输出的非 null broker_snapshot.json 重建同一 Signal 日 decision;
|
||||
# broker observation 本身仍来自唯一下一交易日盘前窗口。完整步骤见 runbook
|
||||
PYTHONPATH=src:. python tools/qmt_shadow_plan.py plan \
|
||||
--decision artifacts/latest-decision/manifest.json \
|
||||
--output artifacts/qmt-shadow-bootstrap
|
||||
```
|
||||
|
||||
后续 `verify` 必须同时提供原始 decision,并读取 plan 时使用的既有
|
||||
`QMT_ACCOUNT_HASH_KEY_FILE`;verify 不会补建丢失 key。manifest HMAC
|
||||
envelope 绑定 plan/observation/snapshot 的内容与发布 byte hash、
|
||||
decision/source(含 operator CLI)/policy;四个 JSON 必须保持唯一 writer
|
||||
encoding。但信任主体是本地 Quant OS key holder,不是 QMT/券商。
|
||||
|
||||
Qlib 和真实平台的完整命令见
|
||||
[`runbooks/PLATFORM_DEPLOYMENT.md`](../runbooks/PLATFORM_DEPLOYMENT.md)。
|
||||
|
||||
## Version and evidence policy
|
||||
|
||||
每个真实 run 都要记录 JoinQuant environment、QMT client/build、
|
||||
`xtquant`、broker plugin、Qlib/Python、bundle hash、data version、
|
||||
config/rules hash 和实际日历。文档说明 API 存在不证明当前账号有权限;
|
||||
mock/fake/synthetic 成功不证明真实平台;Qlib synthetic 成功不证明模型收益。
|
||||
@@ -0,0 +1,201 @@
|
||||
# Quant OS data, credential and live-trading safety
|
||||
|
||||
Quant OS 仓库需要能够被 review、clone 和推送,但不能携带可复用凭据、账户
|
||||
身份、受许可限制的数据或券商专有运行时。Obsidian 只保存项目说明,也不能
|
||||
成为密码、cookie 或行情文件的旁路存储。
|
||||
|
||||
## Never commit or copy into documentation
|
||||
|
||||
- JoinQuant/JQData username、password、cookie、token、session export;
|
||||
- QMT/MiniQMT account ID、terminal profile、userdata directory、session
|
||||
file、device fingerprint;
|
||||
- 从持牌 QMT 安装复制出的 `xtquant` binary;
|
||||
- broker statement、raw callback 或含账户/个人信息的截图;
|
||||
- private key、API key、`.env`、subscription URL、带凭据的 clone URL;
|
||||
- provider licence 不允许再分发的 raw/derived market data;
|
||||
- Colab notebook output 中的 secret、完整账户值或授权数据;
|
||||
- MLflow/Recorder artifact 中意外缓存的环境变量、machine path 或身份信息。
|
||||
|
||||
`.gitignore` 不是安全边界。每次提交前必须检查 staged diff 和所有 generated
|
||||
artifacts。
|
||||
|
||||
## Credential injection
|
||||
|
||||
提交到 Git 的配置只能含 placeholder。推荐本地变量:
|
||||
|
||||
```text
|
||||
JQDATA_USERNAME
|
||||
JQDATA_PASSWORD
|
||||
QMT_ACCOUNT_ID
|
||||
QMT_USERDATA_PATH
|
||||
QMT_SESSION_ID
|
||||
QMT_ACCOUNT_HASH_KEY_FILE
|
||||
```
|
||||
|
||||
JQData adapter 优先读取本地环境变量,也支持交互式读取;密码提示无回显。
|
||||
不得把密码作为 CLI 参数,因为 shell history/process list 会泄漏。
|
||||
|
||||
Colab 可选 JQData cell 必须在 runtime 内通过无回显 prompt/Colab secret
|
||||
注入。禁止:
|
||||
|
||||
- 把 secret 写在 notebook source 或共享链接里;
|
||||
- `print(os.environ)`、输出 auth object 或异常中的 credential;
|
||||
- 把带 secret 的 notebook output 下载、同步或提交;
|
||||
- 运行结束后继续复用包含授权数据和 secret 的共享 runtime。
|
||||
|
||||
用完后清除 runtime。Colab secret 只是注入渠道,不授予数据再分发权。
|
||||
|
||||
QMT 账号不应作为 CLI 参数。`.env.example` 只列变量名和安全默认值;
|
||||
真实 `.env` 必须保留在 operator-controlled local secret store。
|
||||
|
||||
不得在 `--help`、exception、run manifest、test snapshot 或 OB 文档打印上述
|
||||
值。低熵账户号的普通 SHA-256 可枚举恢复;对外证据应使用 keyed one-way
|
||||
identifier,并把 key 保存在独立 secret store。
|
||||
|
||||
`QMT_ACCOUNT_HASH_KEY_FILE` 只指向本地 HMAC key,不是 key 本身。
|
||||
`qmt_shadow_plan.py plan` 在文件不存在时生成至少 32 byte 的安全随机 key;Unix
|
||||
要求文件 mode 0600,并且不会为了创建 key 而放宽或改写一个已经存在的父目录
|
||||
权限。`verify` 只读取既有 key,绝不会在 key 丢失时静默生成替代品。该 key
|
||||
必须稳定备份和最小权限访问:轮换后账户 hash 会变化,历史 broker snapshot
|
||||
与 decision 会按设计失配,历史 authenticated evidence 也无法再验签。key
|
||||
内容不得进入 Git、OB、notebook、artifact、stdout、异常或聊天。
|
||||
|
||||
shadow manifest 保存的是 `QMT_SHADOW_EVIDENCE_V1` HMAC,不是 secret。
|
||||
它用与账户标识不同的 domain 签署 canonical evidence envelope,覆盖完整
|
||||
plan、broker observation、broker snapshot 的内容 hash 和三份实际发布文件
|
||||
原始 byte SHA-256、原始 decision manifest hash、planner/engine 以及
|
||||
`tools/qmt_shadow_plan.py` operator entrypoint source hash,并绑定固定
|
||||
semantic/policy ID 和阈值。四个发布 JSON(含不自签的 manifest)必须符合
|
||||
唯一 deterministic writer bytes;minify、key 重排和空白变化不是等价发布物。
|
||||
verifier 必须同时拿到原始 decision 与既有 key,并读取磁盘实际 bytes 重建
|
||||
envelope 后用
|
||||
constant-time compare 验证。普通 SHA-256 重新封装、替换 decision、改写
|
||||
observation 或同步修改 plan 派生字段都不能在不知道 key 时伪造该 MAC。
|
||||
|
||||
这个 HMAC 的信任主体是“持有本地 key 的 Quant OS evidence publisher”。
|
||||
它证明发布后没有被无 key 的第三方改写;它**不是** QMT/券商对 API 返回值的
|
||||
签名,不证明终端、账号或 callback 未在采集前被攻陷。key 泄漏后攻击者可以
|
||||
伪造本地 envelope,应立即按 credential incident 轮换、隔离旧证据并重新做
|
||||
可信采集。
|
||||
|
||||
## JQData and provider-data licence
|
||||
|
||||
`jqdatasdk==1.9.8` adapter 可获取 raw OHLCV/money、factor、pre-close、
|
||||
daily limits/paused、PIT `is_st` 和历史指数成员。可获取不等于可再分发。
|
||||
|
||||
首次真实 snapshot 前记录:
|
||||
|
||||
- provider、账户 entitlement 和允许用途;
|
||||
- local/Colab 是否允许持久保存、保存期限;
|
||||
- raw 与 derived data 是否可共享;
|
||||
- API/field semantic version;
|
||||
- query、retrieval time、event/effective/available time;
|
||||
- partition/data hash、retention 和 deletion policy。
|
||||
|
||||
snapshot manifest 不含密码,但 snapshot 本身仍可能是受许可数据。默认放在
|
||||
被 Git 忽略的 local storage,不上传代码仓库、OB、公开 object storage 或
|
||||
公开 Colab drive。
|
||||
|
||||
synthetic fixture 可共享但不是市场证据。真实 JQData snapshot 只有在许可、
|
||||
lineage 和语义 verifier 都完成后,才可能成为 G1 的候选证据。
|
||||
|
||||
## QMT proprietary and licensed boundary
|
||||
|
||||
`xtquant` 由持牌 QMT/MiniQMT 与券商分发。Quant OS:
|
||||
|
||||
- 不 vendoring、不上传、不从非官方 PyPI 模仿包安装;
|
||||
- 仅在 QMT-specific path 内 lazy import;
|
||||
- 没有专有运行时也能跑核心/fake tests;
|
||||
- 只使用实际券商支持的 Python 和 client/plugin 组合。
|
||||
|
||||
QMT 并非只提供用户名密码即可运行。还需要已授权 QMT/MiniQMT client、
|
||||
匹配的 `xtquant`、userdata path、行情/历史数据 entitlement 和登录会话。
|
||||
复制其他用户安装不能建立许可或兼容性。
|
||||
|
||||
平台导出必须先脱敏:raw account、broker order ID、userdata path、device
|
||||
信息和专有异常字符串不进入 Git。
|
||||
|
||||
只读 shadow 的 `broker_observation.json` 只保存 keyed account hash、query
|
||||
安全 envelope 和通过标准化的资产、持仓、委托、成交事实;不保存原始
|
||||
account ID。manifest 通过 authenticated evidence HMAC 将 observation、
|
||||
broker snapshot、plan、decision、source 和 canonical policy 绑定。即便如此,
|
||||
它仍可能包含敏感持仓/交易信息,只能放在被 Git 忽略且访问受控的证据目录。
|
||||
|
||||
## Qlib, MLflow and Colab artifacts
|
||||
|
||||
Qlib 固定为 CPython 3.12 + `pyqlib==0.9.7`。Alpha158 runner 为本地
|
||||
MLflow file store 使用:
|
||||
|
||||
```text
|
||||
MLFLOW_ALLOW_FILE_STORE=true
|
||||
```
|
||||
|
||||
这是对 local backend 的显式兼容确认,不是安全授权,也不会替代访问控制。
|
||||
Recorder 目录可能包含 model、label、prediction、code cache/status 和
|
||||
provider-derived output;提交前必须按 provider licence 与 secret scan
|
||||
检查。真实模型 artifact 应存放在访问受控、可审计的 artifact store。
|
||||
|
||||
不要在公开 Colab runtime 上加载券商文件。JQData/Qlib 可选流程只处理研究
|
||||
数据;QMT/XtTrader 应留在受控且持牌的本地/Windows 环境。
|
||||
|
||||
## Default live posture
|
||||
|
||||
所有 broker-facing 路径默认只能是:
|
||||
|
||||
```text
|
||||
BACKTEST
|
||||
SIMULATION
|
||||
SHADOW
|
||||
```
|
||||
|
||||
QMT built-in 和 qmttools supplied runner 硬限制 backtest/history。XtTrader
|
||||
`allow_live_orders` 默认 false,仓库不提供 live launch command。
|
||||
|
||||
未来任何 live mutation 至少还要求:
|
||||
|
||||
1. broker read-only preflight 成功;
|
||||
2. market data 与完整 broker snapshot 新鲜且带时区;
|
||||
3. account allow-list 匹配;
|
||||
4. 无 unknown open order 或 reconciliation difference;
|
||||
5. notional/order/rate limit 已配置;
|
||||
6. operator approval 与 kill switch 已演练;
|
||||
7. 程序化交易报告和软件/频率要求由实际券商确认;
|
||||
8. shadow、重启恢复和连续日终对账达到 release 条件。
|
||||
|
||||
环境变量本身不构成批准。mock guard、fake broker 和单元测试也不构成券商认证。
|
||||
|
||||
## Safe evidence and redaction
|
||||
|
||||
可安全导出的候选内容:
|
||||
|
||||
- source/config/data/rules/model hash;
|
||||
- canonical symbols 和非受限聚合;
|
||||
- order state/reason code;
|
||||
- keyed account hash;
|
||||
- 在不需要精确值时脱敏/取整的 operational metric。
|
||||
|
||||
需要删除或保护:
|
||||
|
||||
- raw account 和可关联 broker order ID;
|
||||
- 用户 machine path、用户名、device/profile 信息;
|
||||
- proprietary client exception;
|
||||
- notebook cell output 中的 token/credential;
|
||||
- provider licence 不允许公开的数据行。
|
||||
|
||||
审计所需原始版本应留在加密、访问受控的本地/企业存储,而不是为了方便直接
|
||||
提交 Git。
|
||||
|
||||
## Incident response
|
||||
|
||||
如果 credential、账户标识或授权数据进入 Git/OB/Colab output:
|
||||
|
||||
1. 停止新订单和相关自动任务;
|
||||
2. 通过 provider/broker 撤销或轮换 credential;
|
||||
3. 在仓库外保存 incident timeline;
|
||||
4. 从当前树移除,并在明确批准后清理历史和 mirror;
|
||||
5. 检查 CI、artifact、OB sync、Colab/Drive 和 downstream clone;
|
||||
6. 评估数据许可/个人信息泄漏范围并完成必要通知;
|
||||
7. 记录恢复和复发预防。
|
||||
|
||||
删除可见文件不等于 credential rotation。交易与数据故障流程见
|
||||
[`runbooks/INCIDENTS.md`](../runbooks/INCIDENTS.md)。
|
||||
Reference in New Issue
Block a user