# 主池145 + A股行业基30：混在一个账户里同时跑 —— 测试报告

**窗口** 2020-01-02 ~ 2026-09-29（6.74 年，1635 个交易日）· zip 分钟数据 · 万 0.5 佣金 · T+1
**参数** 主池：30min / 动量 15 日 / 均线 12 日 / K=3 / 阈值 1%；A股行业基：5min / 动量 10 日 / 均线 12 日 / K=3 / 阈值 2%
**引擎** `mix_engine.py`（新写）：一个账户、两套信号、两个 sleeve，共用现金、共用 T+1 账本、账户级熔断

---

## 一、结论

**能做，但取决于"怎么混"。同一个账户里同时跑 → 收益和 Calmar 都变好；但前提是让两侧各管各的仓位。**

| 方案 | 期末净值 | 年化 | 年化波动 | 最大回撤 | Sharpe | Calmar |
|---|---|---|---|---|---|---|
| 只跑主池 145 | 5.726 | 29.75% | 22.15% | -15.89% | 1.25 | 1.87 |
| 只跑 A股行业基 30 | 5.618 | 29.38% | 25.27% | -17.74% | 1.06 | 1.66 |
| 合并成**一个池**（176 只·单套参数） | 4.530 | 25.29% | 26.39% | -24.62% | 0.88 | **1.03** |
| **两个独立账户** 80/20（各跑各的） | 5.704 | 29.67% | 20.80% | -15.03% | 1.33 | 1.97 |
| **同账户·紧密** 80/20（每次评估全账户对齐） | 5.484 | 28.91% | 20.87% | -16.87% | 1.29 | **1.71** |
| **★同账户·松耦合** 80/20（只动刚评估的那一侧） | **5.973** | **30.57%** | 20.94% | **-15.15%** | **1.36** | **2.02** |

- **松耦合 vs 只跑主池**：年化 +0.82pp、波动 -1.21pp、回撤收窄 0.74pp、**Calmar 1.87 → 2.02**；
- **紧密 vs 只跑主池**：年化 **-0.84pp**、回撤**深了 0.98pp**、Calmar 掉到 1.71 —— **比不混还差**；
- **合池**（把两个池并成一张池、单套参数）最差，Calmar 只有 1.03。

一句话：**「混」本身不是问题，「怎么混」才是。** 让两侧各自记账、只在现金不够时互相避让（松耦合），
既拿到了分散化收益，又不把对方的节奏强加给自己；一旦"每次评估都把整个账户拉回总目标"（紧密），
A 侧每 5 分钟一次的评估就会反复重排主池的仓位，把好处全吃掉还倒亏。

---

## 二、同一权重下三种合并方式的横向对比

| 权重 | 松耦合：净值 / 年化 / 回撤 / Calmar | 紧密：净值 / 年化 / 回撤 / Calmar | 两个独立账户：净值 / 年化 / 回撤 / Calmar |
|---|---|---|---|
| 100 / 0 | 5.726 / 29.75% / -15.89% / 1.87 | 同左 | 同左 |
| 90 / 10 | 5.953 / 30.50% / -15.61% / **1.95** | 5.429 / 28.72% / -17.21% / 1.67 | 5.715 / 29.71% / -15.17% / 1.96 |
| **80 / 20** | **5.973 / 30.57% / -15.15% / 2.02** | 5.484 / 28.91% / -16.87% / 1.71 | 5.704 / 29.67% / -15.03% / 1.97 |
| 70 / 30 | 5.833 / 30.11% / **-14.92%** / **2.02** | 5.510 / 29.00% / -16.51% / 1.76 | 5.694 / 29.64% / -15.15% / 1.96 |
| 60 / 40 | 5.707 / 29.68% / -14.92% / 1.99 | 5.489 / 28.93% / -16.23% / 1.78 | 5.683 / 29.60% / -15.26% / 1.94 |
| 50 / 50 | 5.751 / 29.83% / -15.01% / 1.99 | 5.505 / 28.99% / -16.01% / 1.81 | 5.672 / 29.56% / -15.37% / 1.92 |
| 0 / 100 | 5.618 / 29.38% / -17.74% / 1.66 | 同左 | 同左 |

- **松耦合在 50~90 全区间 Calmar 都在 1.95~2.02**，紧密全区间只有 1.67~1.81 —— 差距不是挑权重挑出来的；
- 松耦合在**每一个权重档**上都略优于两个独立账户（80/20：2.02 vs 1.97），也就是说
  **用"一个账户 + 松耦合规则"就能拿到"两个账户"的效果，还略好一点**。

---

## 三、逐年收益

| 方案 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026(至9/29) |
|---|---|---|---|---|---|---|---|
| 只跑主池 145 | 22.6% | -0.8% | 22.4% | 8.1% | **67.8%** | 46.8% | 43.4% |
| 合并成一个池 176 | 57.4% | 2.3% | **-5.9%** | 12.3% | **26.7%** | 52.2% | 38.0% |
| 两个独立账户 80/20 | 33.0% | 8.5% | 14.6% | 14.0% | 49.6% | 44.6% | 38.8% |
| **同账户·松耦合 80/20** | 32.1% | 7.9% | 16.3% | 12.6% | **53.0%** | 46.8% | 41.3% |
| 同账户·紧密 80/20 | 32.8% | 6.5% | 17.0% | 12.3% | **45.8%** | 43.4% | 40.0% |

- 混入 A 股行业基后，**2021 / 2022 / 2023 三个"主池的弱年"都被垫高了**（-0.8% → 7.9%，2022 由 22.4% 摊薄为 16.3% 但整体更稳），
  代价是 2024 从 67.8% 摊到 53.0% —— 典型的分散化形态：**削峰、填谷**；
- 松耦合在 2024（-7.2pp vs 紧密）和 2026（+1.3pp）都比紧密好，说明紧密的损失主要发生在主池爆发期（被 A 侧的节奏拖住）。

---

## 四、机制：为什么"紧密"会把好处吃光

| 指标 | 松耦合 80/20 | 紧密 80/20 | 独立双账户 80/20 |
|---|---|---|---|
| 账户调仓（下单事件）次数 | 15315 | 15496 | —（两侧各自 4381 + 10975） |
| 换手合计 | **2677** | 2928 | 2494（= 0.8×1967 + 0.2×4604） |
| 其中 主池 / A股 | 1626 / 1050 | 1873 / 1055 | 1574 / 921 |
| 熔断 | 0 | 0 | 0 |

- 紧密模式把**主池的换手从 1626 推高到 1873（+15%）**：A 侧每 5 分钟评估一次，每次都会把整个账户（含主池仓位）拉回两侧总目标；
- 但**多出来的换手只值 0.19 pp/年佣金**（(2928-2677)×万0.5），远远不够解释 1.66 pp/年的收益差 ——
  **真正的损耗是"仓位在错误时点被重排"**：主池本来该在 30 分钟节点按自己的节奏调整，被 A 侧牵着走之后，调整时点被污染。
- 松耦合相对独立双账户的差距是**噪声型**：逐日收益差累计 +4.78%、绝对差合计 152.64%、单日最大 ±1.1%，
  没有单一主因日（最大差异日是 2024-10-08 +1.10%），额外换手只值 0.14 pp/年。

**共享账户的真实成本（现金 + T+1）本身很小**；真正要避免的是**共享"目标对齐时点"**。

---

## 五、稳健性

| 变体（都是松耦合 80/20 框架） | 净值 | 年化 | 最大回撤 | Calmar | 结论 |
|---|---|---|---|---|---|
| A 侧用**专属参数** e5/m10/K3/2% | 5.973 | 30.57% | -15.15% | **2.02** | ✓ 最优 |
| A 侧用**专属但保守** e10/m10/K3/2% | 5.759 | 29.86% | -15.42% | 1.94 | ✓ 仍明显好于单跑 |
| A 侧用**现有参数** 30/15/K3/1% | 5.450 | 28.79% | -15.76% | 1.83 | ✗ 无增益（低于单跑 1.87） |

- **"A 侧必须用自己的专属参数"这一条在松耦合下同样成立**（1.83 < 1.87）。而且这里松耦合与紧密结果完全一致
  （5.450 / 1.83）——因为两侧评估时点都是 30 分钟、完全重合，松紧两种模式退化为同一种；
- **eval=5 的那个 2.02 有过拟合嫌疑**（`poolA` 扫描里 eval 维度的中位数差别不大，只有最优档拉开）。
  保守用户可以取 e10：Calmar 1.94、净值 5.759、回撤 -15.42%，**依然优于只跑主池（1.87）**。

---

## 六、引擎保真度（这轮花最多力气的地方）

合并引擎必须与独立引擎同源可比，否则结论无效。我用两个端点做了校验：

| 端点 | 合并引擎 | 独立引擎 | 一致性 |
|---|---|---|---|
| w = 1.0（只跑主池） | 5.726 / 29.75% / -15.89% / 调仓 4381 / 换手 1967.0 | 5.726 / 29.75% / -15.89% / 4381 / 1966.95 | ✓ 逐位 |
| w = 0.0（只跑 A 股） | 5.618 / 29.38% / -17.74% / 调仓 10975 / 换手 4604.2 | 5.618 / 29.38% / -17.74% / 10975 / 4606 | ✓ 逐位 |

**过程中修掉两个真 bug**（都是我先写错、再自己查出来的，记下来免得再踩）：

1. **滞回锚点用错**：第一版把"上次目标"当锚点，而离线引擎的锚点是"当前实际持仓"。
   后果：买入被缩量 / T+1 挡住后不会补单，残仓一直挂着 → w=0.0 时 A 侧只跑出 5.022（正确值 5.618）、
   回撤 -20.55%（正确 -17.74%）。改成锚实际持仓后端点逐位复现。
2. **松耦合会丢仓位**：只交易一侧时，`new_hold` 只包含那一侧的标的，另一侧持仓被静默丢弃
   （等于免费清仓、下次再买回来）→ 换手翻倍（5059 vs 2677）、年化掉到 24.45%。
   修法：未被本次交易的持仓与 T+1 锁定原样保留。

---

## 七、落地建议

1. **用同一个账户 + 松耦合规则**（推荐）：
   - 账户内维护两个独立账本（主池 / A股行业基），各按各的目标权重与阈值；
   - 每次只对**刚评估过的那一侧**下单，另一侧仓位不动；
   - 现金共用（不够时按比例缩量），T+1 按标的统一记账；
   - 熔断挂在**账户净值**上（松耦合 80/20 全程 0 次触发，比两侧各自熔断更不易误伤）。
2. 嫌复杂就**分两个账户**：Calmar 1.97 vs 松耦合 2.02，几乎一样（98% 的效果）。
3. 权重取 **80/20 或 70/30**（70/30 的回撤更浅 -14.92%，年化 30.11%）。
4. **A 侧必须用自己的专属参数**（5~10 分钟评估、10 日动量、2% 阈值），否则这 20% 资金等于白放。
5. **实盘前要补的三件事**：
   - A 侧换手很高（账户口径 1050 / 6.7 年），**回测未计滑点**，需单独验成交质量；
   - eval=5 偏激进，稳健起见先用 **e10**（Calmar 1.94）跑实盘，观察 3~6 个月再决定是否提到 e5；
   - A 侧标的（半导体、通信、券商、军工…）在极端行情下会**同时**大幅波动，去重层只有 0.90 相关性阈值兜着，
     建议实盘加一道"单只 + 单个大主题"的权重硬上限。

---

## 八、产出与复现

| 文件 | 内容 |
|---|---|
| `同账户合并对比报告.html` | 交互净值曲线（核心对比 / 松紧权重谱）+ 回撤 + 横向对比表 + 逐年表 + 引擎明细 |
| `replay_minute_out/mixacct_all_curves.csv` | 全部曲线的日频净值原始数据 |
| `replay_minute_out/mixacct_summary.csv` | 16 个配置的指标与换手/触发/熔断明细 |
| `mix_engine.py` | 合并引擎（支持 `--w` 权重、`--loose` 松耦合、`--aparam best/cons/base`） |
| `run_group_single.py` | 单组单配置回放（用于与合并引擎做端点校验） |
| `build_mixacct_report.py` | 报告生成器 |

```bash
cd 云飞复刻版
PYTHONHASHSEED=0 python mix_engine.py                      # 全部 16 个配置（约 10 分钟）
PYTHONHASHSEED=0 python mix_engine.py --w 0.8 --loose      # 只跑松耦合 80/20（约 40 秒）
PYTHONHASHSEED=0 python build_mixacct_report.py            # 出报告
```

> 复现提醒：所有回测必须固定 `PYTHONHASHSEED=0`，否则同一配置的净值会有约 ±1% 的随机抖动
> （Python 字符串哈希随机化 → 并列动量时的选股排序差异）。
