您应当知道的 MQL5 向导技术(第 41 部分):深度-Q-网络·综合运用
📘

您应当知道的 MQL5 向导技术(第 41 部分):深度-Q-网络·综合运用

第 3/3 篇

「奖励向量的三态切分与 Critic 目标计算」

这段逻辑把单步奖励 _reward 压成三选一的热编码向量:大于 0 填 _rewards[0]、等于 0 填 _rewards[1]、小于 0 填 _rewards[2],每类固定赋 1.0。它对应 DQN 里「涨 / 平 / 跌」三种环境反馈的离散化,训练时不会混用连续值。 随后用 QL.CriticTarget(_rewards, Learning.dqn_target) 生成Critic目标向量,再交给 output.LossGradient(_target, THIS.loss_typical) 算梯度。_last_loss 被实时回写,方便后续早停或学习率衰减判断。 在 MT5 里验证时,把 _rewards 数组打印出来即可确认分类是否偏移:若样本里震荡行情多,_rewards[1] 命中率可能明显高于另外两维,这时要怀疑奖励尺度是否被压扁。外汇与贵金属波动突变频繁,此类离散奖励对外汇高风险品种易在极端滑点下失真。

MQL5 / C++
   }
   else if(_reward == class="num">0.0)
   {  _rewards[class="num">1] = class="num">1.0;
   }
   else if(_reward < class="num">0.0)
   {  _rewards[class="num">2] = class="num">1.0;
   }
   vector _target = QL.CriticTarget(_rewards, Learning.dqn_target);
   _last_loss = output.LossGradient(_target, THIS.loss_typical);
   }

◍ 双网络与奖励标签的拼接逻辑

这段片段在干一件事:把马尔可夫状态塞进在线网络和目标网络,再用两根 K 线差分算出分类标签喂给 Q 学习。外汇与贵金属行情高波动,这种标签对噪声极敏感,实盘前务必在 MT5 策略测试器里跑通。 先建环境向量 _in_e 并初始化为长度 1,交给 MLP.QL.Environment 绑定行、列、环境三要素。随后取 _in_e 末位状态设定 Markov 坐标,构造长度为 2 的输入 _in 存入行列号,送进 DQN_ONLINE 前向推理;同样用倒数第二位状态给 DQN_TARGET 前向,把输出写进 m_learning.dqn_target 作基准。 奖励标签来自 CopyRates 拉取的 2 根柱:从偏移 8、索引 ii 取 _target_data,偏移 8、索引 ii+1 取 _target_data_old,二者相减得到差分。_type 用差分第二维减 _in_row[1],按负、零、正映射成 0/1/2 类,置 _target 对应位为 1.0 后回写 MLP。仅在 i==m_epochs && ii==m_train_set 时触发 DQN_ONLINE.Backward 做最终反向更新。 别把正态当圣经:差分标签在跳空时可能连续同号,训练集若含重大数据行情,分类会偏成单边,建议手动剔除异常 ii 段再训。

MQL5 / C++
vector _in_e;
_in_e.Init(class="num">1);
MLP.QL.Environment(_in_row, _in_col, _in_e);
class=class="str">"cmt">//
class="type">int _row = class="num">0, _col = class="num">0;
MLP.QL.SetMarkov(class="type">int(_in_e[_states - class="num">1]), _row, _col);
_in.Init(class="num">2);
_in[class="num">0] = _row;
_in[class="num">1] = _col;
DQN_ONLINE.Set(_in);
DQN_ONLINE.Forward();
class=class="str">"cmt">//
MLP.QL.SetMarkov(class="type">int(_in_e[_states - class="num">2]), _row, _col);
_in_old.Init(class="num">2);
_in_old[class="num">0] = _row;
_in_old[class="num">1] = _col;
DQN_TARGET.Set(_in_old);
DQN_TARGET.Forward();
m_learning.dqn_target = DQN_TARGET.output;
if(ii > class="num">0)
{  vector _target, _target_data, _target_data_old;
   if
   (
     _target_data.Init(class="num">2) &&
     _target_data.CopyRates(m_symbol.Name(), m_period, class="num">8, ii, class="num">2) &&
     _target_data.Size() == class="num">2
     &&
     _target_data_old.Init(class="num">2) &&
     _target_data_old.CopyRates(m_symbol.Name(), m_period, class="num">8, ii + class="num">1, class="num">2) &&
     _target_data_old.Size() == class="num">2
   )
   {  _target.Init(__MLP_OUTPUTS);
      _target.Fill(class="num">0.0);
      _target_data -= _target_data_old;
      class="type">class="kw">double _type = _target_data[class="num">1] - _in_row[class="num">1];
      class="type">int _index = (_type < class="num">0.0 ? class="num">0 : (_type > class="num">0.0 ? class="num">2 : class="num">1));
      _target[_index] = class="num">1.0;
      MLP.Get(_target);
      if(i == m_epochs && ii == m_train_set)
      {  DQN_ONLINE.Backward(m_learning, i);

目标网络同步与动作判定的代码落点

这段片段处理的是 DQN 里目标网络(DQN_TARGET)的周期性同步逻辑。当计数器 m_target_counter 达到预设的 m_target_counts 时,就把在线网络 DQN_ONLINE 的权重拷给目标网络,随后计数器归零,避免在每一步都硬更新导致训练震荡。 同步完之后调用 MLP.Backward(m_learning, i) 做反向传播,i 通常是当前样本索引。外层大括号表明这段处在某个训练循环内,实际跑起来时建议把 m_target_counts 设在 100~1000 之间观察回测稳定性——外汇与贵金属市场的高波动可能让过小的值引发策略频繁跳变。 最后一行 Output 的判定很直接:比较 MLP 输出的三个神经元,取最大值对应的下标 0、1 或 2,作为智能体这一帧选出的动作类别。你可以在 MT5 里把这段接进自己的 EA 训练例程,打印 Output 分布看是否长期偏向某一类动作。

MQL5 / C++
if(m_target_counter >= m_target_counts)
{	DQN_TARGET = DQN_ONLINE;
		m_target_counter = class="num">0;
}
MLP.Backward(m_learning, i);
			}
			}
		}
		Output = (MLP.output.Max()==MLP.output[class="num">0]?class="num">0:(MLP.output.Max()==MLP.output[class="num">1]?class="num">1:class="num">2));
		}
	}
}
}

「EURGBP 日线回测的可交易性边界」

用深度 Q 网络在 2023 年 EURGBP 日线周期上训练并测试了这套 MLP 策略,结果在样本内严格证明了策略具备可交易性。 需要注意,这个结论仅基于 2023 年单币种日线数据,不必然在未来行情中复现;外汇与贵金属属高风险品种,实盘前应在 MT5 策略测试器换周期与品种交叉验证。 若想自己复现,直接把训练好的模型接进策略测试器,选 EURGBP D1、2023 全年,观察权益曲线与交易次数是否落在样本内区间。

◍ 深度Q网络之外的下一步

前面几节把深度Q网络这套强化学习替代算法在MT5向导里的实现跑通了,并用汇编出的智能系统做了实测。强化学习作为区别于监督、无监督的第三类训练路径,在外汇与贵金属这种高波动、高杠杆品种上,更像一个概率寻优器而非确定性信号源。 后续文章会把它从「替代算法」推到「主模型+信号发生器」的位置去验证。当前附带的 wz_41.mq5(7.3 KB)和 SignalWZ_41.mqh(13.92 KB)可直接丢进 MT5 回溯 EURUSD 或 XAUUSD 的 M15,看奖励函数收敛前后的胜率偏移。 这类策略实盘前务必用小资金过一遍点差与滑点,杠杆市场里回测漂亮不等于活下来的概率高。

常见问题

三态切分(正/零/负)能让Critic更快区分可交易与不可交易区间,降低稀疏奖励下的误判;实操中在奖励函数里用分支返回+1/0/-1即可。
先在经验回放里把state、action、reward三元组拼好,再进主网络算Q、目标网络算Q_target;动作判定放在epsilon贪心采样后、环境步进前。
可以,小布盯盘的AIGC已内置策略诊断,打开对应品种页就能看EURGBP日线的可交易性边界和信号质量,不用自己搭回测。
日线样本外易过拟合,建议只把模型输出当概率倾向而非下单依据;实盘前先用分段walk-forward验证边界稳定性。
优先补目标网络软同步(tau混合)和奖励归一化,否则训练易抖;之后再考虑换Double-DQN减估值偏高。