feat: add Quant OS A-share baseline

This commit is contained in:
2026-07-26 12:54:04 +08:00
commit 48c5f64bbd
98 changed files with 31874 additions and 0 deletions
+201
View File
@@ -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 的安全随机 keyUnix
要求文件 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 bytesminify、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)。