docs: 同步操作说明/架构/路线图(归档操作、图表基座、数据库目标硬约束)

- USAGE 新增 §6.3.1「归档的日常操作」:查看 / 筛选(回写 URL)/ 导出完整 JSON /
  以此参数再跑 / 删除(写明「删除即失去结果,结果只存归档一份」)/
  历史归档用 restore_experiment_from_job 按原 id 重建;并说明归档完整度如何标注
- USAGE/README 更正技术栈与图表基座:TradingView Lightweight Charts 4.2.3 为唯一
  图表基座(ECharts 已从 package.json、pnpm-lock.yaml、node_modules、文档与
  架构图标注中全部清除),并记录实测证据(个股页图表根节点为
  div.tv-lightweight-charts,页面 canvas 无一来自其它图表库)
- ARCHITECTURE 更正「当前数据库」(原写 SQLite/未来 MySQL):现为本机 MariaDB 10.11,
  §6 补目标库硬约束;USAGE 补服务器身份与实测连接证据
- AGENT.md 新增 §0.1:数据库目标只允许本机 MariaDB,禁止 192.168.1.10,
  由 config.py::assert_db_target_allowed 硬拦截(命中直接抛错,不静默降级)
- DEV_PLAN_DIVIDEND_BACKTEST 记录三轮实施与验证、归档恢复边界(§12.5)、已知限制
- DEV_PLAN v2/v3 标注为历史记录(避免把当时的远端库地址当现状照抄);
  ROADMAP 更正 M3 图表选型
This commit is contained in:
Simon
2026-09-20 07:31:20 +08:00
parent 23972e7063
commit 82240e383d
12 changed files with 1405 additions and 47 deletions
+15 -4
View File
@@ -16,7 +16,7 @@
详见 [AGENT.md](./AGENT.md)(开发约束)与 [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md)(架构文档),**改代码前必须阅读**。
```text
Web 前端 (frontend/web:总览 / 股票池 / 股票筛选 / 因子研究 / 因子组合 / 交易信号 / 选股回测 / 实验)
Web 前端 (frontend/web:总览 / 股票池 / 股票筛选 / 因子研究 / 因子组合 / 交易信号 / 选股回测 / 实验 / 归档详情)
↓ REST / SSE(异步 Job 状态机)
FastAPI (backend:业务对象 API,见下「核心能力」)
↓ Research Specification(统一研究契约)
@@ -72,7 +72,12 @@ cd backend
uv sync # 含 pyqlib(GitHub 源码依赖,固定 commit)。若网络下载困难/超时,按 AGENT.md §0 设置代理 192.168.1.160:3128 后重试
# 3. 运行测试
uv run pytest
uv run pytest # 全量 341 条
uv run ruff check app tests
# 3b. 端到端契约自检(真实提交回测 Job,验证页面↔后端字段不漂移)
PYTHONPATH=. .venv/bin/python ../scripts/verify_strategy_workspace.py # 策略库/说明/名称/选股直通/归档链路
PYTHONPATH=. .venv/bin/python ../scripts/verify_backtest_page_contract.py # 回测结果结构契约
# 4. 启动开发服务
uv run uvicorn app.main:app --reload --port 8000
@@ -101,8 +106,14 @@ uv run alembic revision --autogenerate -m "add xxx table"
| 因子研究 | Job 异步 IC / RankIC / 分层测试(`/api/jobs`) |
| 交易信号 | `POST /api/signals`:评分排名 + 趋势规则 → BUY/WATCH/SELL + 理由;Web `/signals` |
| 选股回测 | `POST /api/backtests`(成本/涨跌停近似;与当前选股共用同一评分引擎,v2 §25 一致性) |
| 策略资产 | `strategy` 落库 + `/api/strategies`(命名配置,可展开为回测 spec) |
| Experiment | 每次研究自动归档 + 一键复跑 + SSE 进度 |
| 定期调仓回测 | **两级截断(候选池 n → 持仓 x)+ 双周期(每 m 月择股 / 每 y 月调仓)+ 复权口径(none/qfq/hfq)+ 组合条件过滤 + 最低佣金**;输出净值/个股曲线并标注买卖点;Web `/backtest`(含高股息案例预设)、`scripts/run_dividend_case.py` |
| 每日指标 | `daily_basic`(股息率 `dv_ratio`/`dv_ttm`、PE/PB/市值)+ `dividend_yield` 因子;`sync daily_basic` 回补 |
| 退市股与时点股票池 | `sync basic --include-delisted` 入库已退市/暂停上市(`status`/`delist_date`)+ 定向 `sync daily` 补行情;`filter_stocks` 按 `as_of` 正确纳入/排除(实测 338 只) |
| 时点 ST / 名称历史 | `sync namechange` 入库名称生效区间(14,213 行);`exclude_st` 在**每个择股日**按当时名称判定(回测与 `/api/selections` 同口径),消除「曾高股息后 ST」的股息陷阱隐藏偏差(实测 3.70pp) |
| 策略库 | `strategy` 落库 + `/api/strategies` CRUD/`PUT` 原地更新/展开为回测 spec;**每个策略有后端推导的「一句话说明 + 计算公式 + 执行步骤 + 注意事项」**(`describe_strategy`,与引擎实执行规则同源);一键回测;Web `/strategies` |
| Experiment / 归档 | **完整存档**:每次回测(异步 Job 与同步接口都算)把结果 + spec + `code_version` + `data_version` 数据快照指纹写入 `experiment` 表,个股收益曲线默认**全量保存**(超出体积预算才裁剪并显式标注);列表支持 `kind`/`q` 过滤且总数经 `X-Total-Count` 暴露(不再静默截断);`DELETE /api/experiments/{id}` + `python -m app.cli.prune_experiments --keep N`(默认 dry-run,删除即失去结果,建议先导出)治理体积;**实验对比**:勾选 2~3 个 → 归一化净值曲线叠加 + 指标差值表 + `config_snapshot` 参数 diff;**归档详情页 `/experiments/{id}`**(Server Component)只读复看完整结果,并明确回答「**选股条件**」与「**交易执行依据**」;归档页可**导出完整 JSON / 以此参数再跑 / 删除**(确认框写明后果);体积用 `app.cli.prune_experiments`(默认 dry-run)治理,删错的历史归档可用 `app.cli.restore_experiment_from_job` 从 Job 副本按原 id 重建 |
| 图表基座 | **统一 TradingView Lightweight Charts 4.2.3**:`components/charts/LwChart.tsx`(折线/面积/柱状 + 买卖点标记 + tooltip + 可点击图例)与 `components/StockChart/CandleChartLW.tsx`(个股 K 线 + 成交量 + MA);ECharts 已完全下线(`package.json`、`pnpm-lock.yaml`、`node_modules`、文档与架构图标注均已清除)。实测个股页图表根节点是 Lightweight Charts 自身的 `div.tv-lightweight-charts`,页面 canvas 无一来自其它图表库 |
| 代码即名称 | 任何出现股票代码的位置都成对显示股票名称且可点击进入个股页(基本信息 + 走势图);后端在 `SelectionCandidate/SymbolCurve/ActionRecord/RankedPick/Position/Trade` 上填充 `name`,前端 `GET /api/stocks/names` 一次性缓存兜底 |
| AI Agent | `POST /api/agent/chat`,**14 个受控 Tool**(v3 §25 全清单) |
## 里程碑(详见 [ROADMAP.md](./docs/ROADMAP.md) 与 [docs/DEV_PLAN_v2.md](./docs/DEV_PLAN_v2.md))