P0/P1/P2 一次性落地:补齐文档、修复 main 挂载/笔误、引入 logging+tests

P0:
- 清理 src/fetchers/sector.py 第 225 行起的旧版残留代码
- 修复 src/fetchers/market_daily.py 中 fetch_history -> _fetch_history 笔误
- 在 src/main.py 挂载 --market-daily 子命令

P1:
- 修正 src/db.py docstring(market_breadth -> market_daily 等)
- requirements.txt 补 baostock;pyproject.toml 同步 + 新增 [dev] extras
- README 增加 config.yaml 安全提示,将 git 历史清理升级为高风险 P0 由用户决策

P2:
- 引入 src/log.py 统一 logging(控制台 + logs/ashare.log 按日滚动 7 天)
- 建立 tests/ 框架,4 个测试文件 / 19 个 pytest 用例全部通过
- pyproject.toml 新增 [tool.pytest.ini_options]
- config.example.yaml 补全 workers 字段与多源说明
- README 更新功能概览/参数说明/表结构/项目结构/设计说明全章节
- TODO.md 全面重写,按 P0/P2 整理剩余条目并附变更日志
- .gitignore 新增 .claude/
This commit is contained in:
曾志威
2026-05-15 13:26:21 +08:00
parent fa31344241
commit dbc8107caa
19 changed files with 655 additions and 201 deletions
+104
View File
@@ -0,0 +1,104 @@
# TODO
本文件用于跟踪 ashare-data 项目的已知问题与后续工作。维护时请保持「问题描述 + 影响范围 + 处理思路」三段式,便于他人接手。
> 🗓️ **2026-05-15 一次性清理**:原 P0 / P1 / P2 中可在不破坏 git 历史的前提下完成的条目已落地(详见底部 [变更日志](#变更日志))。当前剩余条目均为:①需要用户决策的高风险动作,②长期工程任务,③依赖外部数据源调研。
---
## 🔴 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. 写入并发度压测
- **现状**`config.yaml` 默认 `fetch.workers=1``config.example.yaml` 已注明 "多源轮换可适度提高至 2~4"。需通过实测确定 BaoStock 锁、新浪/腾讯/东财限流的安全边界。
- **处理思路**:用 `time pytest` 或专门写一个 `benchmarks/` 脚本,固定一段缺口(如 200 只股票 × 30 天),分别跑 workers=1/2/4/8 比对完成时间和失败率。
### 5. 把现有 `print()` 全面切到 `src.log.get_logger()`
- **现状**`src/log.py` 已就绪并接入了 README "设计说明"**但所有 fetcher 仍在用 `print(..., flush=True)`**,本期保留兼容性未替换。
- **处理思路**:分批替换(建议按文件粒度提 PR),每次替换一个 fetcher 同时把对应日志级别从直觉值改成 INFO/WARNING/ERROR;替换时一并删除 `flush=True`。
### 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。
### 7. 扩展测试覆盖
- **现状**`tests/` 已覆盖 4 个核心纯函数(19 个用例),但 fetcher 主流程和 SQL 聚合仍无测试。
- **处理思路**
- 用 `sqlite::memory:` 跑一遍 `db.init_db()` + `batch_upsert()` 端到端;
- 用 `responses` 库 mock 新浪/腾讯/东方财富 HTTP 接口,覆盖 `_fetch_sina/_fetch_tencent/_fetch_eastmoney`
- 用 `freezegun` 替换手写 `FakeDatetime`
- `market_daily._fetch_history` 的 SQL 阈值(涨停 ≥9.8 / ≥19.5)单测,验证主板/创业板不会互串。
### 8. `sector.fetch_sector` 三种 only 模式的合并保护测试
- **现状**`region_only=True` 时使用 `existing.get("industry")` 保留旧行业值;`industry_only=True` 反之。逻辑正确但无测试。
- **处理思路**:归并到上面第 7 项一起做(需 mock DB session 或用 SQLite)。
---
## 📋 维护节奏建议
- 每次新增 fetcher,请**同步更新** README 的:「功能概览表 / 运行示例 / 命令行参数说明 / 数据库表结构 / 项目结构」 五个章节。
- 每次发现可复现 bug,先把现象写进本文件,再开始改代码,避免漏修。
- 新增代码请用 `from src.log import get_logger`,不要再写 `print(..., flush=True)`。
- 完成的条目移到下方 [变更日志](#变更日志),附完成日期,便于回顾。
---
## 变更日志
### 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 条