Ⅲ · 逐项对照 — 3.3
信号的表达力
CExpert 的 0–100 加权投票是一套完整可用的方案。它的限制不在精度,在信息量——而信息量决定了后面能做什么。
MQL5 实际是怎么合成的
CExpertSignal::Direction() 的核心 ✓ 已实测:
double result = m_weight * (LongCondition() - ShortCondition()); // 标量 [-100, 100]
int number = (result == 0.0) ? 0 : 1;
for (每个 filter) {
direction = filter.Direction();
if (direction == EMPTY_VALUE) return EMPTY_VALUE; // 一票否决
result += direction; // 或 -= ,若该位在 invert 掩码中
number++;
}
return result / number; // 算术平均
// 随后:if (m_direction >= m_threshold_open) 默认阈值 50
结构是清楚的:**每个信号塌缩成一个标量,乘静态权重,求算术平均,与阈值比较。**另有 EMPTY_VALUE 一票否决、invert 位掩码、ignore 位掩码三个机制。
这套设计并不粗糙——一票否决和位掩码反转是很实用的东西。问题在于投票本身携带的信息只有一个数。
LEAN 的 Insight 携带了什么
同一个位置,LEAN 传递的是一个对象 ✓ 已实测:
| 字段 | 含义 | MQL5 投票里有吗 |
|---|---|---|
direction |
方向(Up / Down / Flat) | 有——就是那个数的符号 |
magnitude |
预期变动幅度 | 无 |
confidence |
置信度,与方向独立 | 无——强度和信心被压成了同一个数 |
period |
有效期,过期自动失效 | 无——投票是瞬时的 |
weight |
建议权重 | 有,但是静态输入参数 |
source_model |
产生它的模型 | 无——混合后来源丢失 |
generated_time_utc / close_time_utc |
生成与失效时刻 | 无 |
Nautilus 的做法:不规定
Nautilus 不强加信号结构。策略内部想怎么组合都行,跨组件传递则通过 CustomData 走消息总线——你自己定义数据类型,携带什么字段由你决定。灵活,但也意味着没有现成的归因框架,要自己建。
这一节和前端是同一个问题
数据模型决定了前端的天花板。
信号是整数 → 前端只能画一条净值曲线和买卖点。
信号是带 source_model 和 period 的对象 → 可以画信号贡献分解、各信号的命中率、有效期内的表现衰减、信号之间的相关性。
所以“自研前端的优势”不是“图画得更好看”,而是后端产出了值得画的东西。详见 4.3。