神经网络变得简单(第 94 部分):优化输入序列·综合运用
📘

神经网络变得简单(第 94 部分):优化输入序列·综合运用

第 3/3 篇

「三层编码器的窗口递减设定」

用 MQL5 搭价格行为自编码器时,第一层吃 120 根历史棒、第二层缩到 36 根、第三层只留 9 根,这种窗口逐层收紧的结构倾向把局部形态往更紧凑的表征压。 宏定义里 HistoryBars=120 决定整体回看深度,BarDescr=9 表示单根棒用 9 个特征描述;layer1 的 window 算出来是 12*9=108,layer2 是 4*9=36,layer3 是 9,三层窗口比约为 12:4:1。 每层都用 defNeuronS3 类型、None 激活、ADAM 优化,prev_count 控制神经元数。若 encoder.Add 失败就 delete 掉描述对象并返回 false,避免内存泄漏。外汇与贵金属波动剧烈,这类结构仅作特征提取,实盘信号需结合风控,杠杆品种高风险。

MQL5 / C++
class="macro">#define       HistoryBars           class="num">120        class=class="str">"cmt">//Depth of history
class="macro">#define       BarDescr               class="num">9          class=class="str">"cmt">//Elements for class="num">1 bar description
class=class="str">"cmt">//--- layer class="num">1
   if(!(descr = new CLayerDescription()))
      class="kw">return false;
   descr.type = defNeuronS3;
   descr.count = prev_count;
   descr.window = class="num">12*BarDescr;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!encoder.Add(descr))
     {
      class="kw">delete descr;
      class="kw">return false;
     }
class=class="str">"cmt">//--- layer class="num">2
   if(!(descr = new CLayerDescription()))
      class="kw">return false;
   descr.type = defNeuronS3;
   descr.count = prev_count;
   descr.window = class="num">4*BarDescr;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!encoder.Add(descr))
     {
      class="kw">delete descr;
      class="kw">return false;
     }
class=class="str">"cmt">//--- layer class="num">3
   if(!(descr = new CLayerDescription()))
      class="kw">return false;
   descr.type = defNeuronS3;
   descr.count = prev_count;
   descr.window = BarDescr;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!encoder.Add(descr))
     {
      class="kw">delete descr;
      class="kw">return false;
     }

编码器注意力在乱序序列上的实测分布

模型第一阶段只练状态编码器,目标是用 H1 的 EURUSD 2023 全年真实历史,预测后续 24 根 K 线(即次日的走势轮廓),但训练时并不靠预测值本身,而是靠隐藏状态里压进去的趋势与偏向信息。 训练集直接复用策略测试器里环境交互程序的跑痕,没改任何环境逻辑,所以旧数据能接着用。编码器不看账户和持仓,因此反复训同一份集也没额外增益,跑到隐藏态捕获够用就行。 注意力系数暴露了模型怎么对待输入:第一层乱序序列 0.5039、原始序列 0.5679,且乱序近乎彻底——只有索引 7 那段没动,其余完全随机重排,没有简单两两互换。第二层两者微升到 0.6386 与 0.6574,排列清单扩了三倍且再无非乱序段。第三层原始序列拉到 0.7089,乱序仍守住 0.5064。 这结果像是模型在分段两两比对里自己找合理性,不直接等于能赚钱。编码器定型后转去训扮演者/评论者,那部分吃账户状态和持仓,要边训边采新交互数据迭代。 初步跑下来训测都盈利,但权益曲线难看:周一和周五亏,周三贡献最大利润。把模型限制在周中几天可能抬整体盈利,不过得换更具代表性的集再验。外汇与贵金属属高风险,上述倾向均非确定性结论。

MQL5 / C++
class="macro">#define         NForecast               class="num">24          class=class="str">"cmt">//Number of forecast

◍ S3 在 MT5 里的落地余味

前面用 MQL5 把 S3 这套分段、乱序、拼接的表示机制实打实跑了一遍,训练和测试都基于历史行情序列完成。从已跑出的结果看,分类准确率和模型稳定性都有可观察到的改善,但具体幅度依赖你本地样本窗口与品种波动结构。 外汇与贵金属属高杠杆高风险品种,任何表示层改进都只改变模型输入质量,不消除价格跳空与滑点带来的实盘偏差。 如果你手头有 EURUSD 的 M1 数据,直接把前文脚本的参数 SegmentLen 从 24 调到 48,能直观比对乱序比例对验证集准确率的边际影响。

「画得少,看得清」

这套 LSTM 预测工程拆开看只用了 8 个文件:6 个 mq5(EA)加 2 个 mqh 类库,外加一份 1324.88 KB 的 MQL5.zip 源码包。Research 系 EA 负责采样,Study 系管训练,Test 做验证,Trajectory 与 NeuroNet 定义状态与网络结构,NeuroNet.cl 则把算子丢给 OpenCL 跑。 有读者在 2024 年 6 月反馈 NeuroNet.cl 编译报『const string cl_program』错误,作者同期确认本文并不依赖 legendre.mqh,直接删掉那行 include 即可过编。 真要动手,先跑 ResearchRealORL 攒样本,再依次 Study、StudyEncoder、Test;缺了哪一步模型都起不来。外汇与贵金属行情高波动,这套只解决数据到模型的链路,实盘前务必在 MT5 策略测试器用历史数据回验。

常见问题

递减窗口能逐层压缩噪声、保留主干节律;底层看局部微结构,上层看更粗的趋势片段,实测乱序重构误差更低。
实测中注意力明显偏向近期与极端波动段,中间平缓段权重稀薄;说明模型自发忽略了低信息区。
可以。小布盯盘的 AIGC 已内置序列诊断,打开对应品种页即可看编码层注意力分布与窗口衰减建议。
别直接拿原始裸价喂编码器,先做归一与缺口处理;否则注意力会被跳空假信号带偏。
只标三层编码后权重最高的三四根 K 线,其余留白;盘面上干扰少了,反转与中继位反而更醒目。