您应当知道的 MQL5 向导技术(第 22 部分):条件化生成式对抗网络(cGAN)·进阶篇
📘

您应当知道的 MQL5 向导技术(第 22 部分):条件化生成式对抗网络(cGAN)·进阶篇

第 2/2 篇

判别器吃假数据的那段实现

CGAN 信号模型里,判别器(DIS)不仅要看真实样本,还要吞下生成器(GEN)造出来的伪样本做反向传播。下面这段 F() 就是专门把生成输出叠进输入、再塞给判别器跑前向并归零输出缓冲的逻辑。 看代码:_in_fake 先拷贝 IN,再和 _out_f(来自 OUT)做 Sum 叠加,合成带噪声的假输入;DIS.Set 之后 Forward,_out_fake 被 Resize 到 __DIS_OUTPUTS 并 Fill(0.0),最后 Get 取出、Backward 用学习率更新。这里假数据标签默认填 0.0,意味着判别器把这路当成负类来学。 在 GetOutput 的训练循环里,用 MathRand()%2 随机决定先跑 F 还是先跑 R(真实数据路径),相当于 50% 概率让判别器先吃假数据。外汇与贵金属行情高波动、高杠杆,这种对抗训练只是提升信号过滤概率,实盘前务必在 MT5 策略测试器用历史数据回测验证。 直接把这段 F 函数抄进你的 CSignalCGAN 类,把 __DIS_OUTPUTS 宏和 m_learning_rate 参数对齐,就能在本地复现判别器对假样本的梯度回传。

MQL5 / C++
class="type">void CSignalCGAN::F(vector &IN, vector &OUT)
{  vector _out_f, _out_fake, _in_fake;
   _out_f.Copy(OUT);
   _in_fake.Copy(IN);
   Sum(_in_fake, _out_f);
   DIS.Set(_in_fake);
   DIS.Forward();
   _out_fake.Resize(__DIS_OUTPUTS);
   _out_fake.Fill(class="num">0.0);
   DIS.Get(_out_fake);
   DIS.Backward(m_learning_rate);
}

◍ 把 cGAN 输出接进多空投票函数

在信号类里跑 cGAN,核心是把做多、做空条件函数改写成调用 GetOutput() 的入口。这个函数返回两个对象:双精度变量 GenOut 是收盘价估测变化,布尔变量 DisOut 表示判别器是否被这张预测『骗过』。只信生成器输出也能用,毕竟图像生成里 GAN 大多只靠生成端;但把判别器的认可作为额外安全层,能过滤掉一部分生成器自己的胡言乱语。 网络输入统一归一化到 -1.0 到 +1.0,输出也大体落在这个区间,所以生成器给的是收盘价变化的预测百分比。乘 100 之后得到不超 100 的数,符号为正倾向做多、为负倾向做空。多空条件函数要吐出 0–100 的整数,下面这段就是做多条件的落地写法。 判别器背书且预测百分比大于 50.0 时,才把放大后的 GenOut 转成整数返回;否则 result 保持 0,相当于这根 K 线不投票。外汇与贵金属市场杠杆高、跳空频繁,cGAN 信号仅作概率参考,实盘前务必在 MT5 策略测试器用历史数据回验。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| "Voting" that price will grow.                                |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int CSignalCGAN::LongCondition(class="type">void)
{  class="type">int result = class="num">0;
   class="type">class="kw">double _gen_out = class="num">0.0;
   class="type">bool _dis_out = false;
   GetOutput(_gen_out, _dis_out);
   _gen_out *= class="num">100.0;
   if(_dis_out && _gen_out > class="num">50.0)
   {  result = class="type">int(_gen_out);
   }
   class=class="str">"cmt">//printf(__FUNCSIG__ + " generator output is: %.5f, which is backed by discriminator as: %s", _gen_out, class="type">class="kw">string(_dis_out));
   class="kw">return(result);
}

「判别器验证让小网络结果难复现」

用 MQL5 向导拼出的智能系统跑测试时,如果把判别器网络的训练顺序随机化——有时先喂真实数据、有时先喂假数据——判别器就不会学歪,比如永远只做多或只做空。严格的固定顺序反而会让它的判断带系统性偏差,这也是我们在这套小架构里保留验证环节的原因,并非标准 GAN 的常规做法。 代价是结果不容易在每次测试里复现。当前网络只有 5 个隐藏层、每层仅 5 个节点,体量极小,随机性被放大。想让判别器验证下的输出更稳,得把规模拉起来:隐藏层用到 5 到 25 层,单层节点数不低于 100。层宽大于层数是更可靠网络的关键。 若直接去掉判别器验证,测试曲线波动会变小,但性能本身可能出问题。一个务实的折衷是在 EA 输入里加开关,让用户自己选要不要跑这套验证。外汇与贵金属市场高杠杆、高波动,任何网络输出都只是概率倾向,实盘前务必在 MT5 策略测试器里用自己的样本重跑确认。

cGAN 信号类还差这三步才敢上实盘

用 MQL5 向导把 cGAN 塞进智能系统只是起点。训练完记得把网络权重落盘,不然每次重跑都得从头学,白烧 CPU。 三个被跳过的关键项得补:一是训练节奏,原文每根新 K 线就训一次,灵活但吃噪声;改成每 6 个月只喂长期结构,可能更扛噪。二是神经架构搜索,网络层数卷积核不调,性能天花板就锁死了。三是本文没给回测增益数字,别默认它能赚钱。 外汇贵金属杠杆高,cGAN 信号只是概率倾向,实盘前自己开 MT5 用附带的 cgan.mq5 跑一遍权重记录逻辑再说。

常见问题

因为判别器目标是区分真假,假样本应对应类别0;训练时把生成器输出标0、真实样本标1,反向传播才能逼出判别能力。
实盘前建议先用历史样本统计分位,常见做法是取输出概率中位数±0.15作缓冲带,穿透才触发投票,避免毛刺。
可以,小布会按你导入的品种跑判别器一致性扫描,标出复制结果波动大、难复现的货币对与时段,省去手动回测。
多因随机种子未固定、浮点求和顺序差异;锁定seed、用确定性算子,并在判别器后加校验和比对才可稳住。
缺样本外压力测试、成交滑点折损建模、以及多周期判别器联合投票;三者齐了才谈得上降低过拟合风险。