# Thermometer: 行为 × 估值 双维度 + max/min 阈值不对称 + 资金流强度第4维度 (verified 2026-08-14)

Context: user noted 18顶 and 21顶 were invisible on the behavior-only thermometer but
clearly shown by their 5-ave valuation score. Diagnosis + quantified fix below.
Then user proposed signed turnover (涨正跌负); tested, rejected as replacement but its
magnitude-weighted variant (资金流强度) accepted as an independent 4th behavioral dimension.

## 1. Two dimensions — complementary, NOT overlapping

温度计三指标 (换手率/杠杆率/上涨家数广度) are all **行为热度** (how frenzied trading is).
5-ave is pure **估值** (EP, 股权风险溢价 e_ratio, 股债利差 e_dif, PE, PE×利率 p_ratio).
They catch different tops. Anchor readings (行为温度 / 5-ave估值评分):

| 时点 | 行为温度 | 5-ave估值 |
|---|---|---|
| 15顶 2015-06-12 | 100 | 100 |
| **18顶 2018-01-26** | 30 | **99** |
| **21顶 2021-02-18** | 39 | **99** |
| 16熔断底 2016-01-27 | 65 | 12 |
| 18熊底 2018-10-19 | 2 | 33 |
| 19熊底 2019-01-04 | 0 | 17 |
| 22底 2022-10-31 | 48 | 1 |
| 24低点 2024-02-05 | 30 | 8 |
| 24顶 2024-10-08 | 55 | 57 |
| 当前 2026-08-12 | 94 | 51 |

Patterns:
- **15顶 = 双疯** (行为+估值 both extreme) — both dimensions light up.
- **18顶 / 21顶 = 纯估值抱团顶** (PE ~17.4 but 散户没疯/杠杆没爆/广度不高).
  Behavior thermometer structurally cannot see them; valuation catches them.
- **当前 = 行为热 + 估值温和** (PE 14.4, 10Y 1.7% keeps 估值分位 low).

5-ave formula: quant_update.py `compute_scores()` branch `'5-ave'` =
mean(ep_score, e_ratio_score, e_dif_score, pe_score, p_ratio_score), then re-percentiled
(norm_factor). Inputs: hs300/data/{hs300_pe.csv, gbond_10y.csv, hs300_close.csv}.

## 2. ⚠️ max/min threshold asymmetry (the "牛市误报/熊市警告不足" question)

Naive composite `max(行为,估值)` is asymmetric: it over-fires red and starves green.

### Red side — max(行为,估值)≥90
- Days: 行为≥90 = 294 → max≥90 = 482 (+188, ALL valuation-driven).
- Those +188 days are "early warnings" pointing at REAL tops (18顶, 21顶) with
  +8~20% upside still remaining after the alert:
  - 2017-08~12 估值红点 → 18顶 still +8~14% away (~3 mo early).
  - 2020-10~2021-03 估值红点 (估值首破90 @ 2020-10-12 HS300=4823) → 21顶 (2021-02-10 HS300=5808)
    still +16~20% away (~4 mo early). 估值≥90 held 101 days.
- Interpretation: valuation measures "贵不贵" not "何时跌" — it leads tops by 2-4 months.
  Correct as "risk zone / stop adding", premature as "immediate exit". Not a false alarm.

### Green side — max≤10 collapses (the failure)
- Days: 行为≤10 = 293 | **max≤10 = 6** | min≤10 = 319.
- Reason: bear bottoms = frozen behavior + MEDIAN valuation, so max never drops low enough.
  Bottom coverage under max (行为/估值/max/min):
  - 16熔断底 64/19 → max=64, NO green
  - 18熊底 2/33 → max=33, NO green
  - 19熊底 0/17 → max=17, NO green
  - 22底 47/11 → max=47, NO green
  - 24低点 30/8 → max=30, NO green
  All five historical bottoms get ZERO green dots under max = the "熊市警告不足" failure.
- min≤10 = 319 days covers 18熊底(min=2), 19熊底(0), 24低点(8), 22底(11, 差1点).

### Correct aggregator — asymmetric by design
- **Red dot = max(行为,估值) ≥ 90** — risk uses OR logic: 估值贵 OR 行为疯 → danger.
- **Green dot = min(行为,估值) ≤ 10** — opportunity uses OR logic: 行为冰冻 OR 估值便宜 → chance.
This renders BOTH the 18顶/21顶 估值过热段 (red) AND the bear bottoms (green).

## 3. ⚠️ 符号换手率方案被否决 + 资金流强度第4维度被采纳 (2026-08-14, v10)

User idea: "上涨的换手率记正、下跌记负，平滑后算百分位". Tested before answering.

### 符号版（方向版，乘sign）— REJECTED as turnover replacement
- 与沪深300 MA20动量百分位相关系数 **0.654**（普通换手率仅0.115）。加符号后指标变成
  "净需求/动量"，与上涨家数占比高度冗余，丢失换手率独有的活跃度信息。
- 引发新误报：熊市反弹冲高位（20疫情反弹峰95%、24年2月反弹峰89%）——反弹本就涨多跌少。
- 结论：**不替换换手率**。

### 幅度加权版（资金流强度 = 换手率×涨跌幅×100）— ACCEPTED as independent 4th dimension
- 公式：`flow = amount_to_mv * pct_change * 100`，涨正跌负、按涨跌幅力度加权；
  `flow_ma20 = flow.rolling(20).mean()`，再全量rank(pct=True)*100。
  思路同源 Chaikin Money Flow / A股"主力资金净流入"。
- 4指标行为温度 vs 3指标 全顶底回测（差异=4指标-3指标）：
  - 24顶(924脉冲) 55→**76**（资金流分位100）✓ 脉冲顶识别大幅改善
  - 21顶 39→55；18顶 30→49；15顶 100→100
  - 15股灾降温：7/3 行为温度 75→54，崩盘后降温快一周 ✓
  - 16熔断底 65→43（恐慌底误报减轻）；22底 48→27
  - 当前 94→87（资金流仅37分位）
  - 代价：熊反弹读数推高（20疫情反弹64→78、24年2月反弹57→73），但均<90不触发红点
  - 红绿点总天数不变（296红/295绿）
- 资金流强度独特价值读数：16熔断底1%（恐慌崩盘全场最准）、15股灾前段0%、24顶100%、
  当前37%（与换手率86%背离 = 高活跃但无单边进攻力度 = 高位震荡换手形态）。
- **作为独立面板加入，不替换换手率**——五指标各自携带独立信息是设计原则：
  换手率=活跃度(与方向无关)、杠杆率=资金密度(存量慢变量)、广度=方向广度、
  资金流强度=成交力度方向、估值=贵贱。

### v10 最终结构（market_temperature_v2.py, 7面板）
1. 全市场换手率（MA20+百分位右轴）
2. 两融杠杆率（+百分位右轴）
3. 市场广度（MA20+百分位右轴）
4. **资金流强度**（青色，含零轴，MA20+百分位右轴）
5. 估值温度（5-ave）
6. 行为温度(4指标) vs 估值温度
7. 沪深300 红绿点（红=max(行为,估值)≥90，绿=min(行为,估值)≤10）

当前读数(2026-08-12)：行为温度87（3指标版94，资金流37分位拉低）、估值温度49、
沪深300=4691。形态=行为热+估值温和，与15顶"双疯"、21顶"纯估值贵"均不同。

## 4. Methodology rules
- Before concluding "dimension X is redundant with Y": quantify correlation AND the
  divergence cases (指数-广度差 at each top), don't argue verbally.
- Before choosing a composite aggregator (max/min/mean/weighted): backtest the threshold
  at ALL key dates in BOTH directions — tops AND bottoms. Testing only tops picks max;
  testing only bottoms picks min; you need the asymmetry.
- Valuation-based alarms lead price tops by 2-4 months; frame them as risk-zone warnings,
  not exit signals, or the user will (correctly) call them "误报".
- When user proposes an indicator transform: construct it → measure correlation with
  existing indicators (redundancy check) → full top/bottom backtest → report cost AND
  benefit → let user decide add/replace/drop. Never implement or reject without data.

## 5. ⚠️ v11 — 统一沪深300视角 + 纯AND双确认被数据否决 (2026-08-15)

User directives (supersede the v10 full-market structure above):
1. **杠杆率用全市场两融作为HS300代理**（tushare无HS300成分两融拆分，全市场是唯一代理；面板标题须标注"全市场代理"）。
2. **删除全市场行为温度维度**——整个温度计统一为沪深300视角。理由：HS300是标的指数，全市场指标被中小盘稀释看不见抱团顶（18顶全市场行为仅48，HS300视角87）。
3. 行为+估值双维度都从沪深300角度。

行为温度(沪深300视角) = 4指标MA20百分位均值再二次百分位：
HS300官方换手率(index_dailybasic 000300.SH) / 两融杠杆率(全市场代理) / Top300广度 /
**HS300资金流强度 = HS300换手率×HS300涨跌幅**。
HS300资金流强度加入的增益：21顶 85→88、16熔断底 26→12、22底 8→4、当前 88→81（更保守——高换手但资金流分位低=缺单边力度）。

### ⚠️ 纯AND双确认被实测否决（用户提议"估值和行为双确认而不是min/max"）
- **AND红**（行为≥90且估值≥90；第二维阈值放宽到70/50结果相同）顶命中仅 **1/4**——
  18顶/21顶行为只有48/55，永远到不了阈值，**抱团顶对AND结构性不可见**（深红只点亮15顶59天）。
- **AND绿**（双≤10）只有56天，但全是最优质投降底：2014-05 / 2018-12~2019-01 / 2022-10 / 2024-09；
  恐慌底（16熔断底行为43、22底行为27）行为不冰冻，AND绿抓不到。
- **最终 = 双维度对称三级体系**：AND作最高置信级（深红/深绿），XOR恰好1维作广覆盖级（橙红/浅绿）：
  `hot_orange = (behav>=90) ^ (val>=90)`，`cold_light = (behav<=10) ^ (val<=10)`。
- 教训：AND与OR各有结构性盲区时，用"AND=高置信、OR=广覆盖"的分层，不二选一。

### v11 验证读数（行为/估值）
15顶 100/100深红 | 18顶 87/99橙红 | 21顶 83/99橙红 | 24顶 79/57无(脉冲,正确不报) |
16熔断底 34/12无 | 18熊底 11/32无 | 19熊底 0/7深绿 | 22底 13/1浅绿 | 24低点 41/0浅绿 |
当前(2026-08-12) 83/51无标记。HS300视角下18/21顶行为维度从48/55（全市场口径）升到87/83，距90仅3-7点。

### v11 面板结构（market_temperature_v2.py, 7面板）
HS300换手率 / 两融代理杠杆率 / Top300广度 / HS300资金流强度 / 行为温度 / 估值温度 /
沪深300三级红绿点。⚠️ 估值曲线曾同时画在行为温度面板和估值面板两处，被用户指出冗余后拆开——每个温度各占一个面板，不重复画。

### 方法论补充
- 用户提出新口径（如AND双确认）时，先跑**顶底命中率矩阵**（多阈值变体 × 顶命中数/底命中数）再定，不口头采纳或拒绝。
- 面板去重原则：同一曲线不在两个面板重复出现；新面板取代旧面板时主动提议删除旧的。

## 6. ⚠️ v12 — 杠杆率口径重构 + margin交易所完整性bug + MA统一 + MA扫描 (2026-08-15)

用户质疑杠杆维度"有没有不合理或漏洞"。诊断出旧口径（融资余额/全市场流通市值）三个结构性漏洞，随后用户提议"两融余额和沪深300总市值比"，最终定为**两融余额/沪深300流通市值**。

### 旧口径三个漏洞（诊断方法可复用：任何"余额÷市值"比值都适用）
1. **分母膨胀**：流通市值10年膨胀1.74倍（57→100万亿），同样杠杆规模读数被稀释。验证：当前融资余额2.65万亿放回2015年市值口径=4.61%，实际显示2.65%，低估约2个百分点。
2. **市值崩塌假象**：2015-07-03"历史峰值"4.71%是假象——融资余额在下降（2.22→1.91万亿）但市值崩得更快（57→40万亿），分母缩小推高比值。它污染全量百分位基准。诊断：查峰值日分子是否真在涨。
3. **全量百分位被2015锚定**：前5%高杠杆日140天集中在2015年；当前融资余额已是历史最高（2026-06曾3.01万亿）但比值口径只显示87分位。

### 新口径验证（两融余额/HS300流通市值，MA20后全量百分位）
- 流通市值 vs 总市值分母：两者百分位几乎一致（沪深300流通/总市值比长期稳定~77%，百分位对比值缩放不敏感）——分母选哪个不影响信号排序，流通市值与旧口径概念衔接更好，最终采用。
- 新口径锚定读数：15顶7.39%(pct99) | 15股灾8.18%(100) | 16熔断底5.22%(92,滞后假象:市值先崩两融没来得及平仓) | 18顶3.75%(20) | 21顶3.95%(41) | 22底4.83%(73) | 24低点4.34%(77) | 924行情3.72%(24) | 当前5.11%(87)。
- 三个漏洞在新口径下依然存在（崩溃假象峰值8.47%@2015-06-19、流通市值膨胀1.73倍）——接受，因杠杆只是四维之一，单维假象被其他三维稀释。
- 融券占比仅~1.2%，两融≈融资。

### ⚠️ margin接口交易所完整性bug（必须防）
tushare `margin` 最近一个交易日经常只返回部分交易所（2026-08-14只有上交所1家，正常3家SSE/SZSE/BSE）→ 两融余额被腰斩（显示2.62%而非5.11%）。**修复**：`groupby(date).agg(rzrqye=('rzrqye','sum'), n_exch=('exchange_id','count'))`，剔除 `n_exch < 2` 的日期（用≥2而非==3，因2021年前北交所未开只有2家）。**规则：任何按交易所分行的tushare接口（margin/fund_share等），合计前必须校验当日交易所数量完整。**

### MA窗口统一 + MA扫描（用户:"四个维度用统一的ma数值 顺便看看ma多少能把18顶双确认"）
- **统一MA**：四维度必须用同一MA窗口。此前杠杆率用原始值、其他三维MA20，口径不一致——已统一为MA20。
- **MA扫描结论：没有任何MA能让18顶双确认**。四维度全统一同一MA，扫MA5~100：MA5行为89(最接近差1点)、MA10=87、MA20=88、MA30=82、MA60=77、MA100=64（MA越长越平滑掉脉冲）。
- **根因（分量拆解）**：18顶当天四分量(MA20)=换手75/杠杆41/广度90/资金流90——**杠杆率只有41分位**死死拖住均值。2018是机构/外资抱团顶，散户两融在2015股灾后一直低迷没起来。21顶同型。
- **结论**：18/21顶天生是"估值单边顶"，正确标签就是🟠橙红而非🔴深红。深红=杠杆+估值双疯的真顶（仅15顶），橙红=估值贵的抱团顶——这个区分信息量更大，不要为了双确认去降阈值。

### v12 读数（行为/估值）
15顶100/100深红 | 18顶82/99橙红 | 21顶83/99橙红 | 24顶84/57无 | 16熔断底33/12无 | 18熊底8/32浅绿 | 19熊底1/7深绿 | 22底15/1浅绿 | 24低点42/0浅绿 | 当前(2026-08-13)89/49无标记(行为距橙红仅1点)。
新缓存：margin_two.csv（两融余额,含n_exch过滤）+ cache_hs300_mv.csv（HS300 float_mv，index_dailybasic单位=元非万元）。

## 7. ⚠️ v13 — 行为温度三维化 + MA网格搜索（评估口径决定结论）(2026-08-17)

### 杠杆率移出行为温度合成
v12的MA扫描证明杠杆维度只会拖后腿（18顶分量41分位）且三个结构漏洞无解，用户决定：**行为温度 = 三维（HS300换手率 + Top300广度 + HS300资金流强度）百分位均值再rank**，杠杆率保留独立面板（Panel 2）仅展示不参与红绿判定。效果立竿见影：18顶 行为82→92（升级深红🔴）、22底 15→4（升级深绿🟢）。v13读数：15顶99/100深红 | 18顶92/99深红 | 21顶88/99橙红 | 19底1/5深绿 | 22底2/1深绿。

### 三维独立MA网格搜索 — 评估口径三次演化
用户目标：三维各自找MA窗口，使六个关键区域（15顶/16底/18顶/19底/21顶/24底9月）双确认最多。
1. **单点口径**（只看指定日期当天）：343组合中87个6/6，推荐MA10/10/20（余量均衡）。但用户追问"六个区域多少个交易日"→ 发现信号地基只有6个点=全样本0.2%，过拟合风险大，主动向用户报告并提议扩口径。
2. **用户纠正"六个关键区域而不是点"** → 区域窗口max/min判定（窗口内存在某天触发即算）。
3. **用户再扩口径**："以六个区域的极值为中心看60个交易日窗口，6×60=360个交易日，看哪组ma双确认最多" → 以每区域HS300极值日为中心±30交易日（6×61=366天≈样本12%），数窗口内双确认天数。

**结果**：纯总天数Top解（换手60/广度20/流30=100天）会放弃16底换15顶堆量，不可取 → 加"六区域各≥1天"覆盖约束 → **MA15/20/40（换手/广度/资金流）=98天双确认六区域全覆盖**（15顶39/16底1/18顶4/19底11/21顶15/24底28），胜MA20/20/20(89天)与MA10/10/20(83天)。
**16底结构性只有1天**：熔断底恐慌抛售推高换手率、广度低而不极端，行为维度冷不下来——"恐慌底"天生单腿（估值冷+行为热），不要为凑双确认调参。

### 方法论（参数搜索通用）
- 用历史信号优化参数时**必须向用户报告信号地基的样本覆盖率**，覆盖低（如6个点）主动提议扩口径
- 优化目标须配**"每个关键区域≥N天"的覆盖约束**，否则最优解把信号全堆在最容易的区域（15顶刷量换16底）
- 点搜索找到的解要用区域/窗口口径复核，结论常完全改变（点口径MA10/10/20 → 窗口口径MA15/20/40）
- 搜索脚本必须复刻现有计算框架逐步（各维MA(n)→全量百分位→均值→rank校准→双维判定），且用户明确纠正过的口径（区域vs点）不能回退

### v13 配套改动
- Panel 4 资金流只画MA40曲线（用户"不需要单日的"），ylim±2（MA40实际范围-1.32~1.55，删除单日线后不再被±17极值撑开）
- 图加4个底标注：16底2016-01-28/19底2019-01-03/22底2022-10-31/24底9月2024-09-13，绿色虚线标签在下，与3顶灰色标注区分，贯穿全部7面板
- 24顶标注已删除（用户要求）
- 脚本末尾"关键区域验证"段改为窗口极值判定口径（与搜索目标一致），全历史统计：深红77/橙红444/深绿116/浅绿364天
- 当前读数(2026-08-13/14)：行为温度62（换手pct79/广度pct76/资金流pct14，资金流MA40把"高换手缺买入力度"算得更充分）/ 估值49 / 无标记。落地常量：market_temperature_v2.py `MA_TR, MA_BR, MA_FLOW = 15, 20, 40`。

## 8. ⚠️ v14 — 融资增速MA10并入行为温度 + 存量vs流量方法论实证 (2026-09-09)

用户审视网上"交易拥挤度+机构持仓占比判断高位"的说法, 联想到自家温度计, 追问
"两融(杠杆率)曾并入行为温度但没指导意义"。**用9个关键时点判别力实测回答**:

### 杠杆率水位百分位在9个关键时点的判别力(9点只对3个)
| 时点 | 水位分位 | 对错 | 备注 |
|---|---|---|---|
| 15疯牛顶 2015-06 | 99 | ✓ | 唯一教科书级 |
| 16股灾底 2016-01 | 92 | ✗ | 底部却超高(杠杆去化慢) |
| 18顶 2018-01 | 19 | ✗ | 顶部却超低(2017去杠杆) |
| 19底 2019-01 | 8 | ✓ | |
| 21核心资产顶 2021-02 | 41 | ✗ | 顶部却在中间, 零提示 |
| 22底 2022-10 | 72 | ✗ | 底部偏高 |
| 24-02小盘底 | 76 | ✗ | 底部偏高 |
| 24-09底 | 22 | ~ | 勉强 |
| 当前 2026-09 | 87 | — | 水位历史第二高(仅次15顶99) |

机理: 水位=存量慢变量(升降以月计) + 2015极端值/分母市值扩张双漂移 → 与快变量
(换手/广度/资金流)同权平均会把行为温度拉钝在中间区, 90/10线难触发。
2015-2021期间水位长期3.5-4.8%徘徊 = "慢水位永远在中间晃或者滞后"。

### 用户定案: 融资增速(流量)并入行为温度, 水位降为独立展示
- 融资增速 = 两融余额日增速 pct_change(1) 的 **MA10**(用户明确不要60日, 延迟太大)
  → 全历史百分位 → 行为温度第4指标(行为=换手MA15+广度MA20+资金流MA40+融资增速MA10 均值再rank)
- 杠杆率水位(MA20)保留独立展示(Panel2), 不参与合成
- 并入后7个关键时点判别力不退化: 15顶峰99/16底谷3/18顶峰91/19底谷1/21顶橙红(估值99+行为80)/
  22底谷2/24-09底谷1; 深红76天
- 增速百分位分档统计(全5,804笔baseline, ≥85线): 强869笔+12.9%胜84% / 中3,191笔+8.7%胜70% /
  弱1,744笔+2.9%胜53% (比旧≥70强档1,740笔+12.0%/胜80%更聚焦)

### 增速分位的用途(与水位完全不同)
- **底部锐利**: 历史大底增速分位全≤22 (16底5/19底12/22底22/24-02底9/24-09底12)
- **顶部看"近60日峰值分位≥90"而非当日值**: 增速常领先价格顶1-2月回落(21顶当月分位65但前1月峰83;
  15顶=60日增速+66%/分位99)
- **水位高+增速转负=危险组合(2015-06/07崩盘初期同款)**: 水位99+增速从99崩到0。
  2026-09对照: 水位5.1%/pct87 + 增速MA10分位38 = "高位停滞"(历史唯一同款=15崩初期, 样本1, 需盯后续)

### Panel2 双主题可视化(存量+流量一图)
左轴: 水位MA20(紫实) + 增速MA10(青实, 绕0线±2%范围, 可与水位3-7%同轴不压)
右轴: 水位百分位(浅紫细线) + 增速百分位(青点线)
ylabel 写 "右轴=百分位(紫: 水位, 青: 增速)"(勿写"实线=水位, 点线=增速"——左轴水位也是实线, 有歧义, 用户抓过)
图例4项补齐(水位百分位线无label, 加 `ax.plot([],[],...)` 代理空线进图例)

### ⚠️ margin零值/单边双防御(2026-09-07实证)
拉取端 n_exch≥2 过滤不够——9-07仍出现13,661亿(≈真实26,494亿一半=单边交易所)。
**消费端兜底**: 读缓存后 `pct_change()<-25%` 的行 → ffill 前值(两融单日真实跌幅从不超过~10%)。
Tushare margin/fund_share 当日22:00前发布不全/零值是常态, 不是异常——ffill而非丢弃。

### 方法论(用户要求长期应用): 存量vs流量识别框架
分析任何金融指标先界定: 是**水位**(存量水平, 慢变量, 钝化, 百分位判别力差, 适合做极端确认如双高=疯牛)
还是**增速**(流量变化, 快变量, 锐利但有噪声需MA平滑, 适合做底部冰点/顶部峰值信号)。
水位高+增速转负=危险组合(2015-07模式)。网上说的"交易拥挤度"≈换手+融资增速复合(流量),
机构持仓占比=水位(弹药表)——两者互补, 与我们温度计"存量独立+流量入行为"的分工同构。
