使用带 ENCOG 机器学习框架的 MetaTrader 5 指标进行时间序列预测(基础篇)
📘

使用带 ENCOG 机器学习框架的 MetaTrader 5 指标进行时间序列预测(基础篇)

第 1/3 篇

「用 ENCOG 框架在 MT5 里跑时间序列预测」

MetaTrader 5 可以接 ENCOG 机器学习框架做指标级的时间序列预测,思路是把历史报价当训练样本,让网络学出下一步价格的映射关系。这套玩法在 2014 年初就有公开示例,原帖当时拿到 6682 次查看、58 条讨论,说明老交易员早就盯上 ML 接 MT5 的落地可能。 想在 MT5 验证,核心是先确认终端版本支持自定义指标调用外部 DLL 或脚本宿主;ENCOG 本身是 .NET 系框架,走 MQL5 + C# 混合桥接更稳。外汇与贵金属杠杆高、滑点随机,模型回测漂亮不等于实盘概率占优,上线前先用历史分片做 walk-forward 才靠谱。 小布盯盘的做法是:把预测输出画成副图偏差带,只当 confluency 参考,不单独开仓。你能马上做的,是开 MT5 新建一个空指标,把下面这段骨架贴进去看编译是否通过。

◍ 为什么用 ENCOG 给 MT5 接神经网络

把 MetaTrader 5 接上机器学习,老路子有 FANN、NeuroSolutions、Matlab、NeuroShell 等。ENCOG 是 Heaton Research 的开源框架,定位是补充方案而非替代,代码牢固且设计干净,适合直接读源码理解时间序列预测。 选它有几个硬理由:已被两个商业交易软件实测过(一个 C#、一个 JAVA),专门用来预测金融时间序列;免费开源,C# 代码清晰易读;文档完善,作者 Heaton 提供免费在线课和 JAVA/C# 电子书,官网有完整说明。 项目没死。写稿时 ENCOG 2.6 仍在开发,3.0 路线图已发布;它支持多 CPU 内核与多线程,部分代码开始向 OpenCL(GPU 计算)移植。当前已支持前馈/Elman/Jordan 递归、遗传算法、NEAT、PNN/GRNN、SOM 等架构,训练技术含 RPROP、SCG、LMA 等,激活函数覆盖 Sigmoid、双曲正切、高斯等十余种。 本篇只落地一个点:用弹性传播(RPROP)训练的前馈网络,加上时间序列的量化与常态化编制。桥梁是之前写的《使用非托管导出将 C# 代码运用到 MQL5》——把 C# DLL 夹在 MT5 指标和 ENCOG 程序之间,外汇/贵金属预测属高风险,回测结论仅代表历史概率。

把指标值喂给前馈网络之前

做金融时间序列预测,核心是先想清楚往神经网络里塞什么、指望它吐什么。抽象地看,我们盯一只标的的过去价格和技术指标,试图预判后续市场情绪和价格方向,从而决定做多还是做空,而不是靠抛硬币下注。 前馈网络按层排布神经元,最少两层:输入层装输入神经元,输出层装输出神经元,中间可夹隐藏层。输入层本质是个 double 数组,输出层也是一个或多个 double 组成的数组。图里常省略连线,但事实是输入层每个神经元都连到隐藏层对应神经元,隐藏层再连回下一层。 每条连接带一个权重(也是 double),配一个带阈值的激活函数,决定信号是否向下一层传递——信息单向往前灌,所以叫“前馈”。 落地到 MT5 环境,真正卡住人的不是网络结构,而是四个实操点:喂什么数据、怎么喂、输入怎么归一化、输入输出神经元各开几个。训练完网络期待拿到的,也应是“上涨或下跌的概率倾向”,而非确定信号。外汇与贵金属波动受杠杆和跳空影响,模型误判会带来显著亏损风险。

「喂给神经网络的特征怎么挑」

做金融预测时,网络吃进去的应该是你真正用来判断行情的那些指标输出,而不是裸价格。这篇里只拿了随机指标 %K、慢速随机 %D 和威廉 %R 三组值当输入,纯粹是教学示范,不代表它们就是最优特征。 提取数值直接调 MT5 内置的 iStochastic 和 iWPR 就行,把三个数组按时间倒序排好,再 CopyBuffer 把指标缓冲拷进来。训练样本拉大之后,每个数组可能堆到几千个值,内存和读取耗时都得提前算。 真要落地,建议拿你自己验证过有边际信息的量去试:比如用黄金、原油去蹭股指的拐头,或者把相关性高的 forex 货币对互为输入猜另一个。外汇和贵金属杠杆高、跳空频繁,这类跨品种推断只是概率倾向,实盘前务必小仓位验证。

MQL5 / C++
class="type">class="kw">double StochKArr[], StochDArr[], WilliamsRArr[];
ArraySetAsSeries(StochKArr, true);  
ArraySetAsSeries(StochDArr, true);  
ArraySetAsSeries(WilliamsRArr, true);
class="type">int hStochastic = iStochastic(Symbol(), Period(), class="num">8, class="num">5, class="num">5, MODE_EMA, STO_LOWHIGH);
class="type">int hWilliamsR = iWPR(Symbol(), Period(), class="num">21);
  
CopyBuffer(hStochastic, class="num">0, class="num">0, bufSize, StochKArr);
CopyBuffer(hStochastic, class="num">1, class="num">0, bufSize, StochDArr);
CopyBuffer(hWilliamsR, class="num">0, class="num">0, bufSize, WilliamsRArr);

◍ 用 timebox 把指标切片喂给网络

从多个指标抓完原始数据后,直接丢进神经网络会破坏时序结构,所以要先做时间定量(timeboxing):把每个指标在最近 INPUT_WINDOW 根柱上的数值,按滑动窗口方式抽出来,再拼成一条输入向量。 第一步是从指标缓存里按开始位向将来位复制 INPUT_WINDOW 个元素。比如 INPUT_WINDOW=4,就把 4 根柱的值拷进数组 I1,I1[0] 是最早一根、I1[3] 是最近一根;带 AS_SERIES 标记的时间序列数组,索引方向也按这个逻辑对齐,其他指标同样各拷一份等长数组。 第二步是合并。假设接了 3 个指标,合并时先取各指标的第 1 个值、再各取第 2 个值,依此类推填满窗口,形成神经网络输入层要的一条数组。新柱一来,窗口整体前移一格,旧值挤出、新值补入,流程重跑。 在 MT5 里把 INPUT_WINDOW 从 4 改成 10 或 20,能直接看到输入向量长度变化,可据此验证自己对滑动盒的理解有没有偏差;外汇与贵金属行情跳空频繁,窗口拉太长可能把异质波动一并喂进模型,带来过拟合倾向。

喂给神经网络的数值必须先压进区间

激活函数能不能算对,前提是你送进去的数据尺度一致。把原始行情压到 0..1 或 -1..1,这一步叫正态化;反推回原始量纲叫去正态化,二者互为逆操作。 在 MT5 里接 ENCOG 框架时,标准化和去标准化它内部已经包办,你不用自己写管线。但想改输入边界或排查预测偏移,得知道它底层那两行线性映射在干什么。 下面这段是框架里正态化与去正态化的 Java 风格实现(MQL5 调用 ENCOG 时逻辑同源),INPUT_LOW/INPUT_HIGH 是原始数据上下界,OUTPUT_LOW/OUTPUT_HIGH 是目标区间上下界: 别把边界当摆设 INPUT_LOW 和 INPUT_HIGH 若取错(比如用了未来才出现的极值),正态化会把历史样本压歪,网络学到的映射在实盘就可能失真。外汇与贵金属杠杆高、跳空频繁,边界要用滚动窗口统计量而非全样本固定值。

MQL5 / C++
class=class="str">"cmt">/**
 * Normalize the specified value.
 * @param value The value to normalize.
 * @class="kw">return The normalized value.
 */
class="kw">public class="kw">static class="type">class="kw">double normalize(final class="type">int value) {
    class="kw">return ((value - INPUT_LOW) 
            / (INPUT_HIGH - INPUT_LOW))
            * (OUTPUT_HIGH - OUTPUT_LOW) + OUTPUT_LOW;
}

class=class="str">"cmt">/**
 * De-normalize the specified value.
 * @param value The value to denormalize.
 * @class="kw">return The denormalized value.
 */
class="kw">public class="kw">static class="type">class="kw">double deNormalize(final class="type">class="kw">double data) {
    class="type">class="kw">double result = ((INPUT_LOW - INPUT_HIGH) * data - OUTPUT_HIGH
            * INPUT_LOW + INPUT_HIGH * OUTPUT_LOW)
            / (OUTPUT_LOW - OUTPUT_HIGH);
    class="kw">return result;
}

常见问题

ENCOG封装了前馈网络、训练循环和归一化工具,能直接把指标切片喂给模型,省去底层数学实现,适合快速验证想法。
原始指标量纲差异大,网络梯度易发散导致训练失败;必须先压进[-1,1]或[0,1]区间再输入。
可以,小布盯盘的AIGC已内置特征切片与区间压缩流程,打开对应品种页即可直接看预处理后的序列,你只管调网络结构。
先从20~60根K线的小窗试起,窗口过长会引入噪声;回测时看样本外误差再缩窗或扩窗。
不是,冗余特征会拉低泛化;留2~4个低相关、有逻辑的指标,外汇贵金属高风险,实盘前务必样本外验证。