168 lines
6.9 KiB
Markdown
168 lines
6.9 KiB
Markdown
# Quant OS 面向 80 分的目标架构
|
||
|
||
状态:本轮已建立边界、长期 namespace、机器标准和兼容入口;大模块拆分按
|
||
vertical slice 继续进行,不声称已经完成 26k 行重写。
|
||
|
||
## 1. 架构选择
|
||
|
||
采用**严格边界的模块化单体 + 专有 runtime 代理**,不是微服务。
|
||
|
||
原因:
|
||
|
||
- 个人系统不需要承担微服务的网络、部署和分布式一致性成本;
|
||
- QMT、聚宽、Qlib、JQData 有互不兼容的 Python/SDK 运行时,必须物理隔离;
|
||
- 决策身份、证据链和本地重放需要单一仓库和明确的事务边界;
|
||
- 模块边界可以先在进程内强制,达到真实吞吐或隔离需求后再拆服务。
|
||
|
||
## 2. 三平面
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
B["Composition root<br/>CLI · runtime wiring"] --> C
|
||
B --> X
|
||
C["Control plane<br/>RunSpec · orchestration · release policy"] --> A["Application use cases"]
|
||
A --> D["Data plane<br/>PIT → research → portfolio → execution"]
|
||
D --> P["Ports"]
|
||
X["Adapters / proprietary runtimes<br/>JQData · Qlib · JoinQuant · QMT · XtTrader"] --> P
|
||
D --> E["EvidenceSink port"]
|
||
C --> E
|
||
X --> E
|
||
E --> V["Evidence plane<br/>manifest · parity · scorecard · claims"]
|
||
```
|
||
|
||
硬规则:
|
||
|
||
- Control plane 只编排 RunSpec、状态和发布,不计算信号,不直接调用券商 SDK。
|
||
- Data plane 只消费不可变输入,产生 model、weight 和 execution intent;它不读
|
||
网页状态或 Gate。
|
||
- Evidence plane 只记录已经发生的事实,不得修改 target、order 或 broker fact。
|
||
- Adapter 向内实现 port;core 永远不 import `jqdatasdk`、`qlib`、`xtquant`
|
||
或 hosted 平台全局 API。
|
||
- `ReadBrokerPort` 与 `TradeBrokerPort` 分离。拥有查询权不等于拥有下单权。
|
||
- `composition` 是唯一同时依赖 application/control 与 adapters 的受检装配根;
|
||
adapter 只实现 port,不反向 import application。
|
||
|
||
## 3. 依赖方向
|
||
|
||
```text
|
||
foundation
|
||
↑
|
||
contracts / ports
|
||
↑
|
||
data | research | portfolio | execution
|
||
↑
|
||
application
|
||
↑
|
||
control
|
||
↑
|
||
composition / CLI
|
||
|
||
adapters ──implements──> ports
|
||
evidence <── consumes immutable envelopes
|
||
composition ──wires──> application + control + adapters
|
||
```
|
||
|
||
新 namespace 的边界由 `quant_os.architecture.validate_architecture` 扫描 AST
|
||
执行。CI 会拒绝例如 `research -> execution`、`data -> control` 的倒置依赖,
|
||
也会拒绝新层绕回根级 `quant60`、`adapters`、`platforms` 或 `tools`。
|
||
只有 `composition` 可以临时调用 compatibility 内核;每个 vertical slice
|
||
迁完后继续收窄。
|
||
|
||
## 4. 目录
|
||
|
||
```text
|
||
src/quant_os/
|
||
foundation/ # ID、双时钟、symbol、money
|
||
contracts/ # DTO、schema registry、版本迁移
|
||
ports/ # Data/Engine/ReadBroker/TradeBroker/EvidenceSink
|
||
data/ # PIT snapshot、catalog、quality
|
||
research/ # feature、split、model、evaluate
|
||
portfolio/ # risk、cost、capacity、optimizer
|
||
execution/ # intent、OMS、reconcile、kill switch
|
||
application/ # ingest/train/backtest/publish/shadow use cases
|
||
control/ # RunSpec、orchestrator、release policy
|
||
evidence/ # manifest、claim、parity、maturity
|
||
adapters/ # provider/platform/broker implementations
|
||
composition/ # 唯一受检进程装配根
|
||
|
||
runtimes/ # portable36、JoinQuant、QMT built-in、Colab
|
||
profiles/ # baseline-60、production-80
|
||
examples/ # 永不晋级为候选的 smoke 策略
|
||
status/ # 可发布静态验收快照
|
||
```
|
||
|
||
`quant_os` 是长期产品 namespace;成熟度只存在于 profile。当前 AST checker
|
||
只覆盖新 namespace(现为迁移壳层与新增控制代码),不会把约 26k 行 legacy
|
||
自动宣称为已分层。`quant60` 保留两个
|
||
兼容发布周期,继续读取/写入现有 V1 artifact,避免历史证据失效。
|
||
|
||
## 5. 当前代码如何迁移
|
||
|
||
| 当前模块 | 问题 | 目标位置 | 迁移条件 |
|
||
| --- | --- | --- | --- |
|
||
| `portable_core.py` | symbol、TargetPackage、动量、sizing、delta 混合 | foundation/contracts/portfolio/execution + example | golden vectors 先行 |
|
||
| `experiment.py` | fixture、研究、编排、证据混合 | research + application + evidence | real snapshot Ridge slice 接通 |
|
||
| `qmt_shadow.py` | 规划、签名、落盘、重放 3595 行 | execution/application/evidence | 真 QMT contract probe 后冻结 |
|
||
| `snapshot_pipeline.py` | 数据、决策、broker clock 混合并依赖 backtest 私有函数 | data + application + execution | 先建立公共合同 |
|
||
| `backtest.py` | engine 与 artifact publisher 混合 | local adapter + evidence | V1 manifest reader 保持兼容 |
|
||
| 平台 wrapper | JoinQuant/QMT 重复执行逻辑 | shared portable36 consumer + thin mapping | Python 3.6 golden test |
|
||
| status builder | 解析 Markdown 形成机器状态 | 只读 machine claims index | 标准/assessment 已先机器化 |
|
||
|
||
## 6. 唯一决策权威
|
||
|
||
当前最大结构问题不是文件太大,而是存在两个上游决策权威:
|
||
|
||
1. 真实 provider snapshot 仍走 `portable-momentum-v1`;
|
||
2. Ridge 五层链只在 synthetic research 中产生 TargetPackage。
|
||
|
||
目标必须统一为:
|
||
|
||
```text
|
||
authorized immutable PIT snapshot
|
||
-> frozen feature/model
|
||
-> portfolio + independent post-risk
|
||
-> TargetPackage (weights, no account quantities)
|
||
-> JoinQuant/QMT thin execution consumer
|
||
```
|
||
|
||
hosted runtime 不再现场重算 Alpha。`portable-momentum` 永远留在 example/smoke,
|
||
不能被默认 bundler 静默提升成生产候选。
|
||
|
||
跨引擎 strict peer 是 local、JoinQuant 与 QMT 的 L1—L5。Qlib 只比较其声明
|
||
参与的层级;只有显式导出同一冻结模型和组合实现时,才可提升比较范围。
|
||
Alpha158/LightGBM 研究工作流不能冒充 portable candidate 的 L3/L4 peer。
|
||
|
||
## 7. 分阶段路线
|
||
|
||
### 已在本轮落地
|
||
|
||
- 独立仓历史分支;
|
||
- `quant_os` 长期 CLI/import,`quant60` 兼容;
|
||
- 七维 80 分 machine profile 和 fail-closed evaluator;
|
||
- standard/profile canonical hash、可信 Baseline 前置、不可跳过的 77→canary→80
|
||
授权链及 `TEST_ONLY` 信任隔离;
|
||
- 新 namespace 层级和依赖检查;
|
||
- composition root 与 adapter 单向依赖;
|
||
- ReadBroker/TradeBroker/EvidenceSink port;
|
||
- 独立根 CI;
|
||
- 独立仓 clean-clone 测试修复;
|
||
- 架构、标准、迁移和上手文档。
|
||
|
||
### 下一阶段
|
||
|
||
1. 建立 golden vectors 和 V1/V2 schema registry;
|
||
2. 把真实 snapshot 接入 Ridge 主链,消除双决策权威;
|
||
3. 先拆一个完整 vertical slice,而不是按文件批量搬家;
|
||
4. 平台 wrapper 收敛为同一个 portable consumer;
|
||
5. status builder 改读统一 claims index,不再解析 Markdown;
|
||
6. 取得真实 QMT 后接通 read-only contract probe、shadow 和对账。
|
||
|
||
### 依赖外部环境的阶段
|
||
|
||
- 完整授权 JQData/OOS;
|
||
- 多期真实聚宽导出;
|
||
- 真 QMT/qmttools/XtTrader;
|
||
- 60 个交易日 shadow;
|
||
- 10 个交易日受限资金 canary;
|
||
- 生产 SLO、RPO/RTO、凭据轮换、券商程序化交易确认。
|