文章 "神经网络变得轻松(第四十七部分):连续动作空间"

 

新文章 神经网络变得轻松(第四十七部分):连续动作空间已发布:

在本文中,我们扩展了代理者的任务范围。训练过程将包括一些资金和风险管理等方面,这是任何交易策略不可或缺的部分。

在上一篇文章中,我们训练的代理者只是为了判定交易方向。代理者的动作范围仅限于 4 个选项:

  • 买入, 
  • 卖出, 
  • 持有/等待,
  • 所有持仓平仓。

于此,我们没看到资本和风险管理功能。我们在所有交易操作中采用了最小手数。这足以评估训练方式,但构建交易策略尚嫌不足。一个可盈利交易策略再简单也必须有一个资金管理算法。

此外,为了创建一个稳定的交易策略,我们需要管理风险。我们的设计中也缺少这个模块。EA 在每根新交易蜡烛处评估市场形势,并就交易操作做出决定。但每一根即将到来的柱线都会给我们的账户带来风险。柱线内的价格走势可能不利于我们的余额。这就是为什么始终建议使用止损的原因。这种方式虽简单,但令我们能够限定每笔交易的风险。

经过大约 3000 次验算后,我得到一个能够在训练集上产生盈利的模型。在 5 个月的训练期间,该模型进行了 334 笔交易。其中超过 84% 是盈利的。结果利润达到初始资本的 33%。同时,余额的回撤不到 1%,按净值则为 7.6%。盈利因子超过 26,恢复因子为 3.16。下图展示了余额的上升趋势。余额线几乎总是低于净值线,这表明开仓方向正确。同时,资金的负载约为 20%。这是一个相当高的数字,但不超过累计利润。

模型训练结果

模型训练结果

不幸的是,EA 的操作结果摆明在训练集之外比较温和。


作者:Dmitriy Gizlyk

 
您好。Expert Advisor 在交易 30-50 次后就会停止开仓。这是正常现象吗?我用新的模型文件进行了 5-7 次尝试。当交易次数稍多一些时,它继续打开交易;当交易次数稍少一些时,它继续打开交易。但仍然无法打开交易。我试着对其中一个模型进行 4000 次训练。结果还是一样 - 一条直线。
 
Viktor Kudriavtsev #:
您好。Expert Advisor 在交易 30-50 次后就会停止开仓。这是正常现象吗?我用新的模型文件进行了 5-7 次尝试。当交易次数稍多一些时,它继续打开交易;当交易次数稍少一些时,它继续打开交易。但仍然无法打开交易。我试着对其中一个模型进行 4000 次训练。结果还是一样 - 一条直线。

再见,维克多。

训练模型是一个相当漫长的过程。库中的训练系数设置为 3.0e-4f。也就是说,如果只在一个例子上训练模型,那么模型会在大约 4000 次迭代后学会这个例子。使用这么小的学习率是为了让模型能够平均权重,最大限度地拟合训练样本。

至于缺乏交易,这并不是停止学习过程的理由。训练模型的过程类似于 "试错 "方法。模型会逐渐尝试所有可能的选项,并寻找一种能使回报最大化的方法。在建立学习过程时,我们增加了对无交易的惩罚,这将刺激模型建立头寸。如果模型在某个阶段没有进行任何交易,那么经过一次或多次重复后,惩罚就会发挥作用,使模型摆脱这种状态。为了加快这一过程,可以增加对不交易的惩罚。但需要注意的是,惩罚金额不应超过交易可能造成的损失。否则,模型将打开无利可图的头寸,以避免因没有交易而受到惩罚。

 

Dmitriy Gizlyk 非常感谢你提供的详细文章。我重新训练了 2023 年 1 月 1 日至 2023 年 5 月 31 日期间的模型,生成了 DDPGAct.nnw 和 DDPGCrt.nnw。但是,用 test.ex5 测试 EA 时,没有一笔交易。

我采取了以下步骤:

  1. https://www.mql5.com/zh/articles/download/12853.zip 下载、解压缩并编译 Study.mq5 和 test.mq5
  2. " 策略测试器 "中,按照https://c.mql5.com/2/55/Study.png 中的指示运行一次 Study.ex5
  3. " 策略测试器 "中,按照https://c.mql5.com/2/55/Study_opt.png 中的指示优化 Study.ex5 参考所附的 Optimized.png
  4. 在策略测试器中,在 2023 年 1 月 1 日至 2023 年 5 月 31 日期间运行 test.ex5(优化:禁用)。
  5. (没有错误,也没有任何交易!)。

尝试使用以下PrintFormat 行进行调试:

...
   double sell_sl = NormalizeDouble(Symb.Bid() + ActorResult[5], Symb.Digits());
   PrintFormat("ActorResult[0]=%f  ActorResult[1]=%f ActorResult[2]=%f buy_sl=%f",ActorResult[0], ActorResult[1],  ActorResult[2], buy_sl);
   PrintFormat("ActorResult[3]=%f  ActorResult[4]=%f ActorResult[5]=%f sell_tp=%f",ActorResult[0], ActorResult[1],  ActorResult[2], sell_tp);
//---
   if(ActorResult[0] > 0 && ActorResult[1] > 0 && ActorResult[2] > 0 && buy_sl > 0)
      Trade.Buy(buy_lot, Symb.Name(), Symb.Ask(), buy_sl, buy_tp);
   if(ActorResult[3] > 0 && ActorResult[4] > 0 && ActorResult[5] > 0 && sell_tp > 0)
      Trade.Sell(sell_lot, Symb.Name(), Symb.Bid(), sell_sl, sell_tp);
...

查看了以下内容:

...
2023.12.01 23:15:18.641	Core 01	2023.05.30 19:00:00   ActorResult[0]=0.085580  ActorResult[1]=-0.000476 ActorResult[2]=-0.000742 buy_sl=1.072910
2023.12.01 23:15:18.641	Core 01	2023.05.30 19:00:00   ActorResult[3]=0.085580  ActorResult[4]=-0.000476 ActorResult[5]=-0.000742 sell_tp=1.070290
2023.12.01 23:15:18.641	Core 01	2023.05.30 20:00:00   ActorResult[0]=0.085580  ActorResult[1]=-0.000476 ActorResult[2]=-0.000742 buy_sl=1.072830
2023.12.01 23:15:18.641	Core 01	2023.05.30 20:00:00   ActorResult[3]=0.085580  ActorResult[4]=-0.000476 ActorResult[5]=-0.000742 sell_tp=1.070210
2023.12.01 23:15:18.641	Core 01	2023.05.30 21:00:00   ActorResult[0]=0.085580  ActorResult[1]=-0.000476 ActorResult[2]=-0.000742 buy_sl=1.072450
2023.12.01 23:15:18.641	Core 01	2023.05.30 21:00:00   ActorResult[3]=0.085580  ActorResult[4]=-0.000476 ActorResult[5]=-0.000742 sell_tp=1.069830
2023.12.01 23:15:18.641	Core 01	2023.05.30 22:00:00   ActorResult[0]=0.085580  ActorResult[1]=-0.000476 ActorResult[2]=-0.000742 buy_sl=1.072710
2023.12.01 23:15:18.641	Core 01	2023.05.30 22:00:00   ActorResult[3]=0.085580  ActorResult[4]=-0.000476 ActorResult[5]=-0.000742 sell_tp=1.070090
2023.12.01 23:15:18.641	Core 01	2023.05.30 23:00:00   ActorResult[0]=0.085580  ActorResult[1]=-0.000476 ActorResult[2]=-0.000742 buy_sl=1.073750
2023.12.01 23:15:18.641	Core 01	2023.05.30 23:00:00   ActorResult[3]=0.085580  ActorResult[4]=-0.000476 ActorResult[5]=-0.000742 sell_tp=1.071130
...

请问有什么地方出错或遗漏了?

非常感谢。

Dmitriy Gizlyk
Dmitriy Gizlyk
  • 2023.11.30
  • www.mql5.com
Trader's profile
附加的文件:
Optimized.png  187 kb
 

您好。在我看来,不是模型不打开交易,而是它没有设置为盈利。截图上的直线就说明了这一点。需要在奖励规则中做些什么。

float reward = (account[0] - PrevBalance) / PrevBalance;

if(account[0] == PrevBalance)
if((buy_value + sell_value) == 0)

reward -= 1;

我尝试了这些变体

float reward = (account[0] - PrevBalance) / PrevBalance;

if(account[0] == PrevBalance)

if((buy_value + sell_value) == 0)

奖励 -= 1;

if(buy_profit<10)

reward -= 1;

if(buy_profit>10)

reward += 1;

if(sell_profit<10)

reward -= 1;

if(sell_profit>10)

reward += 1;

没有帮助。请告诉我该怎么做。

附加的文件: