← 归档索引 · 2026-10-12 08:42 · 数据底座健康周报AI解读
Cronjob Response: 数据底座健康周报AI解读
(job_id: 4fa4b21225e3)
-------------

# 数据底座健康周报 AI 解读(2026-10-12,窗口 7 天)

> 数据源:`/home/ubuntu/stock/data/call_stats.db`(health_tracker 台账,176,402 条)+ `capability_details.json`(10-12 03:41 探测)+ 本机 DataHub 实测(10-12 08:33)。
> 分析路径:health_report 逐格复算核对 → 按源×类型聚合 → 5 周周环比 → 失败时段聚类 → live 复现根因。
> **判断落账:judgment_ledger #2010(direction=中性,target=数据底座主链,falsify 可脚本核对)。归档 IMA:rc=0,无错误日志。**

---

## 一、先核数(周报数字可信)

直接 SQL 复算 7 日窗口,与 health_report 输出**逐格一致**(mootdx daily 0/157、mx 全 0、tushare daily 467/572、westock daily 1343/1965 等全部对上)。数据不缺,可以照常下结论。

---

## 二、<50% 的源:根因逐个定性

### 🔴 mx:0/73(0%)—— 不是「源死了」,是三类混合,只有 1/3 是真故障
| 子类 | 量 | 根因(实测证据) |
|:--|:-:|:--|
| daily_fallback 39 + daily_realtime 10 | **49** | **设计性拒收(记账噪音)**。`data_hub.py:2020` 注释明写 2026-08-03 起 MX.get_daily 只回 1 行实时快照 → 主动丢弃记 fail。我实测 `hub.mx.get_daily("600519",120)` → 4.4s **返回 1 行**,与注释完全一致。 |
| realtime 9 + realtime_batch 15 | **24** | **真故障**。实测 `hub.mx.get_realtime_batch(["600519"])` → **返回空字典 `{}`**(1.4s,无异常、非配额拒绝);10-11 22:30 另有 5 次连发 **~8s 超时**。两种形态并存 → 间歇性空返回 + 超时。 |
| 账号/配额 | — | **没死**:10-12 03:41 探测 MX 12 项全绿;我 08:33 实测 `finance_data` 1.2s `success=True`。**不是日配额**(配额按日重置,不可能连续 25 天 0 成功)。最后一次成功:**2026-09-17 14:44**。 |

**处置**:① 熔断已开(`breaker_open('mx')=True`),主链已绕开,**当前无实际伤害**,不必抢修;② mx 批量实时接口要么单点排查东财侧,要么直接从路由摘除(实时主链 westock/tushare 已覆盖);③ **探针必须补生产同路径**——见第三节问题①。

### 🔴 mootdx:4/181(2%)—— daily/realtime 是已知协议失效,但 **minutes 不是**
- `mootdx daily 0/157`、`realtime 0/9` = 8/3 quotes/bars 协议失效,已知、熔断已开(`breaker_open('mootdx')=True`),标注正确。
- **`minutes_realtime 3/11(21%)🔴 未被 KNOWN_ISSUES 覆盖,但也不是协议死**:03:41 探测 `minutes: ok=true 240行`;我 08:33 实测 `get_minutes → 240 行`。11 次失败**全部落在 00/07/16 点非交易时段批次**(7+4 次)。
- **根因=时段性空返回**(非交易时段取当日分时拿不到),不是源失效。
- **处置**:分时**主链只有 mootdx 一根**(新浪已禁、westock 无分时)→ 建议加一根兜底(ifind/westock 分时或缓存前一日分时);同时把 minutes 的失败判据按「非交易时段调用」改写,别让它继续冒充 🔥 新故障。

### 🔴 westock daily_fallback:19/155(12%)—— 凌晨时段数据未就绪
- 它**只在 tushare 已失败后**才被调用(`data_hub.py:2006` 前),天然继承主链的失败。
- 24h 内 33 次全失败集中在 **00:00(22 次)+ 01:00(11 次)**;同一时间窗 `westock daily` 自身 **119 fail/118 ok(50%)**、`tushare daily` 01:00 **13 fail/18 ok**。
- 单点实测全通:`get_kline(westock)` 0.8s → **100 行**;`get_daily` 600519 / 000001.SZ / 000001.SH **6/6 全过**。
- **根因=间歇/时段性**(凌晨请求"最新交易日"数据,当日数据未就绪),非协议失效——5 周成功率在 0~31% 间波动、每天都有成功记录。
- **处置**:把凌晨批量挪到 **06:00 以后**,或先用 `trade_calendar` 判断数据就绪日再取;不需要换源。

### 🔴 westock finance:27/139(19%)—— 调用侧标的无报表(确定性记账噪音)
- 每批固定 **8 fail + 2 ok**,5 周稳定在 19~26%,**确定性**(不是网络抖动)。
- 实测:`sh600519 / sz000001 / sh688981 → sections=3`(正常);**`sz832000`、`sz430047`(北交所,prefix 被推断成 `sz`)→ sections=0**;**`sh510300`、`sh512880`(ETF,无三大报表)→ sections=0**。
- **根因=标的清单里含 ETF/北交所标的,westock 三大报表本来就没有**,被记成源失败。
- **处置**:8/15 的 KNOWN_ISSUES 标注「12:22 测试噪音,复测 3/3 正常」**已漂移 5 周**,应改成「标的类型不匹配(BJ/ETF 无报表)」;并在 `_track` 前区分「源失败」与「标的无数据」。

### 🔴 tushare finance:0/112(0%)—— **代码缺陷,1 行可修**(本周唯一确定的可修 bug)
- `data_hub.py:3114`:`ts_code=f"{code}.SZ" if code.startswith(("0","3")) else f"{code}.SH"`
- 传入**已带后缀**的 code → 拼成 `600519.SH.SH` / `000001.SZ.SZ` → 恒为空。
- **对照实测**(同 source="tushare"):裸码 `600519` → **100 行**;带后缀 `600519.SH` → **1 行**(tushare 空,靠末尾 mootdx 兜底捞回 1 行)。
- 所以下游**没断**,但台账必然 0%,且 tushare 财务能力被白白浪费(`fina_indicator` 探针实测 100 行可用)。
- **处置**:`code.split(".")[0]` 再拼后缀;属 C 类(代码缺陷),不是源失效,不该出现在「建议人工检查协议失效」里。

---

## 三、>50% 但本周明显下滑的两根主链(真正要盯的)

| 源/类型 | 本周 | 前4周 | 判读 |
|:--|:-:|:-:|:--|
| tushare daily | **82%** | 99~100% | **首次下滑**;`index` 子类 3 ok/12 fail=20%,但实测 000001.SH 指数日线 30 行 OK → 非系统性 |
| tushare kline | **74%**(**近24h 39 ok/60 fail=39%**) | 92~94% | 失败集中在 10-11 22:00 一批 60 fail/38 ok |
| westock daily | 68%(00:00 批 119 fail/118 ok) | 39~68% 波动 | 失败集中在 00:00 / 01:00 / 12:00 / 08:00 批次窗口 |

**共性**:单点实时调用 **6/6 全通**(日线、指数、K 线、分钟、财务),失败**全部落在批量窗口** → 间歇限流 / 数据未就绪,**不是协议失效**。
**但**:tushare kline 近 24h 已 **39%**,低于 50%。熔断规则是 24h 连续失败≥5 或失败率>50% → **再这样跑 1~2 天会触发熔断,主链掉一根**,这是本周最该盯的指标。

**另**:`wind edb 0/1(search failed: unknown)`——wind 能力表本就为空(未配置),不计故障。

### 系统层三个真问题(比单源成功率更重要)
1. **探针绿 ≠ 链路绿**:`probe_sources.py` 只探 `mx.finance_data`(自然语言路径),生产走 `get_realtime_batch / get_daily`(结构化路径)→ **探针 12 项全绿,生产却 25 天 0 成功**。探针必须覆盖生产同方法。
2. **台账不记错误文本**:`_track` 的 note 只有 dtype/只数,异常信息全丢 → 本周根因全靠我反推 + live 复现。**1 行改动**:把 `str(e)[:80]` 写进 note,下周周报可直接给根因。
3. **KNOWN_ISSUES 标注漂移**:westock finance 8/15 标注「复测 3/3 正常」,实测 5 周 19~26%;mx 已知标注缺 `get_daily` 设计性拒收这一类。

---

## 三行结论

✅ **正常源**:tushare(日线 82% / K 线 74%,单点与指数实测全通)、westock(日线 68% / kline 100%)、**mootdx 分钟线**(实测 240 行)、gf_skills 与 ifind(03:41 探测全绿)、财务单点 6/6 通过 —— 主链可用,判断已落账 #2010。

🔴 **问题源 + 根因**:mx=批量实时接口返回 `{}` 空 + 间歇 8s 超时(**账号没死**,探针绿/生产死,另 49 次是设计性拒收);tushare finance 0/112=**代码双后缀 bug**(`data_hub.py:3114`);westock finance 19%=北交所/ETF 无报表的记账噪音;mootdx daily/realtime=8/3 协议失效(已知,熔断已开);westock daily_fallback 12%=00-01 点数据未就绪。

⏭ **下一步(按优先级)**:① 修 `data_hub.py:3114` 双后缀(1 行,tushare 财务 0%→100%);② 探针补 `get_realtime_batch/get_daily` 生产同路径;③ `_track` 写入 `str(e)` 异常文本;④ 凌晨批量挪到 06:00 后;⑤ **盯 tushare kline 24h 成功率(现 39%),连续 2 天 <60% 即熔断告警**——那是主链掉一根的临界点。

To stop or manage this job, send me a new message (e.g. "stop reminder 数据底座健康周报AI解读").