交易中的神经网络:点云分析(PointNet)·综合运用
编码器结构里的梯度交换与层定义
在反向传播阶段,先把 cTurned1 的梯度通过 OrthoganalLoss 做正交约束,失败就直接返回 false 中断训练。随后用 NeuronOCL.getGradient() 取出临时梯度指针 temp,再把 cTurned1 的梯度塞给 NeuronOCL、把 temp 还给 cTurned1,相当于两个网络分支互换梯度缓冲。 梯度互换后调用 NeuronOCL.calcHiddenGradients 计算隐藏层梯度,再用 SumAndNormilize 把 NeuronOCL 与 cTurned1 的梯度按权重 1 累加归一化(参数序列 1,false,0,0,0,1 表示不翻转、偏移全 0、缩放为 1),任一步返回 false 都会中止。这套操作在 Encoder 的对称结构里保证了两端梯度可联合更新。 CreateEncoderDescriptions 负责把编码器各层描述压进 CArrayObj。输入层用 defNeuronBaseOCL,节点数 = HistoryBars * BarDescr,激活函数为 None,优化器 ADAM;紧接着 defNeuronBatchNormOCL 做批归一化,batch 设成 1e4,节点数与上层相同。 第三层 defNeuronPointNetOCL 是重点:window=BarDescr(每根 BAR 的变量数),count=HistoryBars(时间步单元数),window_out=LatentCount(潜变量维度),step=int(true) 表示同时用输入与特征变换。最后接 defNeuronSoftMaxOCL 输出 LatentCount 个概率,layers=1。外汇与贵金属行情下用此类结构做特征压缩,过拟合风险高,实盘前务必在 MT5 用历史数据回测验证。
class="kw">return false; if(!OrthoganalLoss(cTNet1, true)) class="kw">return false; CBufferFloat *temp = NeuronOCL.getGradient(); NeuronOCL.SetGradient(cTurned1.getGradient(), false); cTurned1.SetGradient(temp, false); if(!NeuronOCL.calcHiddenGradients(cTNet1.AsObject())) class="kw">return false; if(!SumAndNormilize(NeuronOCL.getGradient(), cTurned1.getGradient(), NeuronOCL.getGradient(), class="num">1, false, class="num">0, class="num">0, class="num">0, class="num">1)) class="kw">return false; } class=class="str">"cmt">//--- class="kw">return true; } class="type">bool CreateEncoderDescriptions(CArrayObj *&encoder) { class=class="str">"cmt">//--- CLayerDescription *descr; class=class="str">"cmt">//--- if(!encoder) { encoder = new CArrayObj(); if(!encoder) class="kw">return false; } class=class="str">"cmt">//--- Encoder encoder.Clear(); class=class="str">"cmt">//--- Input layer if(!(descr = new CLayerDescription())) class="kw">return false; descr.type = defNeuronBaseOCL; class="type">int prev_count = descr.count = (HistoryBars * 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">1 if(!(descr = new CLayerDescription())) class="kw">return false; descr.type = defNeuronBatchNormOCL; descr.count = prev_count; descr.batch = class="num">1e4; 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 = defNeuronPointNetOCL; descr.window = BarDescr; class=class="str">"cmt">// Variables descr.count = HistoryBars; class=class="str">"cmt">// Units descr.window_out = LatentCount; class=class="str">"cmt">// Output Dimension descr.step = class="type">int(true); class=class="str">"cmt">// Use input and feature transformation descr.batch = class="num">1e4; 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 = defNeuronSoftMaxOCL; descr.count = LatentCount; descr.activation = None; descr.optimization = ADAM; descr.layers = class="num">1; if(!encoder.Add(descr)) {
「对象句柄清理的失败分支」
上面这段 MQL5 片段出现在自定义指标或 EA 的初始化收尾处,核心是当描述符对象无法正确创建时,先释放已分配的 descr 内存,再返回 false 通知调用方初始化失败。 很多新手会漏掉 delete descr 这一步,导致 MT5 终端在重复加载脚本时出现隐性句柄泄漏;在回测中若每小时重载一次指标,连续 24 小时可能堆积数十个未释放描述符。 return true 处在 //--- 注释之后,意味着前面所有资源校验都通过后,才认为对象构建可用。开 MT5 随便建个指标把这段塞进 OnInit 尾端,故意让 descr 创建失败,能在 Experts 日志里看到返回 false 后的中止加载行为。
class="kw">delete descr; class="kw">return false; } class=class="str">"cmt">//--- class="kw">return true; }
◍ EURUSD 实盘数据上的初步回测表现
我们用 2023 年 EURUSD 的 H1 历史数据训练 PointNet 改造后的点云模型,测试段取 2024 年 1 月同品种同周期,指标均跑默认参数。环境状态编码器与参与者策略同步迭代,数据集随策略更新保持时效,避免用陈旧分布喂网络。 模型训完若干轮后在训练集和测试集都转盈。测试窗口共成交 52 笔,胜率 55.77%,多空持仓 24 对 28 基本均衡;最大与平均盈利均大于对应亏损,盈利因子 1.76,余额曲线抬头。 但 1 个月样本加 52 笔交易体量太小,没法断言该策略在更长周期能维持稳定。外汇与贵金属杠杆高、滑点跳空频繁,这类浅测试结论仅作可复现起点,建议自己在 MT5 用 2023–2024 样本重跑确认。
把工具请下神坛
PointNet 这套直接吃点云输入的架构,在 MT5 里跑通了从样本收集到策略测试的全链路:Research.mq5 到 Test.mq5 五个 EA 加两套类库,把价格形态当多维点集喂给模型,省掉了转二维图像的麻烦。实测在真实历史数据上训出来的政策,策略测试器里给出了有前景的结果,但误差率和过拟合风险都还没压到可实盘的程度。 外汇和贵金属是高杠杆品种,这套方案目前只是演示性质,真要上线得自己把 Real ORL 采样和 OpenCL 核重写一遍,在多个品种多周期上把回测样本量拉满再说话。 工具再花哨也只是概率放大器,别把它供起来当圣杯,开 MT5 把 MQL5.zip 里的 NeuroNet.mqh 拆开看两层全连接怎么接 PointNet 特征,比听谁吹框架更有用。