您应当知道的 MQL5 向导技术(第 41 部分):深度-Q-网络·综合运用
「奖励向量的三态切分与 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] 命中率可能明显高于另外两维,这时要怀疑奖励尺度是否被压扁。外汇与贵金属波动突变频繁,此类离散奖励对外汇高风险品种易在极端滑点下失真。
} 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 段再训。
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 分布看是否长期偏向某一类动作。
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,看奖励函数收敛前后的胜率偏移。 这类策略实盘前务必用小资金过一遍点差与滑点,杠杆市场里回测漂亮不等于活下来的概率高。