Files
ashare-data/TODO.md
T
2026-05-17 15:51:10 +08:00

190 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TODO
本文件用于跟踪 ashare-data 项目的已知问题与后续工作。维护时请保持「问题描述 + 影响范围 + 处理思路」三段式,便于他人接手。
> 🗓️ **2026-05-15 二轮清理**:上一轮(也是 2026-05-15)清理后剩下的 P2 中,可独立完成的 #4/#5/#7/#8 已落地(详见底部 [变更日志](#变更日志))。
> 当前剩余条目均为:①需要用户决策的高风险动作(P0),②依赖外部数据源调研(P2-北交所),③需要与主项目协调的可选合并(P2-财务结构化、P2-gzl 接入)。
> 📚 **本文件分两部分**:上半部分是**已知缺陷/技术债**(P0/P2),下半部分是**新功能路线图**([Roadmap](#-新功能路线图-roadmap))。前者修,后者建。
---
## 🔴 P0 — 需用户授权的高风险动作
### 1. 清理 git 历史中的明文密码 ⚠️ 高风险
- **现状**`config.yaml` 现已在 `.gitignore` 中(仓库根 `.gitignore` 第 2 行),但**历史 commit `e2c3b41` / `feef7b6` / `217b12c` 中曾以明文形式提交过**
```
password: "ttx2011"
host: "db.freeicu.top"
port: 32000
```
任何能访问本仓库的人都能通过 `git show e2c3b41:config.yaml` 取到这段凭据。
- **影响**:数据库密码事实上已经泄露;如仓库已 push 到远端(包括 fork/克隆),轮换密码是**唯一彻底方案**。
- **处理思路**(需用户确认后才能执行):
1. **立即**在 MySQL 侧轮换 `root@db.freeicu.top:32000` 的密码;
2. (可选)用 `git filter-repo --path config.yaml --invert-paths` 或 BFG Repo-Cleaner 重写历史:
```bash
git filter-repo --path config.yaml --invert-paths
git push --force --all # ⚠️ 破坏所有协作者的本地副本,需团队周知
git push --force --tags
```
3. 让所有协作者**重新克隆**仓库(旧 clone 的 reflog 仍含明文)。
4. 如已公开过(GitHub/GitLab),还需手动让对应平台清理缓存(GitHub 联系 support@github.com,或新建仓库迁移)。
- ❗ 这一步会**改写所有 commit 哈希**,等同于强制变基整个历史,必须由仓库所有者亲自决定并在低峰期执行。请回复后再操作。
---
## 🟢 P2 — 长期工程 & 调研
### 2. 北交所(920xxx)数据支持
- **现状**:BaoStock、新浪、腾讯、东方财富的 K 线接口均不支持北交所;当前在 `daily.py / sector.py / stock_list.py` 中显式跳过 `920xxx`。
- **处理思路**:调研同花顺 / 雪球 / Wind Quant 等接口;若可,新增独立 fetcher 并合并到主流程。预计需要新增一张 `bj_daily` 表或在 `stock_daily` 中加 market 列。
### 3. 财务数据「JSON 存 TEXT」结构化拆分
- **现状**`stock_financial_income/balance/cashflow` 仅有 `code/report_date/data(JSON)` 三列,下游查询需 `JSON_EXTRACT`,难做索引。
- **处理思路**:根据下游真实查询场景(量化筛选 vs 财报展示),把高频指标(ROE、净利润、资产负债率、经营性现金流等)拆出独立列;保留 `extra_json` 兜底。需配套写数据迁移脚本。
### 4. 并发度压测:跑出实测数据
- **现状**`benchmarks/bench_daily.py` 已就绪,可一键跑 `workers=1/2/4/8` 对照(详见 `benchmarks/README.md`)。
- **下一步**:在低峰期跑一次完整压测,把推荐档位写到 `config.example.yaml` 注释里。脚本已自带 speedup 表输出,无需再写采集代码。
### 6. `gzl/` 选股脚本接入主项目
- **现状**`gzl/Selector.py` + `gzl/select_stock.py` 读本地 CSV(不读 MySQL),与 `src/` 完全解耦,依赖 `scipy`。README 已说明其独立性。
- **处理思路**
1. 评估是否纳入主项目 — 如果只是个人玩具脚本可保持现状;
2. 若纳入,迁移到 `src/strategies/`、改读 MySQL、复用 `get_session()` / `batch_upsert()` / `get_logger()`
3. `scipy` 加入 `pyproject.toml` 的 optional `[strategies]` extras。
---
## 🚀 新功能路线图 (Roadmap)
> 这一节是「想做但还没排期」的需求池,与上面的 P0/P2(已知缺陷/技术债)分开维护。
> 立项时把对应条目挪到 P1/P2,附上责任人和预计动手时间;落地后再移到 [变更日志](#变更日志)。
### ⭐ 推荐下一迭代(按"价值高 / 成本可控 / 与现有架构契合"排序)
1. **抓取调度 + 告警**(详见下方「四、调度与监控」#1+#2)— 让项目从工具变服务,半天工作量
2. **HTTP API 服务**(「三、服务化」#1)— FastAPI 暴露查询接口,半到一天
3. **资金面三件套:龙虎榜 / 北向资金 / 融资融券**(「一、数据维度扩展」前 3 条)— 接口现成、量小,2-3 天补齐情绪+资金维度
---
### 一、数据维度扩展
「价值」= 对量化/选股的直接增益,「成本」= 实现规模 + 外部依赖复杂度。
| # | 需求 | 价值 | 成本 | 关键说明 |
|---|---|---|---|---|
| 1 | **龙虎榜** | 高 | 中 | 东财/同花顺接口稳定;游资/机构席位是短线核心信号 |
| 2 | **北向资金(陆股通)持股明细** | 高 | 低 | 港交所/东财 T+1 披露;新增 `hk_holdings` 表 |
| 3 | **融资融券余额** | 高 | 低 | 流动性/情绪指标,东财/交易所每日发布 |
| 4 | **业绩预告 / 快报** | 高 | 中 | 早于正式财报,常含异常波动信息;BaoStock 无,需走东财/同花顺 |
| 5 | **限售解禁日历** | 中 | 低 | 解禁前后股价波动显著;东财日历接口 |
| 6 | **股东户数** | 中 | 低 | 季频,反映筹码集中度;BaoStock `query_stock_other_basic_info` |
| 7 | **十大流通股东** | 中 | 中 | 季频跟踪机构持仓;BaoStock 有现成接口 |
| 8 | **大宗交易** | 中 | 中 | 折溢价 + 营业部,事件驱动 |
| 9 | **ST 标记历史** | 中 | 中 | 当前无连续 ST 状态记录,无法回测「摘帽行情」 |
| 10 | **IPO / 定增 / 可转债日历** | 中 | 中 | 一级市场事件 |
| 11 | **ETF 行情 + 折溢价** | 中 | 中 | 套利策略基础数据 |
| 12 | **股指期货 IF/IH/IC/IM** | 中 | 中 | 对冲/基差研究 |
| 13 | **期权行情**50/300/500ETF | 中 | 高 | 波动率研究 |
| 14 | **L1 Tick 行情** | 高 | 极高 | 数据量爆炸(GB/日),需切 ClickHouse / Parquet |
| 15 | **公司公告全文** | 高 | 高 | 需 PDF/HTML 解析 + 全文检索(ES |
| 16 | **研报 / 一致预期** | 高 | 高 | 多家券商接口闭源,合规风险 |
| 17 | **北交所(920xxx** | 中 | 中 | 已在上方 P2-#2 单列 |
### 二、数据加工层(让"数据"变"信号"
| # | 需求 | 价值 | 关键说明 |
|---|---|---|---|
| 1 | **后复权日线 + 周/月线聚合表** | 高 | 现仅有前复权;后复权用于长期收益对比 |
| 2 | **技术指标预计算**MA/MACD/RSI/BOLL/KDJ | 中 | 一次算多次用 |
| 3 | **因子库**(动量/反转/价值/质量/规模/波动率) | 高 | 量化必备;每日预计算入 `factor_daily` 宽表 |
| 4 | **数据质量校验日报** | 高 | 每日跑:股票数、缺口、异常涨跌幅、停牌识别;失败发告警 |
| 5 | **多源交叉校验** | 中 | BaoStock vs 新浪同日 close 偏差 >1% 自动报警 |
### 三、服务化(让数据被消费)
| # | 需求 | 价值 | 关键说明 |
|---|---|---|---|
| 1 | **HTTP API 服务**FastAPI | 高 | 暴露 `/daily` `/financial` `/sector` 等 REST;前端/其他系统可直接消费 |
| 2 | **Python SDK 包装** | 中 | `from ashare import get_daily`,屏蔽 SQL |
| 3 | **Parquet / Feather 导出** | 中 | 量化研究跑数据更快;增量导出到本地或 S3/OSS |
| 4 | **Kafka / ClickHouse 同步** | 中 | 接入下游量化平台时再考虑 |
| 5 | **CLI 查询子命令** | 低 | `ashare query --code 600000 --metric pe-ttm` |
### 四、调度与监控(手动 → 自动)
| # | 需求 | 价值 | 关键说明 |
|---|---|---|---|
| 1 | **抓取任务调度**APScheduler 或 cron + systemd | 高 | 当前依赖手动 `python -m src.main --daily`;自动化后无人值守 |
| 2 | **失败告警**(企微/钉钉/邮件 webhook) | 高 | 配合 #1;失败/延迟超阈值即推送 |
| 3 | **Prometheus metrics 导出** | 中 | 各 fetcher 耗时/成功率/失败码;接 Grafana |
| 4 | **数据完整性 dashboard**Grafana / Superset | 中 | 直观看股票覆盖、缺口、最新数据日期 |
### 五、选股 / 策略(承接 gzl)
| # | 需求 | 价值 | 关键说明 |
|---|---|---|---|
| 1 | **gzl 接入主项目** | 中 | P2-#6 已列;改读 MySQL,统一日志/连接池 |
| 2 | **策略插件框架** | 高 | `src/strategies/` 下每策略一文件,统一 `run(date) -> List[Signal]` 接口 |
| 3 | **简单回测引擎** | 高 | 基于已有日线表,单策略 N 年回测,输出收益/最大回撤/胜率 |
| 4 | **选股信号定时输出** | 中 | 每日盘后跑所有策略,结果入 `signal_daily` 表或推送 |
| 5 | **事件驱动信号库** | 中 | 涨停回封、放量突破、底背离、机构席位上榜 |
### 六、工程基础(质量护栏)
| # | 需求 | 价值 | 关键说明 |
|---|---|---|---|
| 1 | **GitHub Actions CI** | 高 | 自动跑 pytestPR 必须绿;成本极低 |
| 2 | **Alembic 数据库迁移** | 中 | 替代 `db.py` 中手写的 `DROP TABLE`+`create_all`,版本可控 |
| 3 | **Docker + docker-compose** | 中 | 自带 MySQL,新机器一行命令起;适合给协作者 |
| 4 | **类型注解全量 + mypy strict** | 中 | 现部分函数已有;走全量后 IDE/重构体验显著提升 |
| 5 | **ruff / pre-commit hook** | 低 | 统一格式;低争议低成本 |
| 6 | **PostgreSQL / SQLite 后端兼容** | 中 | 现 `batch_upsert` 写死 MySQL 方言;抽象后可本地 SQLite 跑端到端测试 |
| 7 | **Web 控制台**Streamlit) | 低 | 简单看板:抓取状态、最新日期、表行数;非必需 |
---
## 📋 维护节奏建议
- 每次新增 fetcher,请**同步更新** README 的:「功能概览表 / 运行示例 / 命令行参数说明 / 数据库表结构 / 项目结构」 五个章节。
- 每次发现可复现 bug,先把现象写进本文件,再开始改代码,避免漏修。
- 新增代码请用 `from src.log import get_logger`,不要再写 `print(..., flush=True)`。
- 完成的条目移到下方 [变更日志](#变更日志),附完成日期,便于回顾。
- **路线图条目立项时**:从 [Roadmap](#-新功能路线图-roadmap) 挪到 P1/P2,附责任人 + 预计动手时间;落地后再移到变更日志。
---
## 变更日志
### 2026-05-15(第二轮)
- ✅ **P2-#5 print → logger 全面替换**`src/baostock_conn.py`、`src/db.py`、`src/main.py` 与全部 9 个 fetcher 中的 72 处 `print(..., flush=True)` 已切到 `from src.log import get_logger`,按语义选 INFO/WARNING/ERRORBaoStock 查询签名打 DEBUG,避免控制台被刷屏
- ✅ **P2-#7 扩展测试覆盖**:测试用例从 19 → 43。新增
- `test_log.py`(5 例:命名空间、handler 幂等、不冒泡、env 控制 level、未知 level 回退)
- `test_daily_source_codes.py`8 例:sina/tencent/eastmoney 代码前缀映射)
- `test_daily_sources_http.py`8 例:腾讯/东财 HTTP JSON 解析,含空字段、异常包装、北交所短路)
- ✅ **P2-#8 sector 三种 only 模式合并保护**`test_sector_merge.py`3 例:region_only 保留 industry / industry_only 保留 region / concept_only 不触碰 stock_sector
- ✅ **P2-#4 并发压测脚本骨架**:`benchmarks/bench_daily.py` + `benchmarks/README.md`,可一键跑 `workers=1,2,4,8` 对照,输出 speedup 表;剩下的就是用户在低峰期跑一次实测
### 2026-05-15(第一轮)
- ✅ `src/main.py` 新增 `--market-daily` 参数,挂载 `fetch_market_daily`market_daily 只读 stock_daily,无需 BaoStock 登录)
- ✅ `src/fetchers/market_daily.py` 修复 `fetch_history` → `_fetch_history` 笔误
- ✅ `src/fetchers/sector.py` 清理第 225 行起的重复 import + 旧版函数残留
- ✅ `src/db.py` 顶部 docstring 修正 `market_breadth` → `market_daily`,并补全 index_daily / stock_concept / 分钟K线分表
- ✅ `requirements.txt` 增加 `baostock``pyproject.toml` 同步并新增 `[dev]` extras
- ✅ `config.yaml` 历史明文密码问题:已在 README 加显眼 ⚠️ 安全提示;具体 git 历史清理与密码轮换升级为 P0-1 由用户决策
- ✅ 引入 `src/log.py` 统一 logging(控制台 + `logs/ashare.log` 按日滚动 7 天保留,`ASHARE_LOG_LEVEL` 可调)
- ✅ 建立 `tests/` 框架:4 个测试文件、19 个 pytest 用例全部通过(覆盖 `code_to_bs`、`_fill_derived_fields`、`_recent_quarters`、`_is_20pct`
- ✅ `pyproject.toml` 添加 `[tool.pytest.ini_options]``pytest` 可一键运行
- ✅ `config.example.yaml` 补全 `workers` 字段与多源说明
- ✅ README 增加「运行测试」「选股子项目 gzl/」两节,"设计说明" 加 logging 条