神经网络在交易中的应用:用于多元时间序列预测的 LSTM 优化(终篇)
概述
在上一篇文章中,我们研究了 DA-CG-LSTM 框架的理论基础,该框架专门用于解决涉及动态多元时间序列的复杂预测任务。
现代金融市场是复杂的动态系统,其中众多因素持续相互作用:宏观经济指标、新闻事件、利率变化、主要市场参与者的行为,以及许多其他往往隐含的变量。代表价格和交易量动态的时间序列是了解这些过程的主要信息来源。然而,分析此类数据需要一个模型,该模型既能捕捉长期趋势和短期波动,又能区分真正重要的信号与背景噪声。
传统的时间序列分析方法往往不够灵活,且对所涉及的各种市场因素缺乏敏感性。它们在高度波动的市场条件下,选择性关注关键特征和时间间隔的能力有限,导致预测准确性下降。这些限制成为了 DA-CG-LSTM 框架开发的起点 — 该框架将双重注意力机制与改进的循环块结构相结合。
DA-CG-LSTM 的一个主要优势是其处理多模态数据的灵活性。在实际交易场景中,不仅需要分析价格水平,还需要分析衍生指标和外部经济事件。上述框架能够在每个时间步动态适应特征重要性的变化,自动将注意力重新分配给最相关的信息源。因此,该模型能够有效识别众多特征之间的复杂关系,并根据当前市场环境调整其预测结果。
架构中实现的双阶段注意力机制尤其有价值。在第一层,模型聚焦于特征,判断哪些特征当前对市场动态的影响最大。在第二层,注意力转向时间区间。该模型评估历史数据的哪些部分对于预测最可能的走势最具信息价值。这一两阶段流程实现了深度信息过滤,使系统能够忽略次要数据,专注于真正重要的信号,无论这些信号是涉及重大趋势转变还是局部异常。
DA-CG-LSTM 的另一个重要优势是其对噪声数据具有很高的鲁棒性,这对于在真实市场环境中部署至关重要。金融时间序列通常包含众多随机波动,这些波动并非由潜在的市场机制引起,而是由各种外部或内部随机因素导致。框架内改进的 CG-LSTM 模块充当自适应滤波器,能够动态地降低噪声特征的影响。通过其内部机制来管理特征和时间步长的权重,该模型专注于识别稳定、反复出现的价格行为模式,从而显著提升预测性能。
DA-CG-LSTM 的另一个显著特点是它能够高效地处理长时间序列,而不会失去对短期变化的敏感性。在传统的循环网络中,增加分析序列的长度通常会导致梯度消失,并降低长距离依赖建模的质量。在该框架作者提出的架构中,这一问题通过基于主要注意力的早期信息过滤过程以及 CG-LSTM 块中专门设计的记忆结构来解决。这使得该模型既能持续关注长期趋势,又能迅速应对短期波动,如新闻发布或日内波动率飙升。
因此, DA-CG-LSTM 框架成功地结合了对多维数据的适应性、深度信息过滤能力、噪声鲁棒性和在较长时间范围内良好的可训练性。这些特质使其成为构建现代时间序列预测系统的强大工具。
DA-CG-LSTM 算法基于通过几个关键模块对数据进行顺序处理。
在第一阶段,多元时间序列的原始表示会经过一个初级注意力模块,该模块对每个时间步长上各个特征的重要性进行加权。这使得模型能够压缩并强调最相关的信息,同时消除不必要的信息噪声。
在下一阶段,数据被传递给二级注意力模块,重点转移到时间间隔上。该模型评估历史数据的哪些部分在生成未来预测中起决定性作用。
然后将处理后的数据输入到修改后的 CG-LSTM 模块中,在该模块中,特征会根据其内在重要性和交互性进行聚合。CG-LSTM 模块与传统的 LSTM 模块不同之处在于,它加入了额外的控制机制,这些机制会根据特征和时间间隔的重要性来影响记忆单元的操作。这使得能够更准确地建模市场因素之间复杂的多维依赖关系。
然后,通过两个注意力级别和 CG-LSTM 模块形成的最终聚合表示,用于预测目标变量 — 例如,资产的未来价格或其走势方向。
这种多阶段架构使模型能够同时捕捉短期和长期依赖关系,最大限度地减少噪声的影响,并根据当前市场环境自适应地调整其数据处理策略。
下面展示了作者提供的 DA-CG-LSTM 框架示意图。

在本文中,我们将使用 MQL5 对 DA-CG-LSTM 框架的作者提出的方法进行我们自己的实现,从而迈出下一步。主要重点是设计模型架构。
模型架构
如前所述, DA-CG-LSTM 框架围绕两个基本组件构建:注意力模块和改进的 CG-LSTM 循环模块。这些要素共同构成了一个稳健的架构,为模型提供了所需的灵活性、噪声鲁棒性以及捕捉复杂多层次时间依赖性的能力,这些都是金融市场应用所必需的。在高波动性和市场不确定性的条件下,这些特性不仅重要,而且对于构建可靠的交易系统至关重要。
在上一篇文章的实践部分,我们详细研究了在 MQL5 中实现 CG-LSTM 模块的过程。由此产生的组件成功执行了三项关键功能:特征过滤以消除不必要的噪声,高效管理模型的内部状态以保留长期信息,以及跨多个时间尺度的数据聚合。它既能抑制非结构化噪声,又能保持稳定的学习动态,从而能够构建在较长历史时期内保持预测精度的模型。
为了识别和分析特征和时间序列之间的关系, DA-CG-LSTM 的作者提出了线性注意力机制的增强版本。在我们的实现中,我们决定使用之前开发的 CNeuronLinearAttention 对象,该对象是在 Hidformer 框架开发过程中创建的。尽管这两种解决方案在架构细节上有所不同,但它们的基本概念是一致的。
考虑到这些因素,我们决定使用现有的注意力模块,而不进行额外的修改。这显著加快了开发进程,并将与集成新的、未经充分测试的解决方案相关的风险降至最低。因此,我们现在拥有构建 DA-CG-LSTM 框架所需的一整套组件。
下一步合乎逻辑的步骤是基于这些组件设计可训练模型的架构。在这里,我们超越了预测未来时间序列值的传统任务。在金融市场中,重要的是不仅要预测价格动态,还要在做出交易决策时有效利用这些预测,以优化风险和潜在收益。
为了实现这一目标,我们融合了 HiSSD 架构中的最佳理念,该架构在噪声抑制和复杂非线性依赖关系的处理方面已证明具有很高的有效性。通过构建一个用于表征市场环境状态的全局和局部智能体技能的潜在空间,将 DA-CG-LSTM 结构集成到编码器中。这个潜在空间作为后续分析与决策的基础表示。
在此基础结构之上,我们实现了演员-导演-评论家强化学习框架。这种集成不仅使系统能够生成预测,还能从策略角度选择能最大化预期收益的动作。
可训练模型的架构在 CreateDescriptions 方法中定义。它的参数接收指向六个动态数组对象的指针,每个数组对象对应于整体模型架构的一个不同层级:
- 环境状态编码器 — 负责构建智能体全局技能的潜在空间。它概括了有关当前市场状况的信息,揭示了影响市场动态的因素之间隐藏的关系。
- 底层控制器 — 根据分析的环境特征生成智能体的本地技能。通过在全局技能背景下解读这些因素,控制器综合了一个可能动作的张量,该张量代表了最有前景的交易场景,同时考虑了短期和长期的市场趋势。
- 演员 — 从控制器接收动作张量,并根据当前账户状态、风险水平和预定义的战略目标对其进行评估,从而生成最终的交易决策,旨在最大化利润,同时控制可接受的损失。
- 概率趋势预测模型 — 通过引入预期市场方向的概率表示,丰富全局智能体技能,从而有助于形成更具信息量的全局智能体技能。这使得该模型能够考虑到市场过程的概率特性,并构建出更为稳健的策略。
- 导演 — 执行初步行动筛选,降低与过高风险相关的决策的可能性。它引导演员的策略走向更加保守和可靠的方案,以符合当前的市场状况。
- 评论家 — 评估所选策略在未来时间范围内的有效性,并调整智能体的动作,以在保持合理风险水平的同时最大化长期累积利润。
CreateDescriptions 方法会对所有传入的指针进行严格验证。必要时,会创建新的描述对象实例,以确保模型架构在其构建的每个阶段的完整性和正确性。
bool CreateDescriptions(CArrayObj *&encoder, CArrayObj *&task, CArrayObj *&actor, CArrayObj *&probability, CArrayObj *&director, CArrayObj *&critic ) { //--- CLayerDescription *descr; //--- if(!encoder) { encoder = new CArrayObj(); if(!encoder) return false; } if(!task) { task = new CArrayObj(); if(!task) return false; } if(!actor) { actor = new CArrayObj(); if(!actor) return false; } if(!probability) { probability = new CArrayObj(); if(!probability) return false; } if(!director) { director = new CArrayObj(); if(!director) return false; } if(!critic) { critic = new CArrayObj(); if(!critic) return false; }
让我们先来描述一下环境状态编码器的架构。与之前的工作一样,我们将原始输入数据输入到一个具有足够维度的全连接层中。这一层作为模型的入口,直接接收原始输入数据,无需任何初步的人工预处理。
//--- Encoder encoder.Clear(); //--- Input layer if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronBaseOCL; int prev_count = descr.count = (HistoryBars * BarDescr); descr.activation = None; descr.optimization = ADAM; if(!encoder.Add(descr)) { delete descr; return false; }
信息来源包括直接从交易终端获取的数据:报价、交易量、市场情绪指标以及其他相关参数。我们特意省略了模型外部进行的任何预处理。这一策略无疑使训练过程变得复杂,因为它对模型自我学习和过滤噪声的能力提出了更高要求。然而,这种方法在实际部署中最终会带来更强的鲁棒性。
重要的是要理解,只有在实时操作过程中接收到的数据遵循与训练期间所用数据相似的分布时,训练好的模型才能提供可靠且可复现的结果。在模型外部进行手动预处理会增加出现不可预测偏差的风险。即使对过滤器或其参数进行微小的更改,也会从根本上改变输入数据的性质。因此,数据预处理必须成为模型架构本身不可或缺的一部分。
为了最大限度地降低这些风险并提高训练质量,我们将初始数据处理阶段直接整合到了编码器结构中。该功能由带有受控噪声注入机制的批归一化层 CNeuronBatchNormWithNoise 实现。批归一化将异构多模态数据统一到同一尺度上,从而提高了训练稳定性并加速了模型收敛。此外,少量基于噪声的增强可以提升模型的泛化能力,从而在使用有限数据集时降低过拟合的风险。
//--- layer 1 if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronBatchNormWithNoise; descr.count = prev_count; descr.batch = 1e4; descr.activation = None; descr.optimization = ADAM; if(!encoder.Add(descr)) { delete descr; return false; }
然后将归一化后的数据传递给线性注意力模块,该模块负责分析每个时间步长内各个特征之间的相互依赖关系。
在这个阶段,重点在于正确解读数据的内部结构。虽然该模型处理的是时间序列,但在每个单独的时间步,它处理的都是描述环境状态的同一组固定特征。
鉴于每个时间切片上的数据结构具有重复性,我们决定使用一个共享的可训练参数矩阵来分析所有时间步。换句话说,该模型对整个时间序列应用了一种通用的、普遍的注意力机制。这使我们能够实现几个至关重要的效果:
- 提高了不同时间间隔下特征解释的一致性;
- 可训练参数数量的大幅减少,这在训练数据有限时尤为重要;
- 通过减少过拟合来增强泛化能力;
- 通过计算优化实现更快的训练。
//--- layer 2 if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronLinerAttention; prev_count = descr.count = HistoryBars; descr.window = BarDescr; descr.layers = 1; descr.window_out = 32; descr.batch = 1e4; descr.optimization = ADAM; descr.activation = None; if(!encoder.Add(descr)) { delete descr; return false; }
在分析了每个时间步的特征相互依赖性之后,下一个重要阶段是对输入数据进行时间分析。为了实现这一目标,我们首先对原始张量进行转置,使每个单独的特征都可以被视为随时间变化的观测序列。
然后将转置张量传递给第二个线性注意力模块,该模块专门用于分析时间动态。
值得注意的是,经过转置后,我们实际上得到了一组单变量时间序列,每个序列都代表了一个单一特征随时间的变化过程。这些特征可能属于不同的数据模态。重要的是,不同的模态可能会对相同的市场事件表现出不同的反应模式。因此,在这一阶段,我们采用了一种更为灵活的方法:为每个单变量序列分配其专属的可训练参数矩阵。这种机制使我们能够:
- 在解释每种模态的时间动态时,需考虑其特定特征;
- 识别不同特征对同一市场事件的独特响应模式;
- 提高模型对单个数据通道中微弱但重要的信号的敏感性;
- 避免将源自根本不同类型特征的信息混合在一起。
这种架构在金融市场中尤为有效,因为金融市场中的异构数据源可能会以不同的速度、幅度和方向偏差对基本面事件或技术事件作出反应。
//--- layer 3 if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronTransposeOCL; descr.count = HistoryBars; descr.window = BarDescr; descr.batch = 1e4; descr.optimization = ADAM; descr.activation = None; if(!encoder.Add(descr)) { delete descr; return false; } //--- layer 4 if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronLinerAttention; descr.count = 1; descr.window = HistoryBars; descr.layers = BarDescr; descr.window_out = 32; descr.batch = 1e4; descr.optimization = ADAM; descr.activation = None; if(!encoder.Add(descr)) { delete descr; return false; }
经过两个注意力层处理后,分析的数据获得了更为丰富的表示。它现在包含了关于特征之间的内部关系以及每种模态固有的特征时间依赖性的信息。然而,为了构建有效的金融市场决策策略,必须将这些数据汇总成更简洁、更有意义的表示形式。
内部增强的数据被传递到 CG-LSTM 模块,其中对前一阶段形成的单变量序列进行独立分析。值得注意的是,这种方法与 DA-CG-LSTM 框架的作者提出的原始设计有很大不同。在经典的 DA-CG-LSTM 架构中,循环单元处理与各个时间步对应的多模态表示。这种方法能够捕捉到复杂的跨模态依赖关系。
然而,在我们的项目中,我们特意选择了一种替代策略。我们进一步发展了 HiSSD 架构中提出的理念,其中特别强调对与单个智能体相关的单变量序列进行独立预测。这种方法使我们能够更灵活、更准确地捕捉特定模态的行为模式,同时最大限度地减少来自不同数据源的潜在跨模态噪声的影响。
CG-LSTM 中的这种数据处理方案提供了:
- 针对数据的特定方面,对隐藏状态进行更明确的专门化;
- 提高了模型对市场信息结构变化的鲁棒性;
- 增强了全局技能的可解释性,因为每个技能向量都与分析数据的特定模式相关联。
在设计循环模块时,我们做出了一个重要的架构决定:每个 CG-LSTM 元素的隐藏状态维度被设置为等于单个智能体的全局技能向量的大小。这使得每个单变量序列都能生成一个固定大小的输出表示,该表示能编码其长期行为的最重要方面。这些表述随后成为进一步决策过程的基础。
需要强调的是,全局技能矩阵是以完全可训练的方式构建的。该模型能够独立判断,在真实交易条件下,特征行为的哪些方面对于成功运行最为重要。
//--- layer 5 if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronCGLSTMOCL; descr.count = NSkills; // Common Skkills descr.window = HistoryBars; // Sequence descr.layers = BarDescr; // Variables descr.batch = 1e4; descr.activation = None; descr.optimization = ADAM; if(!encoder.Add(descr)) { delete descr; return false; }
我们还应该记住, HiSSD 框架的高级规划器通过编码潜在状态来学习构建全局技能,以便准确预测下一个系统状态。同样, DA-CG-LSTM 框架的主要目标是尽可能准确地预测多模态时间序列。其整体架构均围绕这一目标构建:复杂的注意力机制、强大的循环模块以及解码器,所有这些设计都是为了提取隐藏模式并提高预测性能。
然而,我们采用了截然不同的方法,并有意将该架构重新用于另一项任务:学习最具信息量的潜在表征 — 即所谓的全局智能体技能。我们的重点并非精确预测每个后续的时间序列值,而是构建一个内部市场表示,为学习最优智能体策略奠定坚实基础。
在此背景下,我们特意放弃了原 DA-CG-LSTM 解码器的复杂架构。其深度潜在空间分析机制可能会扭曲或重新解释全局技能,使其不太适合用于智能体控制任务。
相反,我们选择了一个由两个连续卷积层组成的极简解码器。该设计实现了对隐藏表示的直接处理,对全局技能结构的干扰最小,结果的可解释性高,并且能够独立处理单变量特征序列。
这种方法保留了学习到的潜在空间的完整性和价值,为更有效地训练智能体策略铺平了道路。
//--- layer 6 if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronConvOCL; descr.count = 1; descr.window = NSkills; descr.step = NSkills; int prev_out = descr.window_out = 4 * NForecast; prev_count=descr.layers = BarDescr; descr.activation = SoftPlus; if(!encoder.Add(descr)) { delete descr; return false; } //--- layer 7 if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronConvOCL; descr.count = 1; descr.window = prev_out; descr.step = prev_out; prev_out = descr.window_out = NForecast; descr.layers = prev_count; descr.activation = TANH; if(!encoder.Add(descr)) { delete descr; return false; }
为了使预测值与实际数据正确对齐,在解码器处理的最后阶段,我们将输出张量转置回其原始结构。
//--- layer 8 if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronTransposeOCL; descr.count = prev_count; descr.window = prev_out; descr.activation = None; if(!encoder.Add(descr)) { delete descr; return false; }
然而,即使在恢复其形状后,预测值仍然保持归一化形式。因此,下一个重要步骤是逆变换:恢复在批归一化过程中记录的原始特征分布的统计参数。
//--- layer 9 if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronRevInDenormOCL; descr.count = prev_count * prev_out; descr.layers = 1; descr.activation = None; if(!encoder.Add(descr)) { delete descr; return false; }
接下来我们来看底层控制器的架构。该模型在基于每个特定时间点环境分析构建本地智能体策略方面发挥着关键作用。
与全局技能编码器类似,控制器接收原始环境数据作为输入。事实上,它的架构基于相同的底层结构:通过随机噪声注入进行初始数据归一化,通过线性注意力模块实现的两阶段分析过程,以及用于顺序处理的 CG-LSTM 循环块。
全局技能和本地技能的根本区别不在于它们的构建机制,而在于训练过程中主体需要解决的任务。就全局技能而言,重点在于创造一个能够整合长期依赖关系和关键市场特征的普遍潜在空间。另一方面,本地技能则侧重于快速适应当前市场状况,并针对每个时间步制定具体的交易策略。
因此,我们只需复制技能编码器的架构即可。
//--- Task task.Clear(); //--- Task Encoder for(int i = 0; i <= LatentLayer; i++) if(!task.Add(encoder.At(i))) return false;
生成本地技能后,下一步是用智能体的全局技能中包含的上下文信息来丰富这些本地技能。为了实现这一目标,我们采用了一个两层交叉注意力模块。
智能体的本地技能充当查询,而所有智能体的全局技能充当键和值。这里的关键原则是,每个智能体的本地技能不是孤立地被解读,而是在整个系统潜在空间的更广泛背景下被解读。这有助于做出更明智的决策。
该模块的一个显著特点是其两阶段交叉注意力机制。在第一阶段,执行标准的交叉注意力操作。本地查询提取全局信息中最相关的片段。这使得智能体能够根据当前环境状况和全局技能中编码的策略趋势灵活地调整其短期行为。
在第二阶段,通过增加一个注意力层来进一步加强整合,该层能够揭示短期目标与长期战略指导之间更深层次、更复杂的关系。
正是这种本地与全局环境的融合,使得该模型能够生成更为平衡且理由充分的交易决策,从而增强了智能体对虚假信号和短期市场噪音的抵御能力。
//--- layer LatentLayer+1 if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronCrossDMHAttention; { int temp[] = {NSkills, NSkills}; // WIndow if(ArrayCopy(descr.windows, temp) < (int)temp.Size()) return false; } { int temp[] = {BarDescr, BarDescr}; // Units if(ArrayCopy(descr.units, temp) < (int)temp.Size()) return false; } descr.step = 4; descr.window_out = 32; descr.layers = 2; descr.batch = 1e4; descr.optimization = ADAM; descr.activation = None; if(!task.Add(descr)) { delete descr; return false; }
具备全局环境的本地技能随后被传输至决策模块。其中,两个连续的卷积层起着核心作用。这种架构能够高效地为每个智能体并行构建独立的 MLP 映射。
每个智能体都解释自己的局部潜在空间并做出决策,而不会直接干扰其他智能体的运行。卷积结构通过允许同时处理所有智能体来提供高计算效率,同时每个智能体都使用其自己的专用参数矩阵。
两个卷积层的序列增加了架构的灵活性:第一层执行初始特征聚合和变换,而第二层细化局部表示并生成最终的动作张量。这种方法提高了智能体在高度波动的金融市场条件下的行为适应性和稳健性。
//--- layer LatentLayer+2 if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronConvOCL; descr.count = 1; descr.window = NSkills; descr.step = NSkills; prev_out = descr.window_out = 4 * NActions; prev_count=descr.layers = BarDescr; descr.activation = SoftPlus; if(!task.Add(descr)) { delete descr; return false; } //--- layer LatentLayer+3 if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronConvOCL; descr.count = 1; descr.window = prev_out; descr.step = prev_out; prev_out = descr.window_out = NActions; descr.layers = prev_count; descr.activation = SIGMOID; if(!task.Add(descr)) { delete descr; return false; }
高级演员、导演和评论家模型的架构已完全从我们之前的工作中继承而来。它们的详细描述可以点击此链接查看。所以,我们现在不会过多赘述。附件中提供了所有模型架构的完整描述。
模型的训练
模型训练过程分为三个阶段:数据集生成、所有模型组件的离线训练以及随后的在线微调。这种方法将基于历史数据获得的基本稳定性与对当前市场条件的灵活适应相结合。
训练期间使用的所有程序均沿用了我们之前工作中的版本,未做任何更改;因此,我们不会详细讨论其算法。相反,我们将仅重温该过程的基本原则。
模型训练始于训练数据集的创建。为此,我们使用 Research.mq5 EA,并在 MetaTrader 5 策略测试器中运行它。收集 2024 年全年 EURUSD 货币对一分钟时间周期的历史数据。为了最大程度地减少计算负担,每次运行仅限于一个月的历史数据,而智能体之间的行为多样性则通过随机策略来实现。每根 K 线收盘后,市场状态、指标值、账户指标和智能体操作都会被记录下来,形成完整的体验回放缓冲区轨迹。
收集到的数据将作为所有组件离线训练的基础,该训练使用 Study.mq5 EA 执行。从回放缓冲区中随机采样轨迹和起始点,以构建序列状态的训练批次。为了加快收敛速度,采用了一种近乎完美的轨迹技术,使编码器能够预测未来几步。在此阶段,技能编码器、演员、导演和评论家都会接受训练,从而建立智能体的基本行为策略。
完成离线训练后,我们进入在线微调阶段。这里我们使用 StudyOnline.mq5 EA。主要重点是在导演和评论家的指导下对演员进行训练。每根新 K 线收盘后,系统都会分析环境状态,更新行动评估,并调整模型参数。目标模型的定期软更新有助于保持战略稳定性和适应性之间的平衡。
这种将离线知识积累与线上适应相结合的多阶段方法,在真实市场条件下运行时具有高效性和鲁棒性。
测试
只有使用未参与训练过程的数据,才能对已实施的解决方案和由此产生的交易策略进行客观评价。为此,我们选择了 2025 年 1 月至 3 月的测试期。使用训练集之外的历史数据可以消除过拟合的风险,并使结果具有真正的实际意义。
所有其他实验参数(市场环境、时间周期和终端设置)均保持不变。这样就确保了评估只衡量所学习策略的质量,而不受外部因素的干扰。
下面展示了测试结果,清楚地展示了该智能体在真实世界条件下的行为模型。


在测试期间,该模型执行了 37 笔交易。其中略多于 40% 的交易最终盈利。尽管如此,该模型仍能实现总体盈利,因为平均盈利交易额是平均亏损交易额的两倍多。利润因子达到 1.67。
结论
在本研究中,我们探讨了 DA-CG-LSTM 框架的理论基础,该框架通过引入 CG-LSTM 和双注意力机制等创新组件,有别于传统模型。这些元素能够更准确地提取时间依赖关系,并使模型能够捕捉短期波动和长期趋势。
在实践部分,我们提出了一种适用于训练交易智能体的改进架构。简化解码器而采用卷积块,使得训练过程能够专注于提取全局技能,这是构建稳健且适应性强的交易策略的关键因素。
使用训练期外的测试数据集评估了所实施方法的有效性。尽管盈利交易的比例略高于 40%,但平均收益与平均损失之间的比率足以产生总体正收益。
需要强调的是,本文中描述的模型仍处于探索阶段。在部署到实时交易环境之前,它们必须在更具代表性的数据集上进行训练,并在各种市场条件下接受全面测试。
参考
本文中用到的程序
| # | 名称 | 类型 | 描述 |
|---|---|---|---|
| 1 | Research.mq5 | EA | 样本采集 EA |
| 2 | ResearchRealORL.mq5 | EA | 使用 Real-ORL 方法采集样本的 EA |
| 3 | Study.mq5 | EA | 离线模型训练的 EA |
| 4 | StudyOnline.mq5 | EA | 在线模型训练的 EA |
| 4 | Test.mq5 | EA | 模型测试 EA |
| 5 | Trajectory.mqh | 类库 | 系统状态和模型架构描述结构 |
| 6 | NeuroNet.mqh | 类库 | 用于创建神经网络的类库 |
| 7 | NeuroNet.cl | 代码库 | OpenCL 程序代码 |
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/17939
注意: MetaQuotes Ltd.将保留所有关于这些材料的权利。全部或部分复制或者转载这些材料将被禁止。
本文由网站的一位用户撰写,反映了他们的个人观点。MetaQuotes Ltd 不对所提供信息的准确性负责,也不对因使用所述解决方案、策略或建议而产生的任何后果负责。
海豚回波定位算法(DEA)
您应该了解的MQL5向导技巧(第七十四部分):结合监督学习运用一目均衡表与ADX-Wilder形态
|
在Research中运行了1个月,每次5分钟,生成了300MB的DACGLSTM.bd文件。随后启动了Study。误差率高得吓人。还是说对于首次运行来说这很正常?
Study结束后生成了.nnw格式的神经网络文件。我启动了新一轮的数据收集循环,但就在下个月——Research就停止了交易操作……
太棒了!经过几周的折腾,Study中的错误值终于恢复正常了!现在神经网络真的开始学习了。

不得不扩展奖励和惩罚算法


同时还对Trajectory的输入参数进行了大幅调整
太棒了!经过几周的折腾,Study中的误差值终于恢复正常了!现在神经网络真的开始学习了。
现在最有趣的是——它将如何利用新数据进行交易……我正在研究木模型,这样更容易理解。但在新数据上,交易几乎是随机的,因为没有显著的特征。
现在最有趣的是——该如何根据新数据进行交易……我平时用的是木制模型,这样更容易理解。但在新数据上,交易几乎是随机的,因为没有显著的特征。
距离真正开始交易,我还有一段路要走)经过几轮“研究-学习”循环后,交易开始非常迅速地平仓。神经网络学会了“生存”,而非“盈利”。而且交易时间越短,它就越觉得自己受到的惩罚越少。 这场“手鼓舞”仍在继续。需要正确构建奖励与惩罚机制,这恐怕是最难的部分。目前我只是尝试严格限制。例如,不允许设置低于阈值的止损和止盈。 我还尝试限制交易的最短持仓时间,以免它们刚开仓就几乎立刻平仓。我使用的是LLM、Grok或ChatGPT 4.1,但它们有时会表现得如此愚蠢,简直让人抓狂。不过,进展还是在一点点地推进。 训练循环占用了大量时间。真希望能与人合作,毕竟这个领域前景非常广阔。