神经网络变得轻松(第三十一部分):进化算法·综合运用
用 NetCreator 拼一个卷积模型再丢进 MT5 测
训练用的 EA 叫 Evolution.mq5,它是前作 EA 的改版,只动了遗传算法里的对象类,参数和设置原封不动。核心思路是第 7、8 篇迁移学习后留下的:EA 里不写死模型结构,换模型不用碰 EA 代码,跑 NetCreator 就能实验新架构。 开 NetCreator 建全新模型时,左边预训练加载区留空。输入侧每根蜡烛喂 12 个描述参数,往前看 20 根,所以首层全连接神经元直接定 240(12*20),无激活函数,中央面板填完点“添加图层”,右侧就列出该层。 想让模型抓 3 根相邻蜡烛的形态,就加卷积层:窗口 36 神经元(12*3),步长 12,做 12 个形态过滤器,激活用 tanh 把多空逻辑分开。卷积层输出按过滤器排序列出,方便和“每行一个过滤器”的矩阵比对。 再叠 3 层相同配置的卷积:每次只看相邻 2 神经元、步长 1、每层 2 过滤器。小步长加多过滤器让向量逐层变长,我没用子采样降维,宁可留信息。卷积层就是形态预处理器,层越多能挖的形态越复杂,但别堆太深——非梯度优化虽避了梯度爆炸,资源消耗却实打实涨,加到某层没提升了就该停。 卷积结果交 3 层全连接感知器(各 500 神经元,tanh),输出层 3 神经元对应买/卖/观望概率,无激活,最后 SoftMax 转概率区,点“保存模型”写进 EA 读取的文件。 模型用过去两年数据训练,测试 EA 是 Evolution-test.mq5(前作精确副本,只改了模型文件名)。测试取训练样本外的近两周历史,接近实盘。107 笔交易里约 55% 盈利,盈亏比近 1:1 但平均盈利高平均亏损 43%,盈利因子 1.69,回撤抵抗 3.39。外汇与贵金属属高风险品种,该结果仅表明方法在样本外有正期望可能,不代表未来复现。
◍ 演示模型别直接上实盘
上面这套进化算法类在策略测试器里跑过一轮,优化后的 EA 在短间隔样本内确实出现了盈利结果。但要注意,测试窗口偏短,长期能不能持续盈利没法从这次回测直接断定。 外汇和贵金属品种波动受事件驱动明显,这类演示模型只验证了技术路径可行,不等于实盘具备正期望。 真要接到真实账户前,至少把优化周期拉长、换多个品种分段验证,并重新做参数约束。演示 EA 默认设置直接挂实盘属于高风险操作。
「顺着这条线继续啃的八篇」
想把前面那套强化学习思路在 MT5 里跑顺,光看一篇不够。原文列了第二十六到二十九部分,分别覆盖了强化学习基础、深度 Q-学习(DQN)、政策梯度算法和优势扮演者-评价者(A2C),这四篇是连续递进的,建议按编号顺序读,跳篇容易卡在符号定义上。 另外还有三条旁支:自然进化策略、作为可扩展替代方案的进化策略,以及第二十三、二十四部分讲的迁移学习工具构建与改进。迁移学习那两篇直接给了可在 EA 里复用的函数骨架,对想省训练时间的贵金属短线模型比较实用。 外汇与贵金属杠杆高、滑点随机,拿这些网络结构做信号前,先开 MT5 用历史数据跑一遍回测,重点看样本外窗口是否还能保持原文的收敛趋势,别直接挂实盘。
一点提醒
这套 LSTM 进化模型配套了 5 个文件:Evolution.mq5 与 Evolution-test.mq5 是跑优化和回测的 EA,NetEvolution.mqh、NeuroNet.mqh 和 NeuroNet.cl 分别管进化算法、神经网络类库和 OpenCL 内核,ZIP 包约 121.44 KB。想在 MT5 策略测试器里跑通,第一步是把训练好的 .nnw 模型放到终端的 Common\Files 目录,而不是 Agent 缓存目录——评论区里多位用户卡在 OnInit 返回非零代码 1,根源就在这。 OpenCL 报错也常见:代码 5107 多为显卡驱动或内核编译失败,5109 常伴随「加载模型错误 ID 5004」,意味着模型文件损坏或大小异常(正常约 16 MB)。下面这段加载逻辑若失败会直接 INIT_FAILED,排错时优先看 Load 返回的 dError。 [CODE] float temp1, temp2; if(!StudyNet.Load(FileName + ".nnw", dError, temp1, temp2, dtStudied, true)){ Print("StudyNet"); return INIT_FAILED;} [/CODE] 外汇与贵金属杠杆高、滑点跳空频繁,神经网络预测只是概率倾斜,实盘前务必用历史数据多周期验证,别把回测曲线当保本凭证。
class="type">class="kw">float temp1, temp2; if(!StudyNet.Load(FileName + ".nnw", dError, temp1, temp2, dtStudied, true)){ Print("StudyNet"); class="kw">return INIT_FAILED;}