# Coupling Analysis

> 改动前的耦合分析（Coupling Analysis / 防蝴蝶效应）——任何改动「共享参数、共享状态、 公共接口、全局常量、被多处引用的逻辑」之前，先画约束图，找出互斥约束与影响面， 再决定动…

改动前的耦合分析（Coupling Analysis / 防蝴蝶效应）——任何改动「共享参数、共享状态、
公共接口、全局常量、被多处引用的逻辑」之前，先画约束图，找出互斥约束与影响面，
再决定动手。触发场景：改参数/阈值/常量；改被多个模块调用的函数；改数据库 schema；
改 API 契约；改配置默认值；用户说"改一下 X"但 X 与 Y 耦合时；
以及任何一次"改完这个发现另一个坏了"的感觉出现时（说明上一轮没做本流程）。
**遇到影响关键决策的互斥约束，必须停下来让用户拍板，不得自作主张替用户选。**
不要用于纯新增（新文件、新独立函数）或不改动既有依赖的局部实现。

- Page: https://ss33.ai/skills/aaaaqwq/coupling-analysis-90298073337
- Publisher: aaaaqwq
- Category: [Software Development](https://ss33.ai/skills/category/software-development-t44z8z) › [Misc](https://ss33.ai/skills/category/software-development-t44z8z/misc-0pfo0b)
- License: MIT
- Source: https://github.com/aaaaqwq/agi-super-team/blob/dff8b4bdbeabb658bad0c4b75d173b60b91bd7ca/skills/coupling-analysis/SKILL.md

## Skill

SKILL.md: https://ss33.ai/api/v1/ss33/download/aaaaqwq/coupling-analysis-90298073337

# 改动前的耦合分析 | Coupling Analysis

**核心铁律：改参数前，先把参数之间的"约束图"画出来。互斥的约束，动手前就该发现，而不是动手后发现。**

## 为什么存在这个 Skill

真实事故：把止盈(TP)从"固定 2.2R"改成"最近分形高点"后，原规格
（SL 上界 3.0 ATR + RR ≥ 1.5）**首跑 0 个信号**。根因是数学互斥：
- SL 顶格 3.0 ATR（分母锁死），最近分形仅 1.25 ATR（分子上限）
- → 理论 RR 天花板 = 1.25，永远过不了 rr ≥ 1.5

这不是代码 bug，是**动手前没画约束图**。三个约束（TP/SL/RR）是耦合的，
动一个必然连锁。这就是蝴蝶效应。

## 执行流程（任何耦合改动之前）

### 第 1 步：识别耦合面
改这个之前，先问四件事：
1. **谁共享这个值？** —— `grep` 出所有引用点（常量 / 函数 / schema / 配置）
2. **谁是输入，谁是输出？** —— 画出数据流向
3. **有没有数学/逻辑约束关系？** —— 如 RR = reward/risk，A+B=C 之类
4. **谁依赖它的历史口径？** —— 回测、报表、已发布结论

### 第 2 步：画约束图
把相关参数写成约束列表，标出**可行域**和**互斥区间**：

```
示例（TP/SL/RR）：
  约束1: sl ≤ entry - 1.2*ATR        （风控下限）
  约束2: sl ≥ entry - 3.0*ATR        （风控上限）
  约束3: rr = (tp - entry)/(entry - sl) ≥ 1.5
  约束4: tp = 最近分形高点, 通常 ≈ entry + 1.25*ATR
  →
  由约束2+4: rr_max ≈ 1.25/3.0 ≈ 0.42~1.25  →  与约束3 互斥 ❌
```

**互斥约束必须在动手前暴露。** 暴露不了，就先做第 3 步。

### 第 3 步：零改动扫描（不确定时）
**不要一上来就改代码。** 先在旧代码上做**只读参数扫描**：
- 枚举候选组合（如 rr ∈ [1.0,1.2,1.5,2.0] × sl上限 ∈ [2.0,2.5,3.0]）
- 看哪些组合**输出量合理**、哪些**归零**
- 用真实数据跑，得到可行域

扫描成本 << 改动成本，且**无副作用**。

### 第 4 步：定义不变量（红线）
明确哪些是**用户红线，不可擅动**，哪些是**可调参数**：

| 类型 | 处理 |
|---|---|
| 用户明确的风控参数 | **不可擅自改**，要改必须先问 |
| 结构逻辑（如"SL 优先看支撑位"） | 保留，只调常数 |
| 内部实现细节 | 可自由改 |

### 第 5 步：影响面枚举（改后回归）
列出所有下游：
- 依赖这个值的**测试**会不会红？
- 依赖这个口径的**历史结论**是否失效？
- **报表/回测**口径是否变了、是否可比？

## 高内聚低耦合的设计准则

新代码/重构时优先：

| 准则 | 做法 |
|---|---|
| **高内聚** | 一个模块只干一件事；相关逻辑就近放，不散落 |
| **低耦合** | 参数单一来源（single source of truth），不硬编码在多处 |
| **显式依赖** | 需要的值**传进来**，不要在函数内部偷偷读全局 |
| **可替换** | 改一个策略（如 TP 算法）不影响 SL/RR 模块 |
| **约束可测** | 把互斥约束写成**断言或测试**，违反时报错而非静默 |

**反例**：把 `1.5` / `2.0` 硬编码在计算式里 → 赔率变成常数，与标的无关（真实事故）。
**正解**：常数提取为具名参数，且与其它参数的关系有测试守护。

## 关键决策必须交还用户

**遇到影响关键决策的互斥约束 / 风控参数变更 / 不可逆选择：**

1. **停下来**，不要"为了让它跑起来"自行放宽
2. **把取舍摊开**：A 选项代价 vs B 选项代价，各是什么
3. **给推荐但标明**："我倾向 X，理由是……，但这是你的风控参数，你拍"
4. **等用户明确回答**再继续

> 擅自替用户放宽风控参数 = 越权。哪怕动机是"让它能跑"。

## 交付前自检清单

- [ ] 我画的约束图里，有没有互斥区间？
- [ ] 有没有我偷偷改了用户没授权的参数？
- [ ] 下游影响面（测试/历史口径/报表）我列全了吗？
- [ ] 这个改动有没有新的单一数据源，还是又硬编码了一处？
- [ ] 涉及关键决策时，我是停下来问了，还是自己拍了？

**动手前 10 分钟的约束图，能省掉动手后 10 小时的连锁 bug。**
