lzf_0626
02ba1befc0
feat(data): 取真实费率并回填 fin_product;发现 510300 的身份问题
## 取费率
项目原有的行情适配器只有 names/quotes/history,没有费率。东财也没有可用的 JSON 接口
(`FundArchivesDatas.aspx?type=jjfl` 实测正文只有一句 `var apidata=`),
所以给 EastmoneyFundAdapter 加了 fetch_fees:抓 f10 基金概况页
(fundf10.eastmoney.com/jbgk_{code}.html)去标签后匹配字段名,取管理费/托管费/
销售服务费/申赎费,并顺带带回基金全称。取不到的基金不进返回(而不是给全 None),
免得调用方把"没抓到"当成"该基金确实没有费率"。
实测 20/20 全部取到。
## 回填
新增 tools/backfill_product_fees.py,默认 dry-run、默认只补 NULL:
- 只补空值:写入 38 个字段(19 只 × 管理费/托管费),已执行
- 已有值一律不动 —— `510300` 库里的 0.5000/0.1000 保持原样,要改需显式 --overwrite
- 写入走单事务
回填前 grep 确认:`fin_product.management_fee_rate` / `custodian_fee_rate`
**目前没有任何业务代码读取**(advisor 域那两个 fee 字段属于另一张表
advisor_product_contract),所以这次回填不改变任何现有行为。
要让客户真的看到费率,还需要接口与前端读它 —— 那不在本次范围。
## 两个数据问题(都指向 510300)
1) **它不是南方基金的产品**。数据源返回的基金全称是
「华泰柏瑞沪深300交易型开放式指数证券投资基金」,而库里 fund_manager 写「南方基金」。
其余 19 只全称都是"南方…"开头,只有它例外。
影响面不只是知识库:MarketQuoteSyncService 按 fund_manager='南方基金' 筛选同步对象,
所以它会被当成自家产品一起同步、一起展示。
2) **它的费率是照抄的**。库里 0.5000/0.1000,真实 0.15/0.05;而 0.50/0.10 恰好是
159329/159382/159511/588890 这四只的真实费率。结合它的净值快照时间是当天
(其余 19 只停在 09-11)、净值取整数 4.500000,判断是演示用途的人为设定。
这两条都由用户决定怎么处理,本次只记录、不擅自改(510300 的 fund_manager、净值、费率
三处原值都没动)。
## 其他
- tools/fetch_live_quotes.py 增加费率核对段落与 --no-fees(费率要串行抓 45KB/只,较慢)
- docs/42 用真实费率重写 1.2 节与新增 4.3 真实费率清单,3.1 节标出 510300 的身份问题
- docs/42 的数据缺口表更新:费率不再是缺口
门禁:ruff 通过 / mypy 249 文件 0 错 / 单元+契约 1377 passed 2 skipped。
2026-09-13 19:39:16 +08:00
..
2026-09-12 12:10:10 +08:00
2026-09-12 14:57:17 +08:00
2026-09-10 20:33:13 +08:00
2026-09-11 16:57:47 +08:00
2026-09-11 17:26:18 +08:00
2026-09-13 19:39:16 +08:00
2026-09-12 14:40:53 +08:00
2026-09-10 22:29:23 +08:00
2026-09-10 22:42:17 +08:00
2026-09-12 12:20:01 +08:00
2026-09-12 12:57:16 +08:00
2026-09-12 15:21:34 +08:00
2026-09-12 14:43:05 +08:00
2026-09-10 20:15:09 +08:00
2026-09-12 15:21:34 +08:00
2026-09-10 20:29:12 +08:00
2026-09-11 16:57:47 +08:00
2026-09-11 10:13:48 +08:00
2026-09-13 19:39:16 +08:00
2026-09-10 17:11:52 +08:00
2026-09-11 16:57:47 +08:00
2026-09-11 16:57:47 +08:00
2026-09-10 18:14:03 +08:00
2026-09-12 15:37:36 +08:00
2026-09-12 12:09:55 +08:00
2026-09-12 15:21:34 +08:00
2026-09-12 14:43:05 +08:00
2026-09-11 12:47:01 +08:00
2026-09-11 14:46:40 +08:00
2026-09-11 21:03:58 +08:00
2026-09-11 21:03:58 +08:00
2026-09-09 21:55:37 +08:00
2026-09-12 12:20:01 +08:00
2026-09-10 20:22:53 +08:00
2026-09-10 22:34:20 +08:00
2026-09-12 10:34:28 +08:00
2026-09-11 16:57:47 +08:00
2026-09-11 16:57:47 +08:00
2026-09-12 10:45:40 +08:00
2026-09-09 21:55:37 +08:00
2026-09-09 21:55:37 +08:00
2026-09-13 16:20:39 +08:00
2026-09-11 20:30:27 +08:00
2026-09-11 14:24:45 +08:00
2026-09-11 16:51:52 +08:00
2026-09-11 16:51:52 +08:00
2026-09-11 14:19:05 +08:00
2026-09-11 16:28:19 +08:00
2026-09-12 14:40:53 +08:00
2026-09-13 19:17:56 +08:00
2026-09-13 18:54:09 +08:00
2026-09-11 10:13:48 +08:00
2026-09-11 19:51:44 +08:00
2026-09-11 16:40:15 +08:00
2026-09-11 14:46:40 +08:00
2026-09-10 21:36:23 +08:00
2026-09-10 21:55:03 +08:00
2026-09-11 15:25:45 +08:00
2026-09-11 15:25:45 +08:00
2026-09-11 17:26:18 +08:00
2026-09-11 16:57:47 +08:00
2026-09-12 10:34:28 +08:00
2026-09-11 14:46:40 +08:00
2026-09-11 14:46:40 +08:00
2026-09-12 14:43:05 +08:00
2026-09-11 12:54:51 +08:00
2026-09-13 15:56:54 +08:00
2026-09-13 16:19:54 +08:00
2026-09-12 14:43:05 +08:00
2026-09-11 14:46:40 +08:00
2026-09-12 10:45:40 +08:00
2026-09-11 16:57:47 +08:00
2026-09-12 12:10:10 +08:00
2026-09-11 19:51:51 +08:00
2026-09-11 21:03:58 +08:00
2026-09-11 13:05:33 +08:00
2026-09-11 10:27:29 +08:00
2026-09-11 16:57:47 +08:00