Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ quant-lifecycle dashboard --format all
- [`docs/strategy_lifecycle_policy.zh-CN.md`](docs/strategy_lifecycle_policy.zh-CN.md)
- [`docs/strategy_portfolio_action_matrix.zh-CN.md`](docs/strategy_portfolio_action_matrix.zh-CN.md)
- [`docs/evidence_package_template.zh-CN.md`](docs/evidence_package_template.zh-CN.md)
- [`docs/cross_asset_research_driver.zh-CN.md`](docs/cross_asset_research_driver.zh-CN.md)
- [`docs/cross_asset_forward_risk_driver.zh-CN.md`](docs/cross_asset_forward_risk_driver.zh-CN.md)

## 云服务抽象层

Expand Down
51 changes: 51 additions & 0 deletions docs/cross_asset_forward_risk_driver.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# 跨资产 P4/P5 观察适配契约

## 当前架构理解

P1–P3 research driver 负责绑定输入、冻结配置和历史/OOS 证据;P4/P5 的时间属性和账户/组合属性不同,不应塞回同一个 artifact。`forward_risk_terminal.v1` 因此作为第二个纯观察 envelope:

```text
P1–P3 terminal digest
→ P4 shadow/forward(或已有 paper 结果)身份
→ P5 portfolio RiskSnapshot 身份
→ READY / DEFERRED / PARKED terminal artifact
```

## 权限边界

该适配器固定:

- `no_order=true`;
- `permission_effect=none`;
- `broker_dependency=false`;
- 不启动 paper、shadow 或 live runtime;
- 不抓行情、不运行策略、不计算仓位、不连接 broker;
- `READY` 只描述证据齐全,不授予 shadow、paper 或 live 权限。

P4 的 `mode=paper` 仅表示消费了其他平台已经产生并验证的模拟结果;QPK 适配器本身仍不连接 paper broker。没有 paper 能力的平台直接使用 `mode=shadow`,不会因此被阻塞。

## P4/P5 READY 条件

| 阶段 | artifact schema | 额外约束 |
|---|---|---|
| P4 | `forward_observation.v1` | P1–P3 terminal 必须 READY;candidate 必须一致;artifact 在 terminal 生成时未过期 |
| P5 | `portfolio_risk_snapshot.v1` | P4 必须 READY;candidate 必须一致;RiskSnapshot 身份未过期 |

缺少正常上游时输出 `DEFERRED`;格式错误、过期、candidate 不一致或越过阶段依赖时输出 `PARKED`。每个合法 P1–P3 terminal 都可生成一个 P4/P5 terminal artifact,不能以 workflow 绿色代替终态文件。

## 现有样板评估

- `ShadowValidator` 已能读取近期 performance snapshot 并比较候选,但尚未定义跨资产不可变 P4 artifact;各策略 producer 需要后续输出 `forward_observation.v1`。
- `RiskSnapshot` 已有 fail-closed、expiry、Kelly fraction、风险预算和熔断状态校验,适合作为 P5 producer;本契约只绑定其不可变身份,不复制风险算法。
- `lifecycle_matrix_runtime` 已能只读聚合 P4/P5 terminal 状态,可在 producer 接线后继续复用。
- paper 不是通用前置条件。支持 paper 的平台可提供 P4 paper observation;不支持的平台以 no-order shadow/forward observation 完成 P4。

## 低风险迁移

1. 所有资产先输出 P1–P3 terminal;缺证据时如实 `DEFERRED/PARKED`。
2. 各策略将现有 shadow 日报适配为 `forward_observation.v1`,不改变策略计算。
3. 将现有 `RiskSnapshot` 序列化、摘要后注册为 `portfolio_risk_snapshot.v1`。
4. workflow 的 `always()` 终态步骤输出 P4/P5 envelope。
5. 只读 matrix 消费这些 artifact;live/runtime 继续使用独立 authority 和 Risk Gate。

不推荐新增第二套 scheduler、通用事件总线或让此模块直接运行 paper/broker;这些会把证据适配层与执行层重新耦合。
9 changes: 9 additions & 0 deletions docs/cross_asset_integration_plan.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,12 @@

当前覆盖:CN equity 8 条、HK equity 3 条、crypto 5 条;详见
`docs/registry/cross_asset_strategy_inventory.json`。

P1–P3 生产者统一写出 `research_driver_terminal.v1`,包括正常、等待和失败
分支;具体字段、终态推导和 no-order 边界见
[`cross_asset_research_driver.zh-CN.md`](cross_asset_research_driver.zh-CN.md)。

P4/P5 使用独立的 `forward_risk_terminal.v1` 观察契约绑定 P1–P3 terminal
digest、forward/shadow(或已有 paper)证据与组合 RiskSnapshot;该契约固定
no-order、无 broker 依赖且不产生权限。详见
[`cross_asset_forward_risk_driver.zh-CN.md`](cross_asset_forward_risk_driver.zh-CN.md)。
66 changes: 66 additions & 0 deletions docs/cross_asset_research_driver.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# 跨资产 Research Driver 契约

## 目标与边界

`research_driver_terminal.v1` 为 US、CN、HK、Crypto 提供相同的 P1–P3 研究终态。它只汇总已经生成并验证过的 artifact 身份,不抓取数据、不执行回测、不读取策略 catalog,也不接入 broker。

固定边界:

```text
P1 research input manifest
→ P2 strategy config freeze
→ P3 strategy evidence package
→ READY / DEFERRED / PARKED terminal artifact
```

每次有合法的 run/strategy/candidate 身份时都必须生成 terminal artifact:

- 三个阶段均有有效 artifact:`READY`;
- artifact 尚未生成或正常等待上游:`DEFERRED`;
- artifact 格式错误、摘要错误或越过上游依赖:`PARKED`;
- 任意结果始终为 `no_order=true`、`permission_effect=none`。

## 证据要求

| 阶段 | READY 所需 artifact | 说明 |
|---|---|---|
| P1 | `research_input_manifest.v1` | 由现有 P1 validator 校验后提供身份与 SHA-256 |
| P2 | `strategy_config_freeze.v1` | 冻结候选配置的身份与 SHA-256 |
| P3 | `strategy_evidence_package.v2` | 由现有 P3 validator 校验后提供身份与 SHA-256 |

`catalog_status`、`runtime_enabled`、inventory 条目或网页显示都不是证据。契约不接受这些字段,并固定输出 `catalog_status_used_as_evidence=false`。

## 生产者用法

```python
from quant_platform_kit.strategy_lifecycle import (
build_ready_research_stage,
build_research_driver_terminal_artifact,
)

terminal = build_research_driver_terminal_artifact(
run_id="daily-2026-08-24",
generated_at="2026-08-24T22:00:00+08:00",
strategy_id="example_strategy",
candidate_id="candidate-001",
domain="cn_equity",
p1_input=build_ready_research_stage(
"p1_input", artifact_id="manifest-001", artifact_sha256="a" * 64
),
p2_freeze=build_ready_research_stage(
"p2_freeze", artifact_id="freeze-001", artifact_sha256="b" * 64
),
p3_evidence=None,
)
assert terminal["terminal_status"] == "DEFERRED"
assert terminal["no_order"] is True
```

生产 workflow 应在正常、跳过、依赖缺失和失败分支的 finally/always 步骤中写出该 JSON。这个契约不会自动把 `READY` 提升为 shadow、paper 或 live;后续生命周期消费者仍需独立验证 artifact 与权限。

## 迁移风险

- 旧策略可先只写 `DEFERRED`,不需要伪造 P1/P2/P3 完成状态。
- domain 仅允许 `us_equity`、`cn_equity`、`hk_equity`、`crypto`。
- 该模块不替代 P1/P3 原始 validator;它只绑定验证后的不可变身份。
- 不允许用 catalog/inventory 状态填充 READY,也不允许从该 artifact 推导交易权限。
142 changes: 142 additions & 0 deletions src/quant_platform_kit/schemas/forward-risk-terminal.v1.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://quantstrategylab.dev/schemas/forward-risk-terminal.v1.schema.json",
"title": "forward_risk_terminal.v1",
"description": "Terminal, cross-asset P4/P5 observation artifact. It has no broker or execution authority.",
"type": "object",
"additionalProperties": false,
"required": [
"schema_version",
"terminal",
"terminal_status",
"generated_at",
"run_id",
"strategy_id",
"candidate_id",
"domain",
"research_terminal_status",
"research_terminal_sha256",
"no_order",
"permission_effect",
"broker_dependency",
"stages"
],
"properties": {
"schema_version": {"const": "forward_risk_terminal.v1"},
"terminal": {"const": true},
"terminal_status": {"$ref": "#/$defs/terminalStatus"},
"generated_at": {"type": "string", "format": "date-time"},
"run_id": {"$ref": "#/$defs/nonEmptyString"},
"strategy_id": {"$ref": "#/$defs/nonEmptyString"},
"candidate_id": {"$ref": "#/$defs/nonEmptyString"},
"domain": {"enum": ["us_equity", "cn_equity", "hk_equity", "crypto"]},
"research_terminal_status": {"$ref": "#/$defs/terminalStatus"},
"research_terminal_sha256": {"$ref": "#/$defs/sha256"},
"no_order": {"const": true},
"permission_effect": {"const": "none"},
"broker_dependency": {"const": false},
"stages": {
"type": "object",
"additionalProperties": false,
"required": ["p4_forward", "p5_risk"],
"properties": {
"p4_forward": {
"$ref": "#/$defs/stageRecord",
"properties": {
"stage": {"const": "P4"},
"mode": {"enum": ["shadow", "paper"]},
"artifact": {
"oneOf": [
{"type": "null"},
{
"$ref": "#/$defs/artifactIdentity",
"properties": {"schema_version": {"const": "forward_observation.v1"}}
}
]
}
}
},
"p5_risk": {
"$ref": "#/$defs/stageRecord",
"properties": {
"stage": {"const": "P5"},
"mode": {"const": "portfolio_risk"},
"artifact": {
"oneOf": [
{"type": "null"},
{
"$ref": "#/$defs/artifactIdentity",
"properties": {"schema_version": {"const": "portfolio_risk_snapshot.v1"}}
}
]
}
}
}
}
}
},
"$defs": {
"nonEmptyString": {"type": "string", "minLength": 1, "pattern": ".*\\S.*"},
"sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
"reasonCode": {"type": "string", "pattern": "^[a-z][a-z0-9_]{0,127}$"},
"terminalStatus": {"enum": ["READY", "DEFERRED", "PARKED"]},
"artifactIdentity": {
"type": "object",
"additionalProperties": false,
"required": [
"artifact_id",
"schema_version",
"sha256",
"candidate_id",
"observed_at",
"expires_at"
],
"properties": {
"artifact_id": {"$ref": "#/$defs/nonEmptyString"},
"schema_version": {"type": "string"},
"sha256": {"$ref": "#/$defs/sha256"},
"candidate_id": {"$ref": "#/$defs/nonEmptyString"},
"observed_at": {"type": "string", "format": "date-time"},
"expires_at": {"type": "string", "format": "date-time"}
}
},
"stageRecord": {
"type": "object",
"additionalProperties": false,
"required": ["stage", "status", "mode", "artifact", "reason_codes"],
"properties": {
"stage": {"enum": ["P4", "P5"]},
"status": {"$ref": "#/$defs/terminalStatus"},
"mode": {"enum": ["shadow", "paper", "portfolio_risk"]},
"artifact": {
"oneOf": [
{"type": "null"},
{"$ref": "#/$defs/artifactIdentity"}
]
},
"reason_codes": {
"type": "array",
"uniqueItems": true,
"items": {"$ref": "#/$defs/reasonCode"}
}
},
"allOf": [
{
"if": {"properties": {"status": {"const": "READY"}}, "required": ["status"]},
"then": {
"properties": {
"artifact": {"type": "object"},
"reason_codes": {"maxItems": 0}
}
},
"else": {
"properties": {
"artifact": {"type": "null"},
"reason_codes": {"minItems": 1}
}
}
}
]
}
}
}
Loading