580 lines
17 KiB
Markdown
580 lines
17 KiB
Markdown
# AlphaX 多策略改造实施计划
|
||
|
||
本文档是 `MULTI_STRATEGY_ARCHITECTURE.md` 的施工版,用于把多策略架构拆成可开发、可验证、可上线观察的任务包。
|
||
|
||
今晚目标不是一次性完成所有长期架构,而是交付一个能真实运行的第一阶段:
|
||
|
||
- 每条推荐、挂单、持仓都能追溯到策略。
|
||
- 现有综合确认策略不被打断,统一标记为 `main_composite_v1`。
|
||
- `box_retest_4h_v1` 进入独立策略雏形,不再只是综合确认层里的一个因子。
|
||
- paper trading 和复盘能按策略看表现。
|
||
- 前端至少能看到策略来源,明早可以观察跑出来的数据。
|
||
|
||
## 0. 基础设施重构原则
|
||
|
||
这次属于策略基础设施重构,不允许为了赶进度留下明显技术债。
|
||
|
||
必须遵守:
|
||
|
||
- DB schema 变化必须走 migration,不允许业务函数里偷偷补字段。
|
||
- 策略身份必须用 `strategy_code`,版本必须用 `strategy_version`,不能继续混用。
|
||
- 新增策略输出必须走统一 `StrategySignal` 契约,不允许每个策略各写一套 JSON。
|
||
- 因子角色必须显式声明,未知因子默认只能作为 `attribution` 或 `unknown`,不能默认变成交易触发。
|
||
- paper trading、paper orders、recommendation 必须完整继承策略血缘,不能只在推荐层有策略,交易账本丢失。
|
||
- UI/API/复盘至少要有最小闭环,否则字段只是“存了但没人用”。
|
||
- 兼容旧数据可以回填为 `main_composite_v1`,但新数据不允许空策略来源。
|
||
- 不做全局散落的硬编码策略名,策略中文名、启用状态、描述应集中维护。
|
||
|
||
允许的兼容:
|
||
|
||
- 旧综合确认策略继续运行,但必须标记为 `main_composite_v1`,并与其他策略平等。
|
||
- 第一版 `box_retest_4h_v1` 可以先 paper-only / observe-only。
|
||
- 复杂仲裁可以先做最小规则,但接口要为后续多策略扩展留好。
|
||
|
||
不允许的临时方案:
|
||
|
||
- 不允许把 `box_breakout_pullback_4h` 直接当 `strategy_code`。
|
||
- 不允许只给 paper trades 加字段,却不改写入链路。
|
||
- 不允许只写文档不补测试。
|
||
- 不允许把策略表现继续只按 `strategy_version` 聚合。
|
||
- 不允许前端继续完全看不到策略来源。
|
||
|
||
## 1. 总体交付分层
|
||
|
||
### P0:策略血缘打通
|
||
|
||
必须完成。目标是先让系统所有后续数据都带上策略来源。
|
||
|
||
- 新增策略标准结构。
|
||
- 新增因子角色定义。
|
||
- DB 增加策略血缘字段。
|
||
- 推荐写入时保存 `strategy_code`、`strategy_signal_id`、`strategy_snapshot_json`、`factor_roles_json`。
|
||
- paper orders / paper trades 继承推荐里的策略字段。
|
||
- API 和页面展示策略来源。
|
||
- 复盘统计支持按策略聚合。
|
||
- 测试覆盖 recommendation -> paper order -> paper trade 的策略血缘传递。
|
||
|
||
### P1:第一个独立策略雏形
|
||
|
||
尽量完成。目标是让 `box_retest_4h_v1` 从因子变成独立策略候选。
|
||
|
||
- 新建 `app/strategies/box_retest_4h.py`。
|
||
- 复用统一交易宇宙和 `detect_box_breakout_pullback_4h()`。
|
||
- 输出标准策略信号。
|
||
- 当前先以 observe/paper-only 运行,避免直接影响真实同步。
|
||
|
||
### P2:最小策略编排与仲裁
|
||
|
||
只做最小闭环。目标是不让多策略重复乱写推荐。
|
||
|
||
- 新建简单策略注册表/编排函数。
|
||
- 同一币种同方向保留最高置信度策略。
|
||
- 不同方向先降级观察,不做自动对冲。
|
||
- 先不做复杂策略权重投票。
|
||
|
||
### P3:技术债清理与文档同步
|
||
|
||
必须完成最小项。目标是重构后代码结构清楚、后续可扩展。
|
||
|
||
- `AGENTS.md`、`OPTIMIZATION_TODO.md`、`MULTI_STRATEGY_ARCHITECTURE.md` 同步最终事实。
|
||
- 新增模块必须有单元测试。
|
||
- 任何未完成项必须写入 TODO,不能藏在代码注释里。
|
||
- 运行命令和验收结果写入最终交付说明。
|
||
|
||
## 2. 数据库改造
|
||
|
||
### 2.1 新增 migration
|
||
|
||
新增文件:
|
||
|
||
```text
|
||
app/db/migrations/00xx_multi_strategy.sql
|
||
```
|
||
|
||
建议字段:
|
||
|
||
```sql
|
||
ALTER TABLE recommendation
|
||
ADD COLUMN IF NOT EXISTS strategy_code TEXT DEFAULT '',
|
||
ADD COLUMN IF NOT EXISTS strategy_signal_id BIGINT DEFAULT 0,
|
||
ADD COLUMN IF NOT EXISTS strategy_snapshot_json TEXT DEFAULT '{}',
|
||
ADD COLUMN IF NOT EXISTS factor_roles_json TEXT DEFAULT '{}';
|
||
|
||
ALTER TABLE paper_trades
|
||
ADD COLUMN IF NOT EXISTS strategy_code TEXT DEFAULT '',
|
||
ADD COLUMN IF NOT EXISTS strategy_signal_id BIGINT DEFAULT 0,
|
||
ADD COLUMN IF NOT EXISTS strategy_snapshot_json TEXT DEFAULT '{}',
|
||
ADD COLUMN IF NOT EXISTS factor_roles_json TEXT DEFAULT '{}';
|
||
|
||
ALTER TABLE paper_orders
|
||
ADD COLUMN IF NOT EXISTS strategy_code TEXT DEFAULT '',
|
||
ADD COLUMN IF NOT EXISTS strategy_signal_id BIGINT DEFAULT 0,
|
||
ADD COLUMN IF NOT EXISTS strategy_snapshot_json TEXT DEFAULT '{}',
|
||
ADD COLUMN IF NOT EXISTS factor_roles_json TEXT DEFAULT '{}';
|
||
```
|
||
|
||
新增标准策略信号表:
|
||
|
||
```sql
|
||
CREATE TABLE IF NOT EXISTS strategy_signals (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
run_id TEXT DEFAULT '',
|
||
strategy_code TEXT NOT NULL,
|
||
strategy_version TEXT DEFAULT '',
|
||
symbol TEXT NOT NULL,
|
||
direction TEXT DEFAULT 'long',
|
||
signal_status TEXT DEFAULT 'candidate',
|
||
confidence DOUBLE PRECISION DEFAULT 0,
|
||
score DOUBLE PRECISION DEFAULT 0,
|
||
market_regime TEXT DEFAULT '',
|
||
trigger_json TEXT DEFAULT '{}',
|
||
factor_roles_json TEXT DEFAULT '{}',
|
||
entry_plan_json TEXT DEFAULT '{}',
|
||
risk_plan_json TEXT DEFAULT '{}',
|
||
decision_log_json TEXT DEFAULT '{}',
|
||
created_at TEXT NOT NULL
|
||
);
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_strategy_signals_code_time
|
||
ON strategy_signals(strategy_code, created_at DESC);
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_strategy_signals_symbol_time
|
||
ON strategy_signals(symbol, created_at DESC);
|
||
```
|
||
|
||
可选但建议同步新增策略目录表,避免策略中文名和启用状态散落在代码里:
|
||
|
||
```sql
|
||
CREATE TABLE IF NOT EXISTS strategy_catalog (
|
||
strategy_code TEXT PRIMARY KEY,
|
||
strategy_name TEXT NOT NULL,
|
||
strategy_version TEXT DEFAULT '',
|
||
status TEXT DEFAULT 'active',
|
||
mode TEXT DEFAULT 'paper_only',
|
||
description TEXT DEFAULT '',
|
||
config_json TEXT DEFAULT '{}',
|
||
created_at TEXT NOT NULL,
|
||
updated_at TEXT NOT NULL
|
||
);
|
||
```
|
||
|
||
如果今晚来不及完整管理页面,也应先提供 DB 表和默认种子。
|
||
|
||
### 2.2 兼容回填
|
||
|
||
旧数据没有策略来源时:
|
||
|
||
- `recommendation.strategy_code = 'main_composite_v1'`
|
||
- `paper_trades.strategy_code = COALESCE(recommendation.strategy_code, 'main_composite_v1')`
|
||
- `paper_orders.strategy_code = COALESCE(recommendation.strategy_code, 'main_composite_v1')`
|
||
|
||
回填只做一次,不改变收益数据。
|
||
|
||
回填后要加非空语义检查:
|
||
|
||
- 新推荐写入后 `strategy_code` 不得为空。
|
||
- 新 paper order 写入后 `strategy_code` 不得为空。
|
||
- 新 paper trade 写入后 `strategy_code` 不得为空。
|
||
|
||
### 2.3 migration 验收
|
||
|
||
必须验证:
|
||
|
||
```bash
|
||
docker compose run --rm alphax-web python scripts/postgres/run_migrations.py
|
||
docker compose exec alphax-web python - <<'PY'
|
||
from app.db.schema import get_conn
|
||
conn = get_conn()
|
||
for table in ["recommendation", "paper_trades", "paper_orders", "strategy_signals"]:
|
||
print(table, conn.execute("SELECT COUNT(*) FROM information_schema.columns WHERE table_name=%s", (table,)).fetchone()[0])
|
||
conn.close()
|
||
PY
|
||
```
|
||
|
||
## 3. 核心代码改造
|
||
|
||
### 3.1 新增 `app/core/factor_roles.py`
|
||
|
||
职责:
|
||
|
||
- 定义因子角色枚举。
|
||
- 维护默认因子角色映射。
|
||
- 提供 `factor_roles_for_codes(signal_codes)`。
|
||
- 提供 `validate_factor_roles()`,防止未知因子默认变成交易触发。
|
||
|
||
初始角色建议:
|
||
|
||
```text
|
||
box_breakout_pullback_4h -> trigger
|
||
vp_fly_1h_current -> trigger / confirmation
|
||
short_tf_15m_ignition -> trigger,但默认 observe-only
|
||
short_tf_5m_ignition -> prerequisite / early_watch
|
||
sector_rotation -> confirmation
|
||
sentiment_resonance -> confirmation
|
||
top_trader_long -> confirmation
|
||
exchange_outflow -> confirmation
|
||
false_breakout -> risk
|
||
trend_exhaustion -> risk
|
||
risk_reward_bad -> risk
|
||
entry_quality_gate -> risk
|
||
```
|
||
|
||
注意:同一因子在不同策略里可以有不同角色;默认映射只用于兼容综合确认策略。
|
||
|
||
该模块必须保持纯函数,不依赖 DB,不读运行时配置,避免策略基础设施反向依赖业务层。
|
||
|
||
### 3.2 新增 `app/core/strategy_contract.py`
|
||
|
||
职责:
|
||
|
||
- 定义 `StrategySignal` 数据结构。
|
||
- 定义 `StrategyDecision` / `StrategyRiskPlan` / `StrategyEntryPlan` 的最小字段。
|
||
- 提供 `signal_to_recommendation_context()`,让推荐写入时能统一保存策略快照。
|
||
|
||
最小字段:
|
||
|
||
```python
|
||
strategy_code: str
|
||
strategy_version: str
|
||
symbol: str
|
||
direction: str
|
||
status: str
|
||
confidence: float
|
||
score: float
|
||
trigger: dict
|
||
factor_roles: dict
|
||
entry_plan: dict
|
||
risk_plan: dict
|
||
decision_log: dict
|
||
```
|
||
|
||
要求:
|
||
|
||
- 提供 `to_json_dict()`,统一序列化。
|
||
- 提供 `from_confirm_result()`,兼容现有确认链路。
|
||
- 提供 `default_main_composite_signal()`,给旧综合确认策略生成标准策略快照。
|
||
- 不在这里调用数据库,不在这里拉行情。
|
||
|
||
### 3.2.1 新增 `app/db/strategy_signal_queries.py`
|
||
|
||
职责:
|
||
|
||
- 插入 `strategy_signals`。
|
||
- 查询最近策略信号。
|
||
- 按 `strategy_code` 聚合信号数量。
|
||
|
||
不要塞进 `altcoin_db.py`。
|
||
|
||
### 3.3 修改推荐写入
|
||
|
||
文件:
|
||
|
||
```text
|
||
app/db/recommendation_commands.py
|
||
```
|
||
|
||
改造点:
|
||
|
||
- `create_recommendation()` 增加参数:
|
||
- `strategy_code`
|
||
- `strategy_signal_id`
|
||
- `strategy_snapshot`
|
||
- `factor_roles`
|
||
- 未传时默认 `main_composite_v1`。
|
||
- duplicate merge 时保留更强策略信号,或者暂时用最新策略覆盖空字段。
|
||
- INSERT / UPDATE 同步写入新字段。
|
||
- 写入前通过 `normalize_strategy_context()` 统一清洗,避免空字符串、坏 JSON、重复逻辑散落。
|
||
|
||
### 3.4 修改 paper trading
|
||
|
||
文件:
|
||
|
||
```text
|
||
app/db/paper_trading.py
|
||
```
|
||
|
||
改造点:
|
||
|
||
- `_open_trade()` 插入 `paper_trades` 时继承:
|
||
- `strategy_code`
|
||
- `strategy_signal_id`
|
||
- `strategy_snapshot_json`
|
||
- `factor_roles_json`
|
||
- `_order_payload_from_rec()` 和 paper order 插入时继承同样字段。
|
||
- `_record_event()` 的 detail_json 加入策略来源,方便操作日志直接解释。
|
||
- list API 返回策略字段,前端不需要二次查 recommendation。
|
||
|
||
### 3.5 修改推荐读模型
|
||
|
||
文件:
|
||
|
||
```text
|
||
app/db/recommendation_state.py
|
||
app/db/recommendation_queries.py
|
||
app/db/analytics.py
|
||
```
|
||
|
||
改造点:
|
||
|
||
- API 输出 `strategy_code`、`strategy_signal_id`、`strategy_snapshot`、`factor_roles`。
|
||
- 推荐详情页能展示策略来源。
|
||
- 归档/复盘列表支持 strategy 过滤。
|
||
|
||
### 3.6 策略注册中心
|
||
|
||
新增:
|
||
|
||
```text
|
||
app/core/strategy_registry.py
|
||
```
|
||
|
||
职责:
|
||
|
||
- 集中维护策略代码、中文名、描述、默认模式。
|
||
- 提供 `strategy_label(strategy_code)`。
|
||
- 提供 `registered_strategy_codes()`。
|
||
|
||
初始策略:
|
||
|
||
```text
|
||
main_composite_v1 -> 综合确认策略
|
||
box_retest_4h_v1 -> 4H箱体突破回踩
|
||
```
|
||
|
||
前端展示中文名时优先用 registry/API 返回值,不硬编码。
|
||
|
||
## 4. 独立策略:`box_retest_4h_v1`
|
||
|
||
### 4.1 策略定位
|
||
|
||
不是“看到箱体突破回踩就买”,而是:
|
||
|
||
```text
|
||
底部箱体完成
|
||
-> 放量突破
|
||
-> 首次/二次回踩箱体上沿或 EMA
|
||
-> 回踩不破且承接
|
||
-> 当前价格距离入场区不过远
|
||
-> 市场环境允许
|
||
-> 盈亏比合格
|
||
-> 才进入观察/挂单/交易候选
|
||
```
|
||
|
||
### 4.2 新增文件
|
||
|
||
```text
|
||
app/strategies/__init__.py
|
||
app/strategies/box_retest_4h.py
|
||
app/strategies/orchestrator.py
|
||
```
|
||
|
||
### 4.3 第一版策略规则
|
||
|
||
先决条件:
|
||
|
||
- `market_regime.risk_level != critical`
|
||
- 交易宇宙通过。
|
||
- 4H 数据足够。
|
||
- 箱体宽度合理。
|
||
|
||
核心触发:
|
||
|
||
- `detect_box_breakout_pullback_4h().detected == True`
|
||
|
||
确认条件:
|
||
|
||
- `pullback_age_bars <= 4`
|
||
- `quality in 良好/优质`
|
||
- 没有明显 `trend_exhaustion`
|
||
- 不是已经远离 `entry_zone` 太多。
|
||
|
||
入场规则:
|
||
|
||
- 距离 `entry_zone` 小于配置阈值时允许挂单或买点确认。
|
||
- 如果已经大幅拉开,只进入观察,不追。
|
||
|
||
失效规则:
|
||
|
||
- 跌回箱体。
|
||
- 距离突破/回踩时间过久。
|
||
- 1H/15m 出现假突破或趋势衰竭。
|
||
|
||
输出:
|
||
|
||
- `StrategySignal(strategy_code='box_retest_4h_v1')`
|
||
|
||
### 4.4 与现有综合确认策略关系
|
||
|
||
第一阶段不能直接删除现有综合确认策略里的 `box_breakout_pullback_4h` 加分,否则会改变当前推荐行为过大。
|
||
|
||
处理方式:
|
||
|
||
- 综合确认策略继续把它作为结构因子参与确认,策略来源仍为 `main_composite_v1`。
|
||
- 独立策略并行生成 `box_retest_4h_v1` 信号。
|
||
- 如果同一 symbol 同时被综合确认策略和箱体策略命中,短期由仲裁器保留更明确的策略快照,或在推荐 `strategy_snapshot_json` 中记录 secondary strategies。
|
||
- 明早先观察是否出现重复推荐,再决定是否让箱体策略接管该类信号。
|
||
|
||
## 5. API 与 UI 改造
|
||
|
||
### 5.1 机会总览
|
||
|
||
文件:
|
||
|
||
```text
|
||
static/app.html
|
||
app/web/routes_recommendations.py
|
||
```
|
||
|
||
改造点:
|
||
|
||
- 卡片显示中文策略名,例如“4H箱体突破回踩策略”。
|
||
- 详情页展示:
|
||
- 策略来源
|
||
- 核心触发
|
||
- 确认因子
|
||
- 入场条件
|
||
- 风险/失效条件
|
||
- API 增加 `strategy_code`、`strategy_name`、`strategy_snapshot`、`factor_roles`。
|
||
|
||
### 5.2 策略交易页
|
||
|
||
文件:
|
||
|
||
```text
|
||
static/paper_trading.html
|
||
app/web/routes_paper_trading.py
|
||
```
|
||
|
||
改造点:
|
||
|
||
- 持仓中、挂单中、已完成、操作日志都显示策略列。
|
||
- 增加策略筛选器。
|
||
- 交易详情展示 strategy snapshot。
|
||
- 列表接口支持 `strategy_code` 参数过滤。
|
||
|
||
### 5.3 复盘中心
|
||
|
||
文件:
|
||
|
||
```text
|
||
app/db/review_center.py
|
||
app/db/strategy_insights.py
|
||
static/review_center.html
|
||
```
|
||
|
||
改造点:
|
||
|
||
- 增加“按策略”聚合。
|
||
- 指标:
|
||
- 推荐数
|
||
- 挂单数
|
||
- 成交数
|
||
- 平仓数
|
||
- 胜率
|
||
- 总收益
|
||
- 平均收益
|
||
- 最大回撤
|
||
- 平均持仓时长
|
||
- 适用 market regime
|
||
|
||
### 5.4 Pipeline / 日志中心
|
||
|
||
- pipeline 批次详情展示各策略产出的信号数量。
|
||
- 系统日志中策略运行错误要带 `strategy_code`。
|
||
- 不要求今晚完整 UI,但 API 返回结构要预留。
|
||
|
||
## 6. 测试计划
|
||
|
||
### 6.1 单元测试
|
||
|
||
新增/修改:
|
||
|
||
```text
|
||
tests/test_factor_roles.py
|
||
tests/test_strategy_contract.py
|
||
tests/test_strategy_lineage.py
|
||
tests/test_box_retest_strategy.py
|
||
tests/test_paper_trading.py
|
||
tests/test_strategy_insights.py
|
||
```
|
||
|
||
重点断言:
|
||
|
||
- 因子角色不会把未知因子默认当作 trigger。
|
||
- `box_breakout_pullback_4h` 只是 trigger,不是完整策略。
|
||
- `create_recommendation()` 默认写入 `main_composite_v1`。
|
||
- paper order / paper trade 继承 `strategy_code`。
|
||
- 复盘可以按 `strategy_code` 聚合。
|
||
- API 输出策略中文名。
|
||
|
||
### 6.1.1 必须新增的回归测试
|
||
|
||
- migration 后字段存在。
|
||
- `StrategySignal` 序列化稳定。
|
||
- `main_composite_v1` 默认策略上下文生成。
|
||
- recommendation merge 不会清空已有策略来源。
|
||
- paper order 创建继承策略来源。
|
||
- paper trade 开仓继承策略来源。
|
||
- strategy aggregation 不再只按 `strategy_version`。
|
||
|
||
### 6.2 容器验证
|
||
|
||
```bash
|
||
docker compose build alphax-web alphax-scheduler alphax-price-streamer
|
||
docker compose up -d alphax-web alphax-scheduler alphax-price-streamer
|
||
docker compose exec alphax-web python -m pytest -q tests/test_factor_roles.py tests/test_strategy_contract.py tests/test_strategy_lineage.py tests/test_box_retest_strategy.py
|
||
docker compose exec alphax-web python -m app.cli screener
|
||
docker compose exec alphax-web python -m app.cli confirm
|
||
docker compose exec alphax-web python -m app.cli paper-trader
|
||
```
|
||
|
||
## 7. 明早验收标准
|
||
|
||
明早交付至少要能做到:
|
||
|
||
- 数据库 migration 正常跑过。
|
||
- Docker 服务正常 up。
|
||
- 新推荐至少有 `strategy_code`。
|
||
- 新挂单/持仓至少有 `strategy_code`。
|
||
- paper trading 页面能看到策略来源。
|
||
- 复盘/策略归因能按策略聚合。
|
||
- `box_retest_4h_v1` 能独立输出策略信号或至少进入标准策略信号结构。
|
||
- `box_breakout_pullback_4h` 在代码和文档里没有被误当作完整策略。
|
||
- 不存在新增数据 `strategy_code=''` 的情况。
|
||
- 新增基础设施模块没有反向依赖 Web 或 DB 热路径。
|
||
- 未完成事项已明确写入 TODO,不留口头债。
|
||
|
||
## 8. 风险边界
|
||
|
||
今晚不做:
|
||
|
||
- 不把多策略直接同步真实交易。
|
||
- 不做复杂策略投票。
|
||
- 不做多空完整重构。
|
||
- 不做大规模 UI 重设计。
|
||
- 不删除现有综合确认策略。
|
||
|
||
今晚可以做:
|
||
|
||
- 保留综合确认策略运行。
|
||
- 补策略血缘。
|
||
- 补第一版策略标准结构。
|
||
- 让 `box_retest_4h_v1` 作为独立候选跑起来。
|
||
- 给明早提供能观察的数据和复盘口径。
|
||
|
||
## 9. 今晚执行顺序
|
||
|
||
为了降低基础设施重构风险,按下面顺序施工:
|
||
|
||
1. 新增 migration 和回填。
|
||
2. 新增 `strategy_registry`、`factor_roles`、`strategy_contract` 纯核心模块。
|
||
3. 新增 `strategy_signal_queries`,不要碰业务状态机。
|
||
4. 修改 `create_recommendation()` 写入策略血缘。
|
||
5. 修改 paper orders / paper trades 继承策略血缘。
|
||
6. 修改读模型/API,让前端能看到策略来源。
|
||
7. 修改 paper trading 页面最小展示策略列。
|
||
8. 新增 `box_retest_4h_v1` 策略模块和最小 orchestrator。
|
||
9. 补测试。
|
||
10. Docker build/up,跑容器内回归。
|
||
11. 写明早交付总结和剩余 TODO。
|