用于一组指标信号的朴素贝叶斯分类器(基础篇)
◍ 用朴素贝叶斯把指标信号当概率来算
做交易决策时,很多人纠结行情到底随不随机、概率模型能不能用。但站在 MT5 实操层面,更有价值的是先不管争论,把一组技术指标的触发信号当成随机变量,用朴素贝叶斯分类器去估每个信号对多空方向的贡献权重。 原作者在 2017 年 9 月发布的这套思路,核心目标是提升交易系统的胜率百分比,而不是预测绝对涨跌。框架本身支持任意指标接入,但首版建议先用标准内置指标跑通,降低自定义编译的坑。 外汇与贵金属市场高杠杆、高波动,概率模型只给倾向性参考,任何胜率提升都伴随样本外失效风险,实盘前必须在 MT5 策略测试器里用历史数据验证。 动手路径很直接:开 MT5 → 调出标准指标 → 按信号状态打标签 → 喂给贝叶斯框架统计条件概率。先跑通再谈优化,别一上来堆自定义指标。
用贝叶斯把指标信号换算成入场胜率
| 把行情状态当成假设 H,指标信号当成观测事件 E,后验概率 P(H | E) 就是看到信号后行情最可能走向的概率。公式里 P(E) 是信号柱线占总柱线比,P(E | H) 是盈利方向与信号吻合的柱线占总柱线比,两者都能从历史数据直接数出来。 |
|---|
为压住维度爆炸,这里先做两个激进简化:只用柱线级入场、持仓时间固定为 N 根柱线自动离场,且把「买入」「卖出」合并成「入场」一个假设。如此 P(H|E)=Nok/Ntotal,Nok 是吻合盈利方向的信号数,Ntotal 是信号总数。 实盘回测标准指标会发现,单指标 P(H|E) 大多落在 0.51–0.55。外汇与贵金属属高风险品种,点差和滑点会啃掉薄边,0.51 这种数值基本是盈亏平衡,撑不起资金稳定增长。
| 解法是叠指标。三个独立指标 A/B/C 用朴素贝叶斯展开:P(H | A,B,C) 正比于各自 P(H | X) 连乘再除公共项。若所有指标同概率 p,N 个指标联合胜率 = p^N / [p^N+(1-p)^N],p=0.51 时 3 指标仅 0.53,p=0.55 时 3 指标跳到 0.65。打开 MT5 接 D1 历史,先跑单指标数出你的 p,再决定要叠几个。 |
|---|
「别把高度相关的指标当多维度证据」
上面那套公式建立在随机过程相互独立的假设上,但实盘里这个条件很少成立。把 MT5 自带的几个标准指标摆在一起看就很直观:相同周期的 Stochastic 和 WPR 在副图里几乎重叠,因为两者公式等价;MACD 和动量振荡器在做了均线类型修正后也高度相似,且都脱胎于 MA,谈不上独立于均线本身。 RSI、RVI、CCI 之间的相关系数接近 1,ATR 与 StdDev 这类波动率指标也显著重合。几乎所有标准振荡器都强相关。如果你用这一堆指标组委员会来出信号,真实效果会远低于理论期望——重复信息只是把样本量做大了,信息量没增加。 训练神经网络时同理。喂进去一堆自选却彼此依赖的指标向量,网络算力浪费在冗余维度上,看起来输入很丰富,实际有效特征很少。严谨做法应计算指标间及与最小成对数值集合的相关性,那是另一项大研究;实操上按观察分组即可,例如 Stochastic + ATR + AC,或 WPR + 布林带 + 动量。 AC(加速/减速)本质是振荡器的派生。把报价或振荡器近似成余弦/正弦周期函数,其导数与原函数相关性为零,所以一阶导数适合当独立候选;二阶导数则容易变回原信号副本,价值可疑。 把不同周期计算的同名指标当作独立变量,也要看周期比率。微小差异掩盖了依赖,需要明显倍差——Elder 三联屏用约 5 倍周期差,部分印证这点。外汇与贵金属波动剧烈、杠杆高风险大,组指标时先开 MT5 把 Stochastic 和 WPR 同周期叠图确认重叠,再决定删哪个。 多数同类型振荡器不仅数值相关,信号逻辑也相似,所以时间序列的强弱依赖基本等于信号的强弱依赖。调系统前,先排查你用的指标里有没有相关系数近 1 的配对。
◍ 把信号框架做成跨平台测试器
理论铺完,接下来是落地:用一套 EA 加一个 mqh 框架,把任意指标的信号概率跑出来。框架通过输入参数接收「用哪个指标、怎么出信号」的描述,比如设两条不同周期均线,快线穿慢线分别给多空信号,不用改底层代码就能换指标组合。 EA 以柱线开盘价成交、由开盘事件明确驱动——它本质不是实盘机器人,而是验证假设的工具。重点在快检:指标组合无穷多,先算概率再谈策略。 默认跑 D1。D1 受随机噪声干扰最小,跨数年样本的规律性更贴合概率口径;且 D1 策略常可忽略点差,缓和系统「空等」损耗。日内框架则必须多算点差与假设数,不能套同一条假设。 持仓用固定周期平仓,输入参数默认 5 天——这是 D1 上被大量研究用过的一个特征窗口。EA 与框架走跨平台编译:借公开包装头在 MT5 里用 MQL4 API,关键段用 #ifdef __MQL4__ / #ifdef __MQL5__ 做条件编译,两平台都能出结果。