基于通用 MLP 逼近器的EA(基础篇)
◍ 把通用MLP塞进EA里跑
在 MT5 里做算法交易,不少人卡在「模型怎么接进 EA」这一步。Andrey Dik 在 2025 年 9 月 3 日发布的示例,用一套通用 MLP 逼近器直接嵌进 Expert Advisor,目前原帖已有 506 次查看、13 条讨论,说明这类落地型做法在社群里有真实需求。 所谓通用逼近器,是指不针对某类行情写死规则,而是用多层感知机去拟合输入到决策之间的映射。比起传统指标阈值判断,它把「什么状态该下什么单」交给网络权重决定,EA 只负责把报价、指标向量喂进去、把输出转成订单。 要把 MLP 集成进交易 EA,核心不是重写神经网络,而是解决两件事:MT5 端如何用 Array 和结构体承载张量,以及训练好的权重如何序列化为 EA 能读取的参数文件。外汇与贵金属杠杆高、滑点突变频繁,这类模型在样本外表现可能明显衰减,上实盘前务必用历史数据回测验证。
「神经网络本质是多层函数复合」
提到神经网络,很多交易者直觉里先冒出一堆公式和调参黑话,其实它的骨架非常朴素:它就是若干层函数的复合。每一层干两件事——先做线性变换,再套一个非线性激活函数,没有第二步,深层里那些“神秘能力”全靠非线性堆叠出来。 写成方程就是 f(x) = (f_n ∘ … ∘ f_2 ∘ f_1)(x),其中每个 f_i 都是一个「线性变换 + 激活函数」的组合。对 MT5 玩家来说,这意味着你不必懂证明,只要能控制层数、每层神经元数和激活类型,就握住了它绝大部分可调旋钮。 外汇与贵金属杠杆高、跳空频繁,用神经网络做信号前务必在 MT5 用历史数据做样本外验证,过拟合的概率不低。
把 MLP 当纯变换器用
多层感知机(MLP)最朴素的形式就是一串嵌套函数:F(x)=f2(f1(x)),f1 与 f2 各是一层带激活函数的神经元组。剥掉权重训练和 SGD、ADAM 这些优化器不谈,它本质上是一个非线性信息变换器,这一点对交易者很实用。 在 MT5 里,你可以不碰机器学习框架,直接把 MLP 当成状态识别模块:喂入均线斜率、ATR 比值等指标,让它输出盘整 / 趋势 / 过渡三类市场状态,再外挂不同逻辑的开仓条件。外汇与贵金属杠杆高、滑点跳空频繁,这种切换只是概率上的适配,不保证胜率。 本系列后续会一步步走完数据准备、离线训练、EA 集成的全过程,重点放在‘无优化器也能落地’这条路上,让有 EA 编写基础的人照抄就能跑。
◍ 三种训练范式在行情序列上的真实短板
做行情建模先得认清楚三類训练底子。监督学习靠带标签样本最小化预测误差(如 MSE),但时间序列打标极不可靠:你标的是什么,网络就学什么,常常学到的是研究者脑补的假设,而非价格过程本身。所谓“过拟合”“噪声”在时间序列里没有明确定义和量化标准,纯属主观评估,这会让模型在新数据上稳定性显著下降。 无监督学习让模型自己挖隐藏结构,K-均值最小化簇内平方和、PCA 最大化投影方差、决策树最小化熵或基尼。麻烦在于没有验证标记,数据若没清晰结构,模型可能啥有用模式都没抓到,你也无法确认挖到的东西是否和行情载体过程相关。 强化学习最大化总奖励,智能体与环境交互试错。用 ADAM 训神经网络时,目标强化函数须归一化到接近 [-1;1],否则反向传误差易触发权重爆炸、网络停滞;随机性还导致结果不稳,没有明确奖惩系统的问题基本训不动。 三类范式本质都只对某个目标函数做最小化或最大化,区别仅在于“监督者”在不在。有目标值就归监督,没有就归无监督,后者子类型只看目标函数基于距离、密度、系统绩效还是分布——这套划分比传统教科书更贴实盘数据现实。
「让网络自己找交易信号」
这里走的是无监督路线:不教模型怎么开平仓,因为人本身也没有标准答案。把决策权交给网络,我们只看它跑完一整段历史后的整体交易结果。 MLP(多层感知机)天然适合干这种“信息转换器”的活。通用逼近定理给了理论背书——一个多层感知机可以逼近任意连续函数,而我们面对的“连续函数”就是价格序列里真实发生的过程。 好处是工程上干净:不用对评估函数做归一化,也不用怕权重爆炸或网络停滞,因为从代码逻辑上就把神经网络和外部优化器拆开了。网络只负责把输入(OHLC、指标值等)映射成一种新信息,至于这信息怎么用,由后面的优化算法说了算。 想验证很简单:给 MLP 喂当前品种的历史 K 线和指标,输出端直接拿信号;扫完整个历史算出目标函数(对交易结果的综合评分),再用外部优化器调权重去最大化它。外汇和贵金属波动剧烈、杠杆高风险大,这类信号只代表历史样本下的概率倾向,实盘前务必在 MT5 策略测试器里跑多品种多周期。
把MLP塞进EA里跑信号
先写一个 C_MLP 类承载纯前向传播的多层感知机,不夹带优化器。Init() 按层配置返回权重总数;ANN() 从输入层一路算到输出层;GetWcount() 直接吐出 weightsCNT;LayerCalc() 负责单层计算,激活函数锁死双曲正切,把神经元输出压进 -1 到 1。 LayerCalc 遍历输出层每个神经元:先取偏置,再累加「输入值×对应权重」,最后过 tanh。这样逐层串起来,就是完整的前向传播。网络至少要有输入+输出两层,每层至少 1 个神经元,否则 Init 返回 0 并报错。 EA 侧在 OnInit() 里把 RSI 和 Stochastic 对象建好,按 BarsAnalysis_P 算输入维度,默认网络结构字符串 "1|1" 实际是 2 个隐藏层各 1 神经元。OnTick() 里先判是否该重训,再等新K线,抓 OHLC+双指标,做 -1~1 归一化,丢进 ANN 出信号;输出超阈值且无持仓、时间在窗内就开仓,反向信号或时间窗结束就平。 训练用种群优化在历史数据上搜最佳权重,目标函数本质是一次从当前点回放的历史回测:算盈亏比×交易次数,再乘缩减因子平衡买卖不均。图2给了样本外(OOS)资金曲线——输入就是归一化 OHLC 与 RSI/Stochastic,网络过期先训再跑。外汇与贵金属杠杆高,OOS 漂亮不代表实盘能复现,开 MT5 用 "1|1" 默认结构先验证一次再调隐藏层。
class=class="str">"cmt">//+----------------------------------------------------------------------------+ class=class="str">"cmt">//| Multilayer Perceptron(MLP) class | class=class="str">"cmt">//| Implement a forward pass through a fully connected neural network | class=class="str">"cmt">//| Architecture: Lin -> L1 -> L2 -> ... Ln -> Lout | class=class="str">"cmt">//+----------------------------------------------------------------------------+ class C_MLP { class="kw">public: class=class="str">"cmt">//-------------------------------------------------------------------- class=class="str">"cmt">// Initialize the network with the given configuration class=class="str">"cmt">// Return the total number of weights in the network, or class="num">0 in case of an error class="type">int Init(class="type">int &layerConfig []); class=class="str">"cmt">// Calculate the values of all layers sequentially from input to output class="type">void ANN(class="type">class="kw">double &inLayer [], class=class="str">"cmt">// input values class="type">class="kw">double &weights [], class=class="str">"cmt">// network weights(including biases) class="type">class="kw">double &outLayer []); class=class="str">"cmt">// output layer values class=class="str">"cmt">// Get the total number of weights in the network class="type">int GetWcount() { class="kw">return weightsCNT; } class="type">int layerConf []; class=class="str">"cmt">// Network configuration - number of neurons in each layer class="kw">private: class=class="str">"cmt">//------------------------------------------------------------------- class=class="str">"cmt">// Structure for storing the neural network layer