# 华尔街财团投入指数 & 反击情绪指数：更新逻辑与波动说明

## 一、数据流概览

```
爬虫提取 (extractor_ai / extractor_dashscope)
  → retaliation_sentiment / wall_street_value (0–100，按单篇报道)
  → db_merge.merge(extracted)
  → SQLite: retaliation_current, retaliation_history, wall_street_trend
  → server/situationData.js getSituation()
  → 前端: iranForces.retaliationSentiment(History), usForces.wallStreetInvestmentTrend
  → 组件: RetaliationGauge, InvestmentTrendChart；回放: useReplaySituation 插值
```

## 二、当前写入逻辑（crawler/db_merge.py）

### 1. 华尔街财团投入指数 (wall_street_trend)

- **表**：`wall_street_trend(id, time, value)`，前端用整表做 `wallStreetInvestmentTrend` 折线。
- **写入**：每次爬虫产出 `extracted["wall_street"]` 时：
  - 对 `value` 做限幅 `[1, 99]`，**不做任何平滑**；
  - 直接 `INSERT INTO wall_street_trend (time, value) VALUES (?, ?)`；
  - 表保留最近 `WALL_STREET_TREND_MAX_ROWS`（200）条。
- **波动原因**：
  - 每条报道一个点，爬虫频繁时点很密；
  - 不同报道提取值差异大（如 30 / 80 / 45），曲线会剧烈锯齿；
  - 无“与上一点平滑”，无时间间隔限制，易受单条 0/100 或异常值影响（虽已夹到 1–99）。

### 2. 反击情绪指数 (retaliation_current + retaliation_history)

- **表**：`retaliation_current(id=1, value)` 当前值；`retaliation_history(id, time, value)` 历史曲线。
- **写入**：每次爬虫产出 `extracted["retaliation"]` 时：
  - 当前值平滑：`new_val = 0.6 * current + 0.4 * raw`，再夹到 [1, 99]；
  - `retaliation_current` 更新为该 `new_val`；
  - `retaliation_history` 追加一条 `(time, new_val)`；
  - 历史表保留最近 `RETALIATION_HISTORY_MAX_ROWS`（300）条。
- **波动原因**：
  - 多条新闻短时间连续写入时，每次都用新的 raw 更新 current，连续多步 0.6/0.4 仍会快速漂移；
  - history 每写一次就一个点，点过密且 raw 差异大时折线仍会明显抖动；
  - 单步无“最大变化幅度”限制，极端 raw 仍会导致单次跳动较大。

## 三、爬虫侧产出形态

- **extractor_ai / extractor_dashscope**：仅当报道涉及对应维度时才输出：
  - `retaliation_sentiment`：0–100；
  - `wall_street_value`：0–100。
- 每条报道独立一个值，多篇报道会多次调用 `merge()`，因此**波动确实主要由爬虫数据更新频率和单条取值差异导致**。

## 四、稳定化思路（计算模块）

1. **华尔街**  
   - 与**上一点**做平滑再写入：例如 `value = alpha * last_value + (1-alpha) * raw`，再限幅；  
   - 可选：仅当距上一条时间超过一定间隔（如 15–30 分钟）才 INSERT，减少密集点带来的锯齿。

2. **反击情绪**  
   - 加强平滑：例如提高当前值权重（0.8 * current + 0.2 * raw）；  
   - 单步变化上限：例如 `new_val` 相对 `current` 最多 ±N（如 5）点；  
   - 历史记录：可对 history 做同样限幅或间隔写入，避免曲线过密抖动。

实现位置：**crawler/indicator_smooth.py**，在 `db_merge.merge()` 中调用，仍写回现有表，前端与 API 契约不变。

### 已实现参数（可调）

| 指标 | 参数 | 默认 | 说明 |
|------|------|------|------|
| 华尔街 | `WALL_STREET_NEW_WEIGHT` | 0.35 | 新 raw 权重，越小曲线越平滑 |
| 华尔街 | `WALL_STREET_MIN_INTERVAL_MINUTES` | 20 | 两笔趋势最小间隔（分钟），不足则本条不写入 |
| 反击情绪 | `RETALIATION_CURRENT_WEIGHT` | 0.8 | 当前值权重，越大越平滑 |
| 反击情绪 | `RETALIATION_MAX_STEP` | 5 | 单次相对当前值最大变化幅度（点） |
