202 lines
9.0 KiB
Markdown
202 lines
9.0 KiB
Markdown
# 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)。
|