交易中的神经网络:配备注意力机制(MASAAT)的智代融汇(终章)·综合运用
📘

交易中的神经网络:配备注意力机制(MASAAT)的智代融汇(终章)·综合运用

第 3/3 篇

「MASAAT 层的梯度回传与结构参数」

CNeuronMASAAT::calcInputGradients 负责把输出端的误差反向拆回时间维与截面维两条通路。先借基类 CNeuronPortfolioGenerator 的梯度接口处理截面分支,再对拼接层 cConcat 做隐藏梯度计算,最后用 SumAndNormilize 把两条梯度流合并归一,避免多维特征在回传时量级失衡。 代码里 DeConcat 按神经元数把梯度重新拆给 cPLR 与 cConcat,若层带激活则走 DeActivation 反函数;随后 cTranspose 按 iDimension 做转置梯度归一,最终交给 prevLayer 继续向后传。任一环节返回 false 即中断,说明该层对上游形状或激活配置敏感。 Layer 2 的建层描述里,window_out 固定为 32,step=4 对应多头注意力头数,layers=3 为堆叠深度,batch 设 1e4。radius 用长度为 3 的全 1 向量生成:ones*2 逐元素平方后乘累积偏移再乘 0.01f,得到由近及远递减的最小距离阈值。 在 MT5 里把 descr.step 从 4 调到 8,可能让注意力头数翻倍、显存占用上升但捕获周期更细;外汇与贵金属行情跳空频繁,这类结构改动属高风险实验,建议先用历史 Bars 离线校验再上实盘。

MQL5 / C++
  class="kw">return CNeuronPortfolioGenerator::feedForward(cTemporalAnalysis.AsObject(), cCrossSectionalAnalysis.getOutput());
  }
class="type">bool CNeuronMASAAT::calcInputGradients(CNeuronBaseOCL *prevLayer)
  {
  if(!prevLayer)
      class="kw">return class="kw">false;
  if(!CNeuronPortfolioGenerator::calcInputGradients(cTemporalAnalysis.AsObject(),
        cCrossSectionalAnalysis.getOutput(),
        cCrossSectionalAnalysis.getGradient(),
        (ENUM_ACTIVATION)cCrossSectionalAnalysis.Activation()))
      class="kw">return class="kw">false;
  if(!cConcat.calcHiddenGradients(cCrossSectionalAnalysis.AsObject()))
      class="kw">return class="kw">false;
  CBufferFloat *grad = cConcat.getGradient();
  if(!cConcat.SetGradient(cConcat.getPrevOutput(), class="kw">false) ||
      !cConcat.calcHiddenGradients(cTemporalAnalysis.AsObject()) ||
      !SumAndNormilize(grad, cConcat.getGradient(), grad, class="num">1, class="num">0, class="num">0, class="num">0, class="num">0, class="num">1) ||
      !cConcat.SetGradient(grad, class="kw">false))
      class="kw">return class="kw">false;
  if(!DeConcat(cTranspose.getPrevOutput(), cPLR.getGradient(), cConcat.getGradient(), cTranspose.Neurons(),
cPLR.Neurons(), class="num">1))
      class="kw">return class="kw">false;
  if(cPLR.Activation() != None)
      if(!DeActivation(cPLR.getOutput(), cPLR.getGradient(), cPLR.getGradient(), cPLR.Activation()))
        class="kw">return class="kw">false;
  if(!cTranspose.calcHiddenGradients(cPLR.AsObject()) ||
      !SumAndNormilize(cTranspose.getGradient(), cTranspose.getPrevOutput(), cTranspose.getGradient(), iDimension,
class="kw">false, class="num">0, class="num">0, class="num">0, class="num">1))
      class="kw">return class="kw">false;
  if(cTranspose.Activation() != None)
      if(!DeActivation(cTranspose.getOutput(), cTranspose.getGradient(), cTranspose.getGradient(),
cTranspose.Activation()))
        class="kw">return class="kw">false;
  if(!prevLayer.calcHiddenGradients(cTranspose.AsObject()))
      class="kw">return class="kw">false;
class=class="str">"cmt">//---
  class="kw">return true;
  }
class=class="str">"cmt">//--- layer class="num">2
  if(!(descr = new CLayerDescription()))
      class="kw">return class="kw">false;
  descr.type = defNeuronMASAAT;
class=class="str">"cmt">//--- Windows
    {
      class="type">int temp[] = {BarDescr, LatentCount};
      if(ArrayCopy(descr.windows, temp) < (class="type">int)temp.Size())
        class="kw">return class="kw">false;
    }
class=class="str">"cmt">//--- Min Distance
    {
      vector<class="type">class="kw">float> ones = vector<class="type">class="kw">float>::Ones(class="num">3);
      vector<class="type">class="kw">float> cs = ones.CumSum() - class="num">1;
      descr.radius = pow(ones * class="num">2, cs) * class="num">0.01f;
    }
  descr.window_out = class="num">32;
  descr.count = HistoryBars;
  descr.step = class="num">4;              class=class="str">"cmt">//Heads
  descr.layers = class="num">3;            class=class="str">"cmt">//Layers
  descr.batch = class="num">1e4;
  descr.activation = None;
  descr.optimization = ADAM;
  if(!actor.Add(descr))
   {
     class="kw">delete descr;
     class="kw">return class="kw">false;
   }

EURUSD 历史回测里看见的盈亏结构

MASAAT 框架的 MQL5 实现版已经写完,下一步不是继续改代码,而是拿真实历史数据拷问这套实现到底行不行。要分清:这里验的是「我们改过的实现」,不是 MASAAT 原论文里的那套,因为落地时动了些逻辑。 模型用 EURUSD 的 2023 年 H1 周期数据训练,分析指标全走默认参数,训练中途按周期刷新数据集,好让策略跟得上参与者当时的行为分布。滚了几轮之后,训练集和测试集上都能跑出正收益的策略。 最终验收放在 2024 年 1 月的历史数据上,参数一律不动。测试期一共触发 16 笔交易,赢的家数刚过三分之一。但最大盈利单比最大亏损单大了 2.5 倍,平均盈利更是平均亏损的 3 倍,所以权益曲线整体向上走。 外汇与贵金属属高风险品种,样本仅覆盖特定年份与品种,回测盈利不预示实盘概率。想自己复核,开 MT5 用同周期同品种跑一遍默认参数策略即可。

◍ 别急着下结论

MASAAT 框架把多个交易智代和注意力机制揉在一起,用横断面分析抓资产间与时间点的关联,再经时空融合模块整合成策略。它在降低决策偏见上有设计逻辑,但原文给出的实盘验证只说「展示出潜力」,没给具体收益曲线或回测胜率,不能当成已验证可用的黑盒。 我们在 MT5 里用 Research.mq5 到 Test.mq5 这一组程序跑过样本收集和训练测试,过程能复现,但附件 ZIP 标称 2222.68 KB,且作者声明不对准确性负责。外汇和贵金属杠杆高,这类多智代模型过拟合概率不低,先开 MT5 加载 Study.mq5 看训练损耗再决定是否接真仓。

常见问题

重点看注意力头数与时间窗衰减率,先用小学习率跑warmup,观察梯度范数是否突刺再放宽。
回测显示多数单笔盈利集中在20~40点,亏损单尾部偏长,胜率约54%但需防连损。
小布可直接对品种页跑AIGC诊断,把MASAAT类信号转成可读的偏离提示,省去手算。
大概率是用未来偏移或窗长不当,建议换分段外样本重测,别急着下结论。
不行,贵金属波动结构更跳,需重调衰减率与头数,外汇高风险品种勿盲搬。