diff --git a/.gitignore b/.gitignore index 50a148e..3ed152b 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,6 @@ experiments/* .idea/ .vscode/ *.swp + +# ================= archify 视觉验证副产物(重新生成即可) ================= +docs/diagrams/*.visual-check.* diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md new file mode 100644 index 0000000..7c52925 --- /dev/null +++ b/docs/ROADMAP.md @@ -0,0 +1,150 @@ +# 开发计划(Roadmap) + +> 依据:[AGENT.md](./AGENT.md)(开发约束)、[docs/ARCHITECTURE.md](./ARCHITECTURE.md)(架构) +> 引擎:Qlib 只做计算引擎 · 数据源:Tushare 第一、Sina 备用 · 数据库:SQLite 起步、SQLAlchemy 保证 MySQL 可切换 +> 现处:**M0 已完成(工程骨架 + 可运行后端)**,下一步进入 **Phase 1 数据层** + +--- + +## 0. 总览与里程碑 + +| 里程碑 | 内容 | 验收口径 | +|---|---|---| +| M0 ✅ | 工程初始化:uv + FastAPI 骨架、分层包、SQLAlchemy/Alembic、CI 前检查(pytest/ruff) | `/api/health` 可用、测试通过、已推送远端 | +| M1 | Phase 1 数据层:Tushare 拉取 → 标准化 → SQLite/Parquet | 命令行可全量/增量同步,来源可追溯 | +| M2 | Phase 2 Qlib:Qlib Dataset 构建 + 因子 + LightGBM + 回测(Adapter 封装) | Research Specification 能驱动一次完整回测,产出标准结果 | +| M3 | Phase 3 Web:股票池 / 因子 / 选股 / 回测 / 结果可视化 | 浏览器完成「选池→算因子→回测→看图」闭环 | +| M4 | Phase 4 Experiment:研究全量可复现归档 + Job/SSE 异步化 | 任一历史实验可一键复跑 | +| M5 | Phase 5 AI Agent:自然语言 → Research Plan → 受控 Tool → Experiment | Agent 能独立完成一次「因子假设→测试→结论」并留档 | + +每阶段结束时同步更新:README / AGENT.md 相关清单 / 文档;**禁止跨阶段提前堆量**(AGENT.md §38)。 + +--- + +## 1. Phase 1 —— 数据层(M1,当前下一步) + +> 目标:让系统拥有可追溯、可增量、无未来函数风险的 A 股数据资产。 + +### 1.1 Domain / DTO(先定契约) + +- `domain/entities`:`Stock`(symbol/name/industry/listing_date…)、`TradingCalendar`、`StockDaily`(含 adjust 字段)、`AdjustFactor`、`FinancialIndicator`、`SyncLog` +- `domain/repositories`:`StockRepository / TradingCalendarRepository / StockDailyRepository / SyncLogRepository`(Protocol) +- Pydantic DTO:`StockFilter`、`SyncRequest`、`SyncLogQuery` + +### 1.2 Data Provider(接口 + 双实现) + +- `MarketDataProvider`(Protocol):`get_daily / get_stock_basic / get_trade_cal / get_financial / get_adjust_factor`,签名支持 `as_of_date` +- `TushareProvider`:封装 `tushare.pro`,token 从 `.env` 读;请求限流、错误分类(限频/无权限/网络) +- `SinaProvider`:仅补缺失/交叉校验(**备用**,业务代码不得直连新浪实现) +- **Failover + 审计**(AGENT.md §7):每次拉取写 `SyncLog`:`source / request_time / success / failure_reason / row_count / data_date`,禁止静默切换 + +### 1.3 标准化与校验 + +- 字段统一:`symbol`(如 `600519.SH`)、`trade_date`;财务字段区分 `report_date / announce_date` +- 校验器:空值率、量价非负、涨跌幅超限告警、复权因子单调性(日线复权因子不递减) +- 未来函数红线:**财务数据只允许在 `announce_date` 之后可见**(表结构与查询都体现) + +### 1.4 持久化与迁移 + +- SQLAlchemy Model:stock / trading_calendar / stock_daily / adjust_factor / financial_indicator / sync_log / data_source_status +- Alembic:每个 Model 一版迁移;`render_as_batch` 已配置兼容 SQLite +- 规模策略:日线等明细写 SQLite 同时按年导出 Parquet(`data/parquet`),后续切 DuckDB/Qlib 用 Parquet(AGENT.md §13) + +### 1.5 同步调度(第一版从 CLI 起步) + +- `scripts/` 下 CLI:`sync basic|calendar|daily|financial [--start --end --symbols]`,支持断点续传(按 `data_date` 上限续拉) +- 全部耗时操作留 Job 形态(状态机 queued/running/success/failed/cancelled),API 异步化放 M3/M4 + +### 1.6 验收测试 + +- Provider failover:Tushare 抛错 → 自动尝试 Sina → 审计记录正确 +- 未来函数:财务在 announce_date 前查询返回空 +- Repository:DAO 层 CRUD + 幂等 upsert(`(symbol, trade_date)` 唯一) +- 迁移:`alembic upgrade head` 幂等可重放 + +**里程碑 M1 完成的判定**:`python -m scripts.sync daily --start 2024-01-01` 全量跑通,`sync_log` 完整,`data/quant.db` + `data/parquet` 均有产物,测试通过。 + +--- + +## 2. Phase 2 —— Qlib 研究引擎(M2) + +> 目标:不碰 Qlib 源码,用 Research Specification 驱动完整「因子→模型→回测」。 + +### 2.1 Qlib Adapter(`quant/qlib_adapter/`) + +- `provider.py`:把 MarketDataProvider / Parquet 喂给 Qlib(QlibDataset 或 D/1d handler 数据源) +- `dataset.py`:Parquet → Qlib bin 特征集(`data/qlib`),含交易日历/股票池口径 +- `feature.py`:Alpha158 / 自定义因子注册(因子元数据见 §3.1) +- `model.py`:LightGBM 训练/预测封装(参数收敛、seed 固定、可复现) +- `backtest.py`:TopK 低频回测封装,输出标准化 BacktestResult + +### 2.2 Research Specification 驱动 + +- Pydantic Schema:universe / factors(含权重) / selection / rebalance / period / cost 参数 +- Validator:禁止未来函数字段(financial 用 `as_of`)、范围检查、成本非负 +- Strategy Builder:Spec → 具体策略对象(**不直接拼 Qlib YAML**) + +### 2.3 回测真实性(AGENT.md §24) + +手续费/印花税/滑点/涨跌停/停牌/换仓频率逐项落实;未实现项必须在结果中显式标注「未建模」,禁止默认无成本假设。 + +### 2.4 输出标准化(ARCHITECTURE §14) + +统一 `BacktestResult`:summary / equity_curve / drawdown / monthly_returns / yearly_returns / positions / trades / turnover / risk_metrics / factor_exposure,前端只依赖该结构。 + +**M2 判定**:命令行传入一份 Research Specification JSON → 产出标准 BacktestResult + 图表数据;因子 IC/分层测试可跑;Qlib 全部调用位于 qlib_adapter。 + +--- + +## 3. Phase 3 —— Web 前端(M3) + +> 目标:业务导向 UI(股票池/因子/选股/回测/结果),不暴露 Qlib 内部概念。 + +- `frontend/web`:Next.js(TS) + ECharts(按 README 与架构 §12/§13/§26 初始化) +- 页面:Dashboard → 股票池 → 因子研究 → 选股 → 回测 → 结果(Experiment 视角) +- API 对齐业务对象(AGENT.md §17):`/api/stocks /api/universes /api/factors /api/factor-tests /api/strategies /api/backtests /api/experiments /api/jobs` +- 交互:参数清晰、结果可视化;耗时任务显示 job 进度(轮询起步,SSE 视需要) +- DTO 前后端共享 Schema(OpenAPI 生成 TS 类型) + +**M3 判定**:浏览器完成「选池→配因子→回测→看图」闭环,UI 无任何 Qlib/SQL 字样。 + +--- + +## 4. Phase 4 —— Experiment 与异步化(M4) + +- `experiment` 模型落地:experiment_id / data_version / code_version / strategy_version / universe / factors / model / parameters / backtest_config / period / result(含 git commit 记录) +- Job 体系:queued→running→(success|failed|cancelled) + 阶段事件(factor_calculation/model_training/backtesting…),FastAPI BackgroundTasks 起步,不引 Redis/Celery(AGENT.md §15/§38) +- SSE:`/api/jobs/{id}/events` 推送进度 +- 复跑:任意历史 Experiment 可从存档配置重放(数据版本需存在) + +**M4 判定**:一次研究自动落 Experiment;网页可查看历史实验并一键复跑。 + +--- + +## 5. Phase 5 —— AI Research Agent(M5) + +- `agent/tools`:search_stocks / get_market_data / test_factor / create_strategy / run_backtest / get_experiment / compare_experiments(只读 + 沙箱,AGENT.md §28 禁令表) +- Agent 编排:自然语言 → Research Plan → 逐步 Tool 调用 → 产出 Experiment → 结论分析(§29 假设-实验-分析循环) +- 反过拟合纪律:IC/RankIC/ICIR/分层/换手/行业市值暴露/样本外 walk-forward;不得以单次 Sharpe 高宣布有效 +- 接入:先本地(LLM API Key 走 .env),后续可视需要提供 API + +**M5 判定**:对 Agent 说「找适合 A 股月度调仓的低频因子」→ Agent 产出因子测试报告 + Experiment,结论包含稳健性讨论。 + +--- + +## 6. 贯穿全程的硬约束(每次提交自查,AGENT.md §41) + +- [ ] 是否违反 ARCHITECTURE.md / 绕过 DAO / 把 SQLite 写死? +- [ ] 是否直接依赖 Qlib 内部实现(应只在 `quant/qlib_adapter/`)? +- [ ] 是否可能引入未来函数 / 数据泄露(as_of_date、announce_date、历史成分股)? +- [ ] 新表是否走 Model → Migration → Test? +- [ ] API 契约是否变?文档是否同步? +- [ ] 是否有测试(至少相关模块)?是否运行通过? +- [ ] 是否把 secret / 数据库 / 大文件提交进 Git? +- [ ] 是否做了不必要的大规模重构(应最小修改)? + +## 7. 最近三个可执行项(建议顺序) + +1. 定义 Phase 1 的 Domain 实体与 Repository Protocol(纯接口,无数据库依赖) +2. 实现 `TushareProvider` + `SinaProvider` + Failover 审计(先用 .env 配好的 token 实测拉 1 只股票日线) +3. 落 SQLite Model + Alembic 首版迁移 + Repository 实现 + 对应测试 diff --git a/docs/diagrams/qlib-architecture.html b/docs/diagrams/qlib-architecture.html new file mode 100644 index 0000000..c546d34 --- /dev/null +++ b/docs/diagrams/qlib-architecture.html @@ -0,0 +1,13715 @@ + + + + + + + A股量化研究平台 · 系统架构 Diagram + + + + + + + + + + + +
+ +
+
+
+

A股量化研究平台 · 系统架构

+
+
+ + + + + + +
+ + A股量化研究平台 · 系统架构 + A architecture diagram generated by Archify. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Web UI · Next.js · ECharts · Architecture component + + + + Web UI + Next.js · ECharts + + + + FastAPI API · Pydantic DTO · REST / SSE · Architecture component + + + + FastAPI API + Pydantic DTO · REST / SSE + + + + Application Services · 数据 / 因子 / 策略 / 回测 / 实验 · Architecture component + + + + Application Services + 数据 / 因子 / 策略 / 回测 / 实验 + + + + Domain · Repository · 实体 + Protocol(禁 SQL) · Architecture component + + + + Domain · Repository + 实体 + Protocol(禁 SQL) + + + + Agent Service · AI 助手 · 受控 Tool · Architecture component + + + + Agent Service + AI 助手 · 受控 Tool + + + + Tushare · 日线 / 财务 / 日历(首选) · Architecture component + + + + Tushare + 日线 / 财务 / 日历(首选) + + + + 新浪财经 · 兜底 / 交叉验证(备用) · Architecture component + + + + 新浪财经 + 兜底 / 交叉验证(备用) + + + + Quant · Qlib Adapter · Dataset / 训练 / 回测封装 · Architecture component + + + + Quant · Qlib Adapter + Dataset / 训练 / 回测封装 + + + + Qlib 引擎 · LightGBM / 回测(不改源码) · Architecture component + + + + Qlib 引擎 + LightGBM / 回测(不改源码) + + + + SQLite · 元数据 / 实验 / Job · Architecture component + + + + SQLite + 元数据 / 实验 / Job + + + + Parquet · Qlib Dataset · 行情 / 财务 / 特征 · Architecture component + + + + Parquet · Qlib Dataset + 行情 / 财务 / 特征 + + + + + + REST / SSE + + + + Research Specification + + + + Repository Protocol · 编排 + + + + 元数据 / 实验 + + + + 时序 / 特征 + + + + 行情 / 财务(首选) + + + + 兜底(缺失) + + + + 因子 / 回测 Job + + + + Dataset / 训练 / 回测 + + + + 受控 Tool(Phase 5) + + + + + Legend + + + Frontend + + + + Backend + + + + Database + + + + External + + + +

+ + + + + + + + +
+ + +
+
+
+
+

主研究链

+
+
    +
  • • Web UI → API(Research Specification DTO)→ 服务编排 → Repository → SQLite / Parquet
  • +
  • • Qlib 仅经 Qlib Adapter 调用,业务层不直接 import qlib
  • +
+
+ +
+
+
+

数据源与边界纪律

+
+
    +
  • • Tushare 首选,新浪兜底须经统一 Provider 并记录来源,禁止静默切换
  • +
  • • 业务层禁 SQL / Session 直连;Agent 仅走受控 Tool(Phase 5)
  • +
+
+ +
+
+
+

异步与可复现

+
+
    +
  • • 因子 / 训练 / 回测为异步 Job:queued → running → success / failed / cancelled
  • +
  • • 所有研究落 Experiment,含数据与代码版本,可一键复跑
  • +
+
+
+ +
+ + + + diff --git a/docs/diagrams/qlib-architecture.json b/docs/diagrams/qlib-architecture.json new file mode 100644 index 0000000..29571bf --- /dev/null +++ b/docs/diagrams/qlib-architecture.json @@ -0,0 +1,65 @@ +{ + "schema_version": 1, + "diagram_type": "architecture", + "meta": { + "title": "A股量化研究平台 · 系统架构", + "quality_profile": "showcase", + "viewBox": [1360, 660], + "views": [ + { "id": "main-chain", "label": "主研究链", "focus": ["web-ui", "api", "services", "domain", "sqlite", "parquet"], "note": "从 Web UI 经 Research Specification 到持久化的业务主链。" }, + { "id": "quant-path", "label": "量化引擎链路", "focus": ["services", "qlib-adapter", "qlib"], "note": "Qlib 只经 Adapter 被调用,业务层不直接 import qlib。" }, + { "id": "source-path", "label": "数据源链路", "focus": ["tushare", "sina", "services"], "note": "Tushare 首选,新浪仅作缺失兜底与交叉验证。" } + ] + }, + "components": [ + { "id": "web-ui", "type": "frontend", "label": "Web UI", "sublabel": "Next.js · ECharts", "pos": [460, 16], "size": [320, 64] }, + { "id": "api", "type": "backend", "label": "FastAPI API", "sublabel": "Pydantic DTO · REST / SSE", "pos": [460, 118], "size": [320, 64] }, + { "id": "services", "type": "backend", "label": "Application Services", "sublabel": "数据 / 因子 / 策略 / 回测 / 实验", "pos": [400, 232], "size": [440, 108] }, + { "id": "domain", "type": "backend", "label": "Domain · Repository", "sublabel": "实体 + Protocol(禁 SQL)", "pos": [460, 392], "size": [320, 80] }, + { "id": "agent", "type": "backend", "label": "Agent Service", "sublabel": "AI 助手 · 受控 Tool", "pos": [30, 40], "size": [240, 62] }, + { "id": "tushare", "type": "external", "label": "Tushare", "sublabel": "日线 / 财务 / 日历(首选)", "pos": [30, 232], "size": [240, 64] }, + { "id": "sina", "type": "external", "label": "新浪财经", "sublabel": "兜底 / 交叉验证(备用)", "pos": [30, 390], "size": [240, 64] }, + { "id": "qlib-adapter", "type": "backend", "label": "Quant · Qlib Adapter", "sublabel": "Dataset / 训练 / 回测封装", "pos": [1010, 232], "size": [290, 72] }, + { "id": "qlib", "type": "external", "label": "Qlib 引擎", "sublabel": "LightGBM / 回测(不改源码)", "pos": [1010, 400], "size": [290, 68] }, + { "id": "sqlite", "type": "database", "label": "SQLite", "sublabel": "元数据 / 实验 / Job", "pos": [330, 532], "size": [240, 64] }, + { "id": "parquet", "type": "database", "label": "Parquet · Qlib Dataset", "sublabel": "行情 / 财务 / 特征", "pos": [750, 532], "size": [260, 64] } + ], + "connections": [ + { "id": "req-rest", "from": "web-ui", "to": "api", "label": "REST / SSE", "labelAt": [620, 94] }, + { "id": "to-spec", "from": "api", "to": "services", "label": "Research Specification", "variant": "emphasis", "labelAt": [620, 196] }, + { "id": "to-domain", "from": "services", "to": "domain", "label": "Repository Protocol · 编排", "labelAt": [620, 366] }, + { "id": "domain-sqlite", "from": "domain", "to": "sqlite", "label": "元数据 / 实验", "fromSide": "bottom", "toSide": "top" }, + { "id": "domain-parquet", "from": "domain", "to": "parquet", "label": "时序 / 特征", "fromSide": "bottom", "toSide": "top" }, + { "id": "fetch-tushare", "from": "tushare", "to": "services", "label": "行情 / 财务(首选)", "variant": "emphasis", "labelAt": [250, 318] }, + { "id": "fallback-sina", "from": "sina", "to": "services", "label": "兜底(缺失)", "variant": "dashed" }, + { "id": "to-adapter", "from": "services", "to": "qlib-adapter", "label": "因子 / 回测 Job", "variant": "emphasis" }, + { "id": "adapter-qlib", "from": "qlib-adapter", "to": "qlib", "label": "Dataset / 训练 / 回测", "fromSide": "bottom", "toSide": "top", "labelAt": [1155, 318] }, + { "id": "agent-tools", "from": "agent", "to": "services", "label": "受控 Tool(Phase 5)", "variant": "dashed" } + ], + "cards": [ + { + "dot": "emerald", + "title": "主研究链", + "items": [ + "Web UI → API(Research Specification DTO)→ 服务编排 → Repository → SQLite / Parquet", + "Qlib 仅经 Qlib Adapter 调用,业务层不直接 import qlib" + ] + }, + { + "dot": "violet", + "title": "数据源与边界纪律", + "items": [ + "Tushare 首选,新浪兜底须经统一 Provider 并记录来源,禁止静默切换", + "业务层禁 SQL / Session 直连;Agent 仅走受控 Tool(Phase 5)" + ] + }, + { + "dot": "amber", + "title": "异步与可复现", + "items": [ + "因子 / 训练 / 回测为异步 Job:queued → running → success / failed / cancelled", + "所有研究落 Experiment,含数据与代码版本,可一键复跑" + ] + } + ] +} diff --git a/docs/diagrams/qlib-dataflow.html b/docs/diagrams/qlib-dataflow.html new file mode 100644 index 0000000..dcb34b1 --- /dev/null +++ b/docs/diagrams/qlib-dataflow.html @@ -0,0 +1,13775 @@ + + + + + + + A股量化研究平台 · 数据流水 Diagram + + + + + + + + + + + +
+ +
+
+
+

A股量化研究平台 · 数据流水

+
+
+ + + + + + +
+ + A股量化研究平台 · 数据流水 + A data-flow diagram generated by Archify. + + + + + + + + + + + + + + + + + + + + + + + + + 01 / 数据接入 + + + 02 / 数据落地 + + + 03 / 特征构建 + + + 04 / 研究计算 + + + 05 / 回测 · 实验 · 消费 + + + + + + + + + + + + + + + + + + + + Tushare · 日线 / 财务 / 交易日历 · 01 / 数据接入 · 首选 + + + + Tushare + 日线 / 财务 / 交易日历 + 首选 + + + + Data Provider · 归一化 / 校验 / 审计 · 01 / 数据接入 · MarketDataProvider + + + + Data Provider + 归一化 / 校验 / 审计 + MarketDataProvider + + + + 新浪财经 · 缺失兜底 / 交叉验证 · 01 / 数据接入 · 备用 + + + + 新浪财经 + 缺失兜底 / 交叉验证 + 备用 + + + + SQLite · 股票 / 日历 / 因子定义 / Job · 02 / 数据落地 · 业务库 + + + + SQLite + 股票 / 日历 / 因子定义 / Job + 业务库 + + + + Parquet · 历史行情 / 复权 / 财务时序 · 02 / 数据落地 · 时序库 + + + + Parquet + 历史行情 / 复权 / 财务时序 + 时序库 + + + + Qlib Dataset · data/qlib 特征集 · 03 / 特征构建 · 研究数据 + + + + Qlib Dataset + data/qlib 特征集 + 研究数据 + + + + 因子研究 · Alpha158 / 自定义因子 · 04 / 研究计算 · IC · 分层测试 + + + + 因子研究 + Alpha158 / 自定义因子 + IC · 分层测试 + + + + 模型训练 · LightGBM · 04 / 研究计算 · 预测信号 + + + + 模型训练 + LightGBM + 预测信号 + + + + 选股回测 · 调仓 / 成本 / 涨跌停 / 停牌 · 05 / 回测 · 实验 · 消费 · 低频策略 + + + + 选股回测 + 调仓 / 成本 / 涨跌停 / 停牌 + 低频策略 + + + + Experiment · 参数 / 结果 / 数据与代码版本 · 05 / 回测 · 实验 · 消费 · 可复现 + + + + Experiment + 参数 / 结果 / 数据与代码版本 + 可复现 + + + + FastAPI API · 业务 API(Pydantic DTO) · 05 / 回测 · 实验 · 消费 · REST / SSE + + + + FastAPI API + 业务 API(Pydantic DTO) + REST / SSE + + + + Web UI · Next.js · ECharts · 05 / 回测 · 实验 · 消费 · 结果可视化 + + + + Web UI + Next.js · ECharts + 结果可视化 + + + + + + 行情 / 财务 raw + + + + 兜底 raw + + + + 股票 / 日历 / 元数据 + + + + 行情 / 财务时序 + + + + 交易日历 / 股票池 + + + + 行情特征输入 + + + + 特征矩阵 + + + + 训练 / 预测特征 + + + + 因子信号 + + + + 预测信号 + + + + 因子测试归档 + + + + 回测结果归档 + + + + 结果查询 DTO + + + + REST / SSE + + + + + Legend + + + primary data + + + + async batch + + + + data store + + + + data flow + + + +

+ + + + + + + + +
+ + +
+
+
+
+

主研究数据流

+
+
    +
  • • Tushare → Data Provider(归一化 / 校验 / 审计)→ SQLite 与 Parquet 分流
  • +
  • • Qlib Dataset 汇总日历与行情 → 因子 / 模型 → 回测 → Experiment 全量归档
  • +
  • • 每条拉取记录 source / 行数 / 时间,来源可追溯
  • +
+
+ +
+
+
+

防未来函数口径

+
+
    +
  • • 财务数据区分 report_date / announce_date,仅 announce_date 后可见
  • +
  • • 研究查询一律带 as_of_date,禁止未来成分 / 行业 / 财务数据
  • +
  • • 新浪仅作缺失兜底与交叉验证,禁止静默切换
  • +
+
+ +
+
+
+

结果消费

+
+
    +
  • • Experiment → FastAPI API → Web UI(REST / SSE)可视化
  • +
  • • AI Agent(Phase 5)仅经受控 Tool 经 API 读取研究数据与实验
  • +
  • • 历史实验含数据与代码版本,可一键复跑
  • +
+
+
+ +
+ + + + diff --git a/docs/diagrams/qlib-dataflow.json b/docs/diagrams/qlib-dataflow.json new file mode 100644 index 0000000..c814c42 --- /dev/null +++ b/docs/diagrams/qlib-dataflow.json @@ -0,0 +1,373 @@ +{ + "schema_version": 1, + "diagram_type": "dataflow", + "meta": { + "title": "A股量化研究平台 · 数据流水", + "quality_profile": "showcase", + "viewBox": [ + 1300, + 693 + ], + "views": [ + { + "id": "main-path", + "label": "主研究数据流", + "focus": [ + "tushare", + "provider", + "parquet", + "dataset", + "factor", + "backtest", + "experiment", + "api", + "web" + ], + "note": "行情从 Tushare 一路流转到可复现的实验与可视化。" + }, + { + "id": "future-free", + "label": "防未来函数口径", + "focus": [ + "provider", + "sqlite", + "parquet", + "dataset" + ], + "note": "财务数据按 announce_date 控制可见性,查询一律带 as_of_date。" + }, + { + "id": "agent-path", + "label": "AI 研究助手消费", + "focus": [ + "experiment", + "api", + "web" + ], + "note": "结果经 API 提供给 Web UI;AI Agent(Phase 5)仅经受控 Tool 经 API 消费研究数据。" + } + ] + }, + "stages": [ + { + "label": "数据接入" + }, + { + "label": "数据落地" + }, + { + "label": "特征构建" + }, + { + "label": "研究计算" + }, + { + "label": "回测 · 实验 · 消费" + } + ], + "nodes": [ + { + "id": "tushare", + "type": "external", + "label": "Tushare", + "sublabel": "日线 / 财务 / 交易日历", + "tag": "首选", + "stage": 0, + "row": 0, + "height": 36, + "yOffset": -2 + }, + { + "id": "provider", + "type": "backend", + "label": "Data Provider", + "sublabel": "归一化 / 校验 / 审计", + "tag": "MarketDataProvider", + "stage": 0, + "row": 2, + "width": 130, + "height": 36, + "yOffset": -2 + }, + { + "id": "sina", + "type": "external", + "label": "新浪财经", + "sublabel": "缺失兜底 / 交叉验证", + "tag": "备用", + "stage": 0, + "row": 4, + "height": 36, + "yOffset": -2 + }, + { + "id": "sqlite", + "type": "database", + "label": "SQLite", + "sublabel": "股票 / 日历 / 因子定义 / Job", + "tag": "业务库", + "stage": 1, + "row": 0, + "height": 36, + "yOffset": -2 + }, + { + "id": "parquet", + "type": "database", + "label": "Parquet", + "sublabel": "历史行情 / 复权 / 财务时序", + "tag": "时序库", + "stage": 1, + "row": 2, + "height": 36, + "yOffset": -2 + }, + { + "id": "dataset", + "type": "database", + "label": "Qlib Dataset", + "sublabel": "data/qlib 特征集", + "tag": "研究数据", + "stage": 2, + "row": 2, + "height": 36, + "yOffset": -2 + }, + { + "id": "factor", + "type": "backend", + "label": "因子研究", + "sublabel": "Alpha158 / 自定义因子", + "tag": "IC · 分层测试", + "stage": 3, + "row": 0, + "height": 36, + "yOffset": -2 + }, + { + "id": "model", + "type": "backend", + "label": "模型训练", + "sublabel": "LightGBM", + "tag": "预测信号", + "stage": 3, + "row": 2, + "height": 36, + "yOffset": -2 + }, + { + "id": "backtest", + "type": "backend", + "label": "选股回测", + "sublabel": "调仓 / 成本 / 涨跌停 / 停牌", + "tag": "低频策略", + "stage": 4, + "row": 0, + "height": 36, + "yOffset": -2 + }, + { + "id": "experiment", + "type": "database", + "label": "Experiment", + "sublabel": "参数 / 结果 / 数据与代码版本", + "tag": "可复现", + "stage": 4, + "row": 1, + "height": 36, + "yOffset": -2 + }, + { + "id": "api", + "type": "backend", + "label": "FastAPI API", + "sublabel": "业务 API(Pydantic DTO)", + "tag": "REST / SSE", + "stage": 4, + "row": 3, + "height": 36, + "yOffset": -2 + }, + { + "id": "web", + "type": "frontend", + "label": "Web UI", + "sublabel": "Next.js · ECharts", + "tag": "结果可视化", + "stage": 4, + "row": 4, + "height": 36, + "yOffset": -2 + } + ], + "flows": [ + { + "id": "raw-tushare", + "from": "tushare", + "to": "provider", + "label": "行情 / 财务 raw", + "variant": "emphasis" + }, + { + "id": "raw-sina", + "from": "sina", + "to": "provider", + "label": "兜底 raw", + "variant": "dashed" + }, + { + "id": "to-sqlite", + "from": "provider", + "to": "sqlite", + "label": "股票 / 日历 / 元数据", + "labelAt": [ + 212, + 256 + ] + }, + { + "id": "to-parquet", + "from": "provider", + "to": "parquet", + "label": "行情 / 财务时序", + "route": "straight", + "labelAt": [ + 212, + 426 + ] + }, + { + "id": "calendar-to-dataset", + "from": "sqlite", + "to": "dataset", + "label": "交易日历 / 股票池", + "labelAt": [ + 422.5, + 276 + ] + }, + { + "id": "series-to-dataset", + "from": "parquet", + "to": "dataset", + "label": "行情特征输入", + "route": "straight", + "labelAt": [ + 452, + 426 + ] + }, + { + "id": "dataset-to-factor", + "from": "dataset", + "to": "factor", + "label": "特征矩阵", + "variant": "emphasis", + "labelAt": [ + 637.5, + 268 + ] + }, + { + "id": "dataset-to-model", + "from": "dataset", + "to": "model", + "label": "训练 / 预测特征", + "route": "straight", + "labelAt": [ + 610, + 426 + ] + }, + { + "id": "factor-signal", + "from": "factor", + "to": "backtest", + "label": "因子信号" + }, + { + "id": "model-signal", + "from": "model", + "to": "backtest", + "label": "预测信号", + "labelAt": [ + 852.5, + 298 + ] + }, + { + "id": "factor-archive", + "from": "factor", + "to": "experiment", + "label": "因子测试归档", + "fromSide": "top", + "toSide": "right", + "via": [ + [ + 745, + 98 + ], + [ + 1060, + 98 + ], + [ + 1060, + 258 + ] + ], + "labelAt": [ + 1060, + 176 + ] + }, + { + "id": "backtest-archive", + "from": "backtest", + "to": "experiment", + "label": "回测结果归档", + "variant": "emphasis" + }, + { + "id": "query-result", + "from": "experiment", + "to": "api", + "label": "结果查询 DTO" + }, + { + "id": "to-web", + "from": "api", + "to": "web", + "label": "REST / SSE" + } + ], + "cards": [ + { + "dot": "emerald", + "title": "主研究数据流", + "items": [ + "Tushare → Data Provider(归一化 / 校验 / 审计)→ SQLite 与 Parquet 分流", + "Qlib Dataset 汇总日历与行情 → 因子 / 模型 → 回测 → Experiment 全量归档", + "每条拉取记录 source / 行数 / 时间,来源可追溯" + ] + }, + { + "dot": "violet", + "title": "防未来函数口径", + "items": [ + "财务数据区分 report_date / announce_date,仅 announce_date 后可见", + "研究查询一律带 as_of_date,禁止未来成分 / 行业 / 财务数据", + "新浪仅作缺失兜底与交叉验证,禁止静默切换" + ] + }, + { + "dot": "amber", + "title": "结果消费", + "items": [ + "Experiment → FastAPI API → Web UI(REST / SSE)可视化", + "AI Agent(Phase 5)仅经受控 Tool 经 API 读取研究数据与实验", + "历史实验含数据与代码版本,可一键复跑" + ] + } + ] +} \ No newline at end of file