9.0 KiB
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 安装复制出的
xtquantbinary; - 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。推荐本地变量:
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 使用:
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 路径默认只能是:
BACKTEST
SIMULATION
SHADOW
QMT built-in 和 qmttools supplied runner 硬限制 backtest/history。XtTrader
allow_live_orders 默认 false,仓库不提供 live launch command。
未来任何 live mutation 至少还要求:
- broker read-only preflight 成功;
- market data 与完整 broker snapshot 新鲜且带时区;
- account allow-list 匹配;
- 无 unknown open order 或 reconciliation difference;
- notional/order/rate limit 已配置;
- operator approval 与 kill switch 已演练;
- 程序化交易报告和软件/频率要求由实际券商确认;
- 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:
- 停止新订单和相关自动任务;
- 通过 provider/broker 撤销或轮换 credential;
- 在仓库外保存 incident timeline;
- 从当前树移除,并在明确批准后清理历史和 mirror;
- 检查 CI、artifact、OB sync、Colab/Drive 和 downstream clone;
- 评估数据许可/个人信息泄漏范围并完成必要通知;
- 记录恢复和复发预防。
删除可见文件不等于 credential rotation。交易与数据故障流程见
runbooks/INCIDENTS.md。