English Русский Español Português
preview
神经网络在交易中的应用:演员—导演—评论家框架

神经网络在交易中的应用:演员—导演—评论家框架

MetaTrader 5交易系统 |
22 0
Dmitriy Gizlyk
Dmitriy Gizlyk

概述

强化学习(RL)仍然是现代机器学习中最有前途且发展最快的领域之一。它的独特之处在于,智能体(Agent)能够通过与环境交互进行学习,并根据积累的经验制定最佳行为策略。其与深度神经网络的融合尤为成功,通常被称为深度强化学习(Deep RL),这一融合推动了机器人、游戏、工业过程控制和金融市场等自主系统的显著进步。

金融环境具有高度随机性、持续变化和巨大风险的特点,使其成为深度强化学习方法的理想试验场。在这种情况下,智能体必须迅速适应价格、交易量和市场波动的变化,同时在不确定性下做出决策。然而,在交易策略中,尤其是在高频交易和投资组合管理中,强化学习的实际部署面临着诸多挑战。其中最显著的问题之一是样本效率低下,这意味着无信息的动作和错误的策略会带来异常高的成本。

在经典的无模型强化学习算法中,不使用环境的显式模型,智能体仅从观察到的经验中获取信息。它通过试错来学习:采取行动,获得奖励,并更新其估计值。然而,这些交互中很大一部分信息量很小。在金融市场中,这意味着巨大的交易成本、资本损失以及通往稳健策略的漫长道路。因此,提高样本效率和加速学习收敛仍是关键目标。

演员-评论家框架是最稳健、应用最广泛的架构之一,它结合了两种模型:

  • 演员 — 学习策略
  • 评论家 — 通过价值函数评价动作。
这种责任分工使得策略梯度方法能够与基于价值的估计相结合,既保证了训练的稳定性,又适用于连续动作空间。

在金融应用中,通常使用演员-评论家架构来构建能够预测短期收益同时管理长期风险的智能体。例如,在投资组合再平衡任务中,评论家学习估计预期收益,而演员选择最大化投资组合价值的资产权重。然而,即使是这种先进的架构也有其局限性。在训练的早期阶段,评论家的估计可能非常不准确,导致演员收到误导性信号。因此,智能体可能会反复探索那些可能无利可图的动作空间区域。

为了解决这一局限性,论文“Actor-Director-Critic:一种新型深度强化学习框架”引入了一个新框架:演员—导演—评论家ADC )。除了演员评论家之外,该架构还包含第三个组成部分 — 导演 。它的作用是作为一个分类器,即使在评论家学会提供可靠评估之前,也能区分出高质量的动作和低质量动作。与评论家不同,导演执行的是分类而不是评价功能。它决定是否应使用某一特定动作来训练策略,或者该动作本身质量低下,应排除在进一步的考虑之外。

引入导演一职有诸多优势。首先,在训练的早期阶段,选择性至关重要,应尽可能避免无效动作。其次,在交易成本高和市场波动大的环境中,每一次不成功的动作对智能体来说都可能代价高昂。在这种情况下,导演作为演员的初步引导机制,使其能够专注于可能有效的动作。这种方法降低了探索熵,并加速了有效策略的形成。

导演使用两个经验数据子集进行训练:一个包含高收益的状态-动作-奖励三元组,另一个包含低效示例。经过训练后,导演会对新生成的动作进行二元分类,过滤掉可能无效的选择,从而强化评论家提供的信号。导演的影响力通过衰减系数来控制:最初,它对演员施加了相当大的影响,但随着评论家准确性的提高,导演的影响力逐渐降低。该机制在整个优化过程中既保持了灵活性,又保持了稳定性。

除了 ADC 架构引入的结构改进之外,作者还解决了另一个根本性问题:高估偏差。在强化学习(RL)中,当使用过高的价值估计作为学习目标时,会出现高估现象,从而导致过高的奖励期望和训练不稳定。导致高估的主要原因有:

  • 最大化偏差,源于倾向于选择过高估计的价值函数输出;
  • 自举误差,即利用预测的未来奖励来更新当前状态估计。

缓解高估的最著名方法之一是双延迟深度确定性策略梯度TD3 )算法。TD3 采用两个独立的 Q 函数,并使用它们的估计值的最小值进行更新。然而,由于目标网络更新存在延迟,且其估计值仍可能存在噪声,因此该方法仍易受不稳定性的影响。

ADC 框架提出了一种改进方法。每个 Q 函数都分配了两个目标网络,这两个网络以不同的时间间隔交替更新。在计算目标值时,该框架使用两个目标模型产生的平均估计值。这种方法减少了估计方差,最小化了高估偏差,并提高了训练稳定性。这些改进在金融应用中尤为重要,因为 Q 函数中的误差可能会直接转化为资本损失。

通过将演员-导演-评论家架构与增强的双重估计机制相结合,ADC 产生了一个强大、自适应且稳健的框架。将其应用于算法交易、资产管理和自动对冲,有可能显著提高交易绩效,加快智能体训练速度,并通过从学习的最初阶段进行智能动作选择来降低风险。



ADC 算法

在各种强化学习任务中, 演员-评论家架构已被证明是一种可靠有效的解决方案。其优雅性、清晰度以及制定高质量策略的能力,使其成为强化学习后续发展的基石。然而,随着环境变得越来越复杂,特别是那些涉及连续动作空间和稀疏反馈的环境,更强大、更灵活的架构解决方案变得必不可少。演员-导演-评论家ADC )框架应运而生,以应对这些挑战,它融合了策略规划、启发式指导和深度动作评估的原则。

该架构由三个相互关联的组件构成:演员(Actor)评论家(Critic),以及导演(Director)。它们共同构成了一个协调的系统,其中每个组件都加强了其他组件,从而为更快、更稳定的智能体(Agent)学习创造了条件。

评论家是该系统的分析核心。它的主要作用是通过近似价值函数 Q ( s, a ) 来评估智能体行为的长期效用,该价值函数表示当前策略下的预期累积奖励。评论家通过最小化预测值和目标值之间的误差进行训练:

其中:

  • r智能体因最近一次动作而从环境中获得的奖励;
  • γ ∈ [0,1) 是贴现因子;
  • s ' 和 a ' 分别表示后续状态和动作。

然而,完全依赖评论家的估计,尤其是在训练的早期阶段,可能会有风险,因为它的预测往往不稳定。为了弥补这种不确定性并引导智能体做出明智的决定,该架构引入了导演,它起到类似导师的作用。导演作为一个二分类器,用于区分潜在有益和不理想的动作。根据以下目标函数,使用预先标记的正面动作 ah 和负面动作 al 数据集对导演进行训练:


其中函数 D ( s, a ) 估计在状态 s 下动作 a 是合理动作的概率。这样,导演就能筛选演员的动作,并指导它们的学习过程,尤其是在评论家的评价可能还不可靠的初期阶段。

演员则代表了智能体的行为策略。它被实现为一个参数化函数 μ θ ( s ),该函数在分析当前状态 s后,输出在当前策略下被认为是最优的动作 a 。在 ADC 框架中,演员不仅要接受评论家的反馈,还要接受导演的指导。这使模型能够更稳健地逼近最优策略。演员的目标函数结合了这两种信息来源:

因此,演员会寻求既得到导演认可又被评论家赋予较高期望值的行为。

为了提高训练稳定性并减轻高估偏差, ADC 框架采用了一种增强的双重估计机制。维护两个独立的评论家,每个评论家都配有两个参数固定的目标网络。在评论家训练过程中,目标值被计算为下一个状态-动作对的相应目标网络的平均预测值,这有助于稳定学习过程。在演员训练过程中,采用两位评论家给出的最低评估值,以防止动作被高估,并鼓励制定更保守但更可靠的策略。

评论家的目标模型会按照预定的时间间隔,通过复制其对应可训练模型的参数来交替更新。这种方法有助于长期保持训练稳定性,防止目标值出现剧烈波动。

还需注意的是, 评论家的参数在每次训练迭代中都会进行优化。相比之下, 演员的策略更新会延迟执行,从而提供额外的训练稳定性。这种延迟更新机制使评论家有足够的时间准确评估当前策略,并为策略调整提供更可靠的指导。

此外,还采用了随机平滑技术来提高智能体的行为多样性和鲁棒性,包括:

  • 给智能体的动作添加高斯噪声:

  • 对目标动作施加有限的噪声:

演员的最终参数优化函数整合了来自评论家导演的信号:


演员-导演-评论家框架为开发智能体开辟了新的途径,这些智能体不仅能够从经验中学习,而且能够以类似于人类学习的方式使用指导。

下图展示了作者给出的演员-导演-评论家框架的示意图。

作者提供的演员-导演-评论家框架示意图



MQL5 中的实现

在回顾了演员-导演-评论家框架的理论方面后,我们现在进入本文的实践部分,在此我们将介绍我们对于使用 MQL5 实现所提方法的解读。

正如你可能已经注意到的,所考虑的框架不需要引入全新的模块作为单独的对象。这一方面使这项工作与以往的方法有显著区别。在此实现中,我们专注于利用先前开发的模块构建可训练模型的架构,并根据所提出的方法设计训练过程。

可训练模型的架构


在开始构建可训练模型架构时,需要注意的是,作者提出的 ADC 框架适用于广泛的架构设计。在原文中,使用了 TD3 框架的扩展来展示实验结果。然而,在我们的工作中,我们更进一步,将所提出的想法应用于更复杂的架构解决方案 — HiSSD ,该方案是在之前的研究中提出的。此外,我们不仅增加了两个新模型(评论家和导演),还对先前开发的组件进行了修改。

与之前一样,所有可训练模型的架构都在 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;
     }

在该方法的主体中,我们检查接收到的指针,并在必要时创建动态数组对象的新实例。这可以防止在后续访问这些数组时出现严重错误。

我们描述的第一个模型是高层规划器,它部分充当环境状态的编码器。

提醒一下,该模型接收描述环境状态的张量作为输入。它在模型的潜在状态中生成一个通用技能(skill)矩阵,并预测给定规划视野内的未来环境状态。重要的是,在预测未来状态时,仅使用通用技能表示。这鼓励模型构建一个信息量极大的潜在技能张量。

第一层仍然是一个全连接层,其大小足以编码环境的完整输入状态张量。

//--- 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;
     }

该模型直接从 MetaTrader 5 终端接收原始的、未经处理的数据。这可能包括价格报价序列以及从简单移动平均线到复杂振荡器等各种技术指标数据。

尽管这些数据极具价值,但它们在本质上具有极大的异质性。它们的范围、统计分布和噪声特性可能存在显著差异。若没有进行适当的预处理,这种异质性会导致模型训练性能大幅下降。因此,下一步是将数据带入一个可比的表示空间,通常使用批量归一化,这有助于缓解值分布的不平衡。

然而,在这个实现过程中,我们采用了不同的方法。为了提高模型的鲁棒性和泛化能力,我们通过在归一化数据中引入受控噪声来增强这一阶段。这起到了一种正则化的作用,能够防止过拟合,并在真实市场动荡的情况下提高模型的适应性。

//--- 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 = defNeuronSkillsEncoder;
   descr.count = HistoryBars;
     {
      int temp[] = {BarDescr, NSkills, 4};   // Variables, Common Skills, Heads
      if(ArrayCopy(descr.windows, temp) < (int)temp.Size())
         return false;
     }
   descr.window = 8;
   descr.step = 1;
   descr.window_out = 32;
   prev_count = descr.windows[0];
   int prev_out = descr.windows[1];
   descr.batch = 1e4;
   descr.optimization = ADAM;
   descr.activation = None;
   if(!encoder.Add(descr))
     {
      delete descr;
      return false;
     }

为了进一步改进智能体的动作,考虑到通用技能张量的变化动态,我们引入了LSTM 循环块。该组件在捕捉观测到的市场数据的时间结构方面发挥着关键作用。众所周知,金融市场对过去的状态表现出强烈的依赖性,市场逻辑的很大一部分都体现在时间模式中。

正是在这种情况下, LSTM长短期记忆网络)成为了不可或缺的工具。其内部记忆机制使其能够保留和更新关于关键市场转变和结构模式的信息,同时不会因长期依赖而丢失上下文。因此,该模型不仅学会了识别当前的市场状况,还学会了根据历史观测数据的复杂结构来预测潜在的反转或延续。

LSTM 模块放在技能生成层之后是一种有意为之的架构选择。首先,该模型以技能张量的形式提取当前状态和智能体目标的抽象表示。然后,LSTM 会跟踪这些技能随时间的演变。这使得智能体不仅能够感知市场的静态快照,还能感知其策略概况的动态变化 — 例如,主要趋势如何演变,支撑位和阻力位如何形成,以及波动性随时间的变化情况。

//--- layer 3
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronLSTMOCL;
   descr.count = prev_out;                      // Common Skkills
   descr.layers = prev_count;                   // Variables
   descr.batch = 1e4;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!encoder.Add(descr))
     {
      delete descr;
      return false;
     }

接下来,我们依次添加两个卷积层,每个卷积层在处理从前面层接收到的多维时间序列时都发挥着特定的作用。这些卷积层以 MLP 的形式发挥作用,具有独立的预测头,旨在自主分析和预测复杂市场序列中的各个单变量分量在指定预测范围内的演变。

//--- layer 4
   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 = 4*NForecast;
   descr.layers = prev_count;
   descr.activation = SoftPlus;
   if(!encoder.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 5
   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 6
   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 7
   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;
     } 

需要强调的是,通用技能生成模块产生的潜在表征并非流程的最终输出。相反,它作为一种有价值的中间抽象,可以在演员-导演-评论家框架的不同组件中多次重复使用。因此,我们将循环 LSTM 表示存储在局部变量中,以确保其可用于后续操作。

//--- Latent
   CLayerDescription *latent = encoder.At(LatentLayer);
   if(!latent)
      return false;

接下来,我们将描述底层控制器(Controller)的架构。该模块分析相同的环境状态,并生成特定技能的张量。因此,我们可以无需修改地复用之前模型的前两层 — 输入处理和归一化。

//--- Task
   task.Clear();
//--- Input layer
   if(!task.Add(encoder.At(0)))
     {
      return false;
     }
//--- layer 1
   if(!task.Add(encoder.At(1)))
     {
      return false;
     }

控制器随后作为底层模块运行,负责构建特定任务技能的张量。与之前描述的在战略层面运行的通用技能生成模块不同,控制器在战术层面运行,分析当前环境状态。

控制器并非仅仅对环境做出反应;它主动解读复杂的市场结构,从中提取出可被描述为代理人的短期“直觉”的部分。基于这一分析,它生成了一个反映即时偏好和智能体在特定情况下应采取动作的任务特定技能张量。

最后,三个信息流合并在一起:  

  1. 通用(高级)技能的潜在表征;
  2. 特定任务(低级)技能的张量;
  3. 当前环境状态的归一化表示。

由此得到的组合张量将作为生成智能体动作矩阵的基础。这种结构提供了强大的模型适应性:使战略目标与战术层面的实际情况保持一致。行为模式变得更加灵活,但仍然与整体交易策略保持一致。

需要强调的是,控制器不仅仅是一个预测性动作模块,而是连接高层意图和具体市场环境的语义桥梁。它使智能体能够在不断变化的市场条件下保持其行为的战略方向。

//--- layer 2
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronHiSSDLowLevelControler;
   descr.count = HistoryBars;
     {
      int temp[] = {latent.layers,     // Variables
                    NSkills,           // Task Skills
                    latent.count,      // Common Skills
                    NActions,          // Action Space
                    4};                // Heads
      if(ArrayCopy(descr.windows, temp) < (int)temp.Size())
         return false;
     }
   descr.window = 8;
   descr.step = 1;
   descr.window_out = 32;
   prev_count = descr.windows[0];
   prev_out = descr.windows[3];
   descr.batch = 1e4;
   descr.optimization = ADAM;
   descr.activation = SIGMOID;
   if(!task.Add(descr))
     {
      delete descr;
      return false;
     }

接下来,我们将介绍负责做出最终交易决策的高级演员模型的架构。它的任务是解释控制器在前一阶段提出的动作矩阵。换句话说,演员作为最终决策实体,根据一系列备选战术方案,决定在当前市场环境下执行的具体行为。

演员的架构完全继承自我们之前的作品。我们特意选择不给由备选策略矩阵产生的动作增加噪声。与许多强化学习问题中通过噪声注入来促进探索和多样性不同,在金融市场中,即使最终动作发生极小的偏差,也可能导致灾难性后果。仓位规模的轻微偏差、交易水平的微小变化,甚至更糟糕的是,对市场动态的误判,都可能导致重大损失,并因此降低系统可靠性。

我们仅对方向性市场走势的概率预测模型进行了小幅调整,该调整涉及将环境编码器的潜在状态从通用技能生成模块迁移到循环块中。这一虽小却重要的修改旨在提高模型捕捉时间依赖性的能力,并使其能够动态适应不断变化的市场条件。

由于本节的目标是保持论述的简洁性,因此我们在此不对这些架构进行全面详细的描述。不过,感兴趣的读者可以参考附件了解完整的实现细节。

上述几乎所有模型都构成了演员-导演-评论家框架内的演员层级结构。下一个关键组成部分是导演 ,一个专门的模型,其主要任务是将演员生成的动作进行上下文分类,分为有利可图的动作和无利可图的动作。

导演的作用怎么强调都不为过:它起到战略质量筛选器的作用,在可能造成损失的决策执行之前将其剔除,从而避免造成经济损失。在波动剧烈的金融市场中,每一个错误都会付出高昂的代价,因此这种早期评估机制显得尤为重要。

所提出的方法的一个显著特点是,导演不仅对行为进行分类,而且还生成额外的监督学习信号。这加快了演员的适应过程,因为它允许策略采纳导演的反馈,而无需反复积累负面经验。这种机制在错误代价高昂且学习时间有限的情况下尤其有效。

在传统实现中, 导演接收环境状态张量作为输入,直接反映智能体的观察结果。然而,在我们的实现中, 导演使用的是通用技能矩阵 — 由 LSTM 模块输出的技能生成模块生成的具有信息量的潜在表示,该模块已经过预训练,可以从多元时间序列中提取行为模式。这种表示方法已经考虑了环境动态,过滤掉了无关的信号,并集中了当前背景下最有意义的方面。因此, 导演在更压缩、更稳定的特征空间中运行,从而显著提升在实时市场环境中的分类准确性、决策稳定性和适应能力。

在主信息流中, 导演接收智能体的动作张量作为输入,该输入立即被归一化。

//--- Director
   director.Clear();
//--- Input layer
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   descr.count = NActions;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!director.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 1
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBatchNormOCL;
   descr.count = NActions;
   descr.batch = 1e4;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!director.Add(descr))
     {
      delete descr;
      return false;
     }

使用交叉注意力模块对当前市场条件下演员生成的动作进行直接分析(以通用技能矩阵编码)。在这里,智能体的意图与当前市场动态所实际证明的合理性之间实现了语义上的一致性。

交叉注意力机制使导演能够识别动作张量组成部分与通用技能矩阵特征之间的关系。这在波动性极大的市场中尤为重要,因为简单的线性关系不再成立。交叉注意力能够有效地使模型专注于在特定情况下最关键的演员的行为方面。

//--- layer 2
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronCrossDMHAttention;
     {
      int temp[] = {3,                 // Inputs window
                    latent.count       // Cross window
                   };
      if(ArrayCopy(descr.windows, temp) < (int)temp.Size())
         return false;
     }
     {
      int temp[] = {NActions/3,        // Inputs units
                    latent.layers      // Cross units
                   };
      if(ArrayCopy(descr.units, temp) < (int)temp.Size())
         return false;
     }
   descr.step = 4;                     // Heads
   descr.window_out = 32;
   descr.batch = 1e4;
   descr.activation = None;
   descr.optimization = ADAM;
   if(!director.Add(descr))
     {
      delete descr;
      return false;
     }

交叉注意力模块的输出是对演员行为的语义增强表示,并且已经适应了当前的市场环境。这种表示不仅反映了智能体的意图,还反映了其在当前条件下的适当性,同时考虑到了所有已发现的模式以及动作与一般技能之间的相互作用。

这种上下文丰富的表示成为最终处理阶段的基础 — 根据潜在盈利能力对行为进行分类。

分类过程采用三个全连接神经网络层序列来实现,每个神经网络层都配备了自己的激活函数,以将必要的非线性引入数据转换中。这种级联使模型能够灵活地近似复杂的决策边界,从而更准确地区分有利可图的行为和无利可图的动作。

在最后一层,使用 sigmoid 激活函数,使得模型的输出可以解释为类别成员的概率估计。因此,该模型不仅能做出二元决策,还能提供分类的置信度度量。

//--- layer 3
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   descr.count = LatentCount;
   descr.batch = 1e4;
   descr.activation = TANH;
   descr.optimization = ADAM;
   if(!director.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 4
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   descr.count = LatentCount;
   descr.activation = SoftPlus;
   descr.batch = 1e4;
   descr.optimization = ADAM;
   if(!director.Add(descr))
     {
      delete descr;
      return false;
     }
//--- layer 5
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   prev_count = descr.count = 1;
   descr.activation = SIGMOID;
   descr.batch = 1e4;
   descr.optimization = ADAM;
   if(!director.Add(descr))
     {
      delete descr;
      return false;
     }

需要注意的是,此实现中的评论家模型采用了类似的架构设计。与导演的情况一样,评论家使用了一个交叉注意力模块,使演员能够将演员生成的动作与由通用技能矩阵表示的当前环境背景对齐。这样就能更准确地评估动作结果,考虑到智能体行为与潜在市场动态之间的复杂依赖关系。

然而,评论家架构的最后阶段存在着根本性的区别。与使用 sigmoid 函数进行概率解释的导演不同,评论家的输出层不包含激活函数。这一设计选择是基于目标变量的性质 — 预期累积奖励 — 而做出的,该变量可能跨越一个广泛且实际上无界的范围。

换句话说,评论家输出的是在当前情况下所提动作效用的标量估计值,以预期收益为单位表示。应用有界激活函数会通过截断潜在的重要偏差来扭曲这个量。因此,最终值直接产生,使模型能够自由地表示对环境的学习预期。

但这只是架构上的一个微小调整。因此,本文将省略对评论家架构的详细讨论。附件中提供了所有模型的完整架构描述,可供独立研究。

关于架构设计的内容在本文中基本已经介绍完毕。我们在此稍作停顿,在下一篇文章中,我们将讨论模型的训练过程,并评估所提解决方案在真实历史数据上的有效性。



结论

在这项工作中,我们引入了一种新的演员-导演-评论家框架,旨在用于基于深度学习的任务求解。该框架的主要贡献之一是引入了导演模型,该模型根据当前环境状态对演员的行为进行分类,从而显著提高了训练过程的效率和稳定性。

在文章的实践部分,我们详细研究了构成演员-导演-评论家框架基础的可训练模型的架构设计。我们阐述了使用各种模块的原则,并着重强调了系统各组件背后的关键设计决策。

在下一篇文章中,我们将重点介绍这些模型的训练过程,并评估它们在真实历史市场数据上的表现。


参考


本文中用到的程序

# 名称 类型 描述
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/17796

附加的文件 |
MQL5.zip (2651.68 KB)
基于季节性因素的MetaTrader 5外汇价差交易质量评估 基于季节性因素的MetaTrader 5外汇价差交易质量评估
本文在日线周期上,针对单一品种及价差组合,检验季节性交易方法的质量。研究重点在于识别周期性月度规律,以及在当年交易中应用这些规律的可行性。
老鹰策略(ES) 老鹰策略(ES)
老鹰策略是一种模拟老鹰两阶段捕猎策略的算法:通过曼特尼亚(Mantegna)方法实现的莱维(Levy)飞行进行全局搜索,与利用萤火虫算法进行的密集局部开发交替进行,这是一种在数学上合理的探索与开发平衡方法,也是一种将两种自然现象融合为单一计算方法的生物启发式概念。
新手在交易中的10个基本错误 新手在交易中的10个基本错误
新手在交易中会犯的10个基本错误: 在市场刚开始时交易, 获利时不适当地仓促, 在损失的时候追加投资, 从最好的仓位开始平仓, 翻本心理, 最优越的仓位, 用永远买进的规则进行交易, 在第一天就平掉获利的仓位,当发出建一个相反的仓位警示时平仓, 犹豫。
您应该了解的MQL5向导技巧(第七十一部分):使用MACD与OBV形态 您应该了解的MQL5向导技巧(第七十一部分):使用MACD与OBV形态
指数平滑异同移动平均线震荡指标(MACD)与能量潮指标(OBV),是另一组可在MQL5智能交易系统(EA)中联合使用的技术指标。与本系列文章一贯的思路相同,这一组合具有互补性:MACD用于确认趋势,OBV则用于验证成交量。我们依旧通过MQL5向导来构建并测试这一组合的潜在效果。