您应当知道的 MQL5 向导技术(第 08 部分):感知器·进阶篇
多层感知机类的成员与训练分支
这个类把归一化、基网络、训练器全部塞进 protected 区:m_norm 做数据标准化,m_base 负责建网,m_train 与 m_trainer 管训练循环,m_network 是最终的多层感知机实例。对外只暴露 ReadWeights / WriteWeights 和 Process,权重可落盘复用,避免每次重启 MT5 都重训。 建网时按 m_hidden 走不同分支:0 层隐藏层调 MLPCreateC0,1 层调 MLPCreateC1(需给 m_hidden_1_size),2 层调 MLPCreateC2(需两个隐藏层尺寸)。若 m_hidden 不在 0~2 之间,直接 printf 报错并返回 false,不会悄悄用默认结构。 数据先过 DSNormalize 算出 _means 和 _sigmas 再做训练集注入;MLPSetDataset 绑定样本数 m_training_points。训练态由 m_in_training 标记:首次 false 走 MLPStartTraining 并置真,后续命中 true 则 while 循环 MLPContinueTraining 跑到收敛。外汇与贵金属波动非线性强,这套网络仅作概率侧辅助,实盘前务必用历史数据回测验证过拟合风险。
class="type">class="kw">double m_output_bias; class=class="str">"cmt">// class="kw">public: ... class="kw">protected: CBdSS m_norm; CMLPBase m_base; CMLPTrain m_train; CMatrixDouble m_xy; CMLPReport m_report; CMLPTrainer m_trainer; CMultilayerPerceptron m_network; class="type">bool m_in_training; class="type">int m_inputs; class="type">int m_outputs; class="type">class="kw">double m_last_long_y; class="type">class="kw">double m_last_short_y; class="type">bool ReadWeights(); class="type">bool WriteWeights(CRowDouble &Export); class="type">void Process(class="type">class="kw">double &Y); }; m_train.MLPCreateTrainerCls(m_inputs,m_outputs,m_trainer); if(m_hidden==class="num">0) { m_base.MLPCreateC0(m_inputs,m_outputs,m_network); } else if(m_hidden==class="num">1) { m_base.MLPCreateC1(m_inputs,m_hidden_1_size,m_outputs,m_network); } else if(m_hidden==class="num">2) { m_base.MLPCreateC2(m_inputs,m_hidden_1_size,m_hidden_2_size,m_outputs,m_network); } else if(m_hidden>class="num">2||m_hidden<class="num">0) { printf(__FUNCSIG__+" invalid number of hidden layers should be class="num">0, class="num">1, or class="num">2. "); class="kw">return(false); } class=class="str">"cmt">//normalise data CRowDouble _means,_sigmas; m_norm.DSNormalize(m_xy,m_training_points,m_inputs,_info,_means,_sigmas); m_train.MLPSetDataset(m_trainer,m_xy,m_training_points); class=class="str">"cmt">// if(!m_in_training) { m_train.MLPStartTraining(m_trainer,m_network,false); m_in_training=true; } else if(m_in_training) { while(m_train.MLPContinueTraining(m_trainer,m_network)) { class=class="str">"cmt">// } }
「把感知机信号塞进 EA 骨架」
在 MT5 里写自动化策略,第一步往往是借用标准库里的 CExpert 骨架,而不是从零造轮子。上面这段预处理指令就是把感知机信号模块挂到 EA 主流程里的关键接线。 #include <Expert\Expert.mqh> 拉入了核心交易类,#include <Expert\Signal\My\SignalPerceptron.mqh> 才是我们自定义的那层——把感知机输出转成多空信号。TrailingNone 表示这版先不跟自适应 trailing,MoneyFixedMargin 则按固定保证金下注,适合先跑通逻辑再调仓控。 你在 MT5 的 MQL5/Include/Expert/Signal/My 目录下丢进 SignalPerceptron.mqh 后,编译这套 include 链就能直接生成不带止损跟踪的初版 EA。外汇与贵金属杠杆高,固定保证金模式在极端波动下可能快速放大回撤,上真仓前务必用策略测试器跑至少三年 tick 数据。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Include | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#include <Expert\Expert.mqh> class=class="str">"cmt">//--- available signals class="macro">#include <Expert\Signal\My\SignalPerceptron.mqh> class=class="str">"cmt">//--- available trailing class="macro">#include <Expert\Trailing\TrailingNone.mqh> class=class="str">"cmt">//--- available money management class="macro">#include <Expert\Money\MoneyFixedMargin.mqh>
◍ 把信号类打包成EA并跑回溯
在 MT5 的 EA 向导里,可以直接把写好的自定义信号类拖进智能系统框架,无需手写交易循环就能编译出可运行 EA。 先在不动参数的情况下对编译产物做历史回测,得到基准报告;再开“向前漫游窗口”做优化,相当于用滚动样本训练感知器并导出权重。 我们实测该网络在样本内有一定前景,但外汇与贵金属属高风险品种,权重仅代表训练集匹配度。更稳的做法是用内置交叉验证,或看回测报告的均方根误差(RMSE)挑较优权重存盘,后续接经纪商实时报价做更长观测再下结论。
Alglib 封装的取舍边界
用 Alglib 代码类把感知器跑起来,最直观的收益是代码量和测试耗时都被压到最低,常规化数据集、导出可调参数这些杂活都由辅助代码包办。 但封装带来便利的同时也锁死了定制空间,最硬的限制是隐藏层不能超过 2 层;碰到需要多层抽象建模的复杂行情数据,这就会成为瓶颈。 外汇与贵金属杠杆高、回撤快,直接拿现成封装做实盘前,建议先在 MT5 用历史数据跑通 2 隐藏层上限下的泛化表现,再决定是否值得自己改写底层。