文章 "轻松快捷开发 MetaTrader 程序的函数库(第 二十二部分):交易类 - 基准类,限制验证"

 

新文章 轻松快捷开发 MetaTrader 程序的函数库(第 二十二部分):交易类 - 基准类,限制验证已发布:

在本文中,我们将着手开函数发库基准交易类,并在其第一个版本中加入进行交易操作的权限初始验证。 此外,我们还将略微扩展基准交易类的功能和内容。

若要验证交易限制检查方法的操作,我们需要人为地创建它们。
例如:

  1. 禁用 Internet 访问(模拟交易服务器断连),
  2. 在 EA 设置中禁用自动交易(按 F7 并在 EA 设置窗口的 “常用” 标签中取消勾选 “允许自动交易”),
  3. 在终端中禁用自动交易(自动交易按钮)。

单击 EA 交易面板中的开仓按钮。 以下条目出现在日志中:

2019.09.26 15:07:55.582 CTrading::OpenBuy: Request rejected before being sent to server due to:
2019.09.26 15:07:55.582 1. No permission to conduct trading operations in terminal ("AutoTrading" button disabled)
2019.09.26 15:07:55.582 2. No connection to trade server
2019.09.26 15:07:55.582 3. EA does not have permission to conduct trading operations (F7 --> Common --> "Allow Automatic Trading")


我们来一一消除这些限制。

启用 Internet 连接后,尝试开仓时我们会收到以下消息:

2019.09.26 15:10:36.766 CTrading::OpenBuy: Request rejected before being sent to server due to:
2019.09.26 15:10:36.766 1. No permission to conduct trading operations in terminal ("AutoTrading" button disabled)
2019.09.26 15:10:36.766 2. EA does not have permission to conduct trading operations (F7 --> Common --> "Allow Automatic Trading")


在终端上启用自动交易,单击自动交易按钮。 尝试开仓时,我们获得以下消息:

2019.09.26 15:13:03.424 CTrading::OpenBuy: Request rejected before being sent to server due to:
2019.09.26 15:13:03.424 EA does not have permission to conduct trading operations (F7 --> Common --> "Allow Automatic Trading")


按 F7 并在其设置里允许 EA 进行交易。 当尝试开仓时,我们终于成功了:

2019.09.26 15:14:32.619 - Position is open: 2019.09.26 11:14:32.711 -
2019.09.26 15:14:32.619 EURUSD Opened 0.10 Buy #455179802 [0.10 Market-order Buy #455179802] at price 1.09441, Magic number 123


其他限制可以在测试器或模拟帐户中测试,激活其中一个限制并创建一种情况来进行检查,例如,该帐户中挂单的最大数量限制。

作者:Artyom Trishkin

Artyom Trishkin
Artyom Trishkin
  • www.mql5.com
交易者的个人资料
 

Artem,我需要在打开仓位 或激活订单后获取 mql4 中仓位的属性。我找到了获取事件索引的方法

ENUM_TRADE_EVENT engine.LastTradeEvent()

此时我需要获取可用属性。

我甚至找到了枚举,但如何获取......我找不到。

 
Alexey Viktorov:

Artem,我需要在打开仓位 或激活订单后获取 mql4 中仓位的属性。我找到了获取事件索引的方法

此时我需要获取可用属性。

我甚至找到了枚举,但如何获取......我找不到。

如果最后一个事件是开仓?我们需要获取最后打开的仓位并访问其所有属性?对吗?

如果是这样,那就很容易了(无需检查获取列表和对象的结果):


 
谢谢,剩下的傻问题我会私下问,免得吓着路人。))))))
 

我有进展了。谢谢你们,图书馆非常有用。

下一个问题(并不愚蠢):我们有两个挂单。我们在激活其中一个订单时收到了一个事件,然后第二个订单被激活....。事件没有变化。如何在收到事件后让守望者返回?已尝试

last_event = WRONG_VALUE;
处理事件 后,但得到的结果是无意义的...
 
Alexey Viktorov:

我有进展了。谢谢你们,图书馆非常有用。

下一个问题(并不愚蠢):我们有两个挂单。我们在激活其中一个订单时收到了一个事件,然后第二个订单被激活....。事件没有变化。如何在收到事件后让守望者返回?我试过

处理事件 后,但得到的结果却是一派胡言......

我没有正确控制事件。库会捕获所有事件,然后测试 EA 会检查过去事件和当前事件之间的差异。于是就出现了两个相同的事件。

原则上,发送事件后,库会重置事件本身。在接收到事件后,尝试再次接收该事件--应该向变量写入没有事件,然后再捕捉下一个事件。

但我早就在计划中写明,交易事件的处理方式应与符号或账户事件的处理方式相同--它们只是返回一个有事件发生的标志。然后我们就可以在程序中看到事件是什么了。在智能交易系统中,一切都已准备就绪,只有交易事件在智能交易系统的 OnDoEasyEvent() 函数中被阻止了,因为标志还没有返回 - 我无法得到它:

//--- 处理贸易活动
   else if(idx>TRADE_EVENT_NO_EVENT && idx<TRADE_EVENTS_NEXT_CODE)
     {
      event=EnumToString((ENUM_TRADE_EVENT)ushort(idx));
      int digits=(int)SymbolInfoInteger(sparam,SYMBOL_DIGITS);
     }
     
 
Artyom Trishkin:

我这里的事件控制出了问题。库会捕获所有事件,然后测试 EA 会检查过去事件和当前事件之间的差异。结果就出现了两个相同的事件。

原则上,在发送事件后,库会重置事件本身。在接收到事件后,请再次尝试接收事件--应该将没有事件写入变量,然后再捕获下一个事件。

但我早就在计划中写明,交易事件的处理方式应与符号或账户事件的处理方式相同--它们只是返回一个有事件发生的标志。然后我们就可以在程序中看到事件是什么了。在智能交易系统中,一切都已经准备就绪,只有交易事件在智能交易系统的 OnDoEasyEvent() 函数中遇到了阻碍,因为标志还没有返回 - 我无法得到它:

这是肯定的,早晨的傍晚更明智....。如果收到一个事件,在我的特殊情况下,我们应该以某种方式对其做出反应。特别是,再下一个挂单。新事件就这么多。

 
不,你必须重置事件标志。
 
Artyom Trishkin:

我这里的事件控制出了问题。库会捕获所有事件,然后测试 EA 会检查过去事件和当前事件之间的差异。结果就出现了两个相同的事件。

原则上,在发送事件后,库会重置事件本身。在接收到事件后,请再次尝试接收事件--应该将没有事件写入变量,然后再捕获下一个事件。

但我早就在计划中写明,交易事件的处理方式应与符号或账户事件的处理方式相同--它们只是返回一个有事件发生的标志。然后我们就可以在程序中看到事件是什么了。在智能交易系统中,一切都已准备就绪,只有交易事件在智能交易系统的 OnDoEasyEvent() 函数中遇到了阻碍,因为还没有返回标志--我无法得到它:

但事件是一个变量,只有在OnChartEvent 中可用,而在测试器中没有处理。

我想在 OnTick() 中做类似的事情:

//--- 如果最后一次交易事件发生变化
 if(engine.LastTradeEvent() != last_event)
  {
   switch(last_event)
    {
     case TRADE_EVENT_PENDING_ORDER_PLASED :
      // 调用相应的函数
     break;
     case TRADE_EVENT_PENDING_ORDER_REMOVED :
      // 调用相应的函数
     break;
     case TRADE_EVENT_PENDING_ORDER_ACTIVATED :
      // 调用相应的函数
     break;
     case TRADE_EVENT_POSITION_OPENED :
      // 调用相应的函数
     break;
     case TRADE_EVENT_POSITION_CLOSED :
      // 调用相应的函数
     break;
     
     default :
      break;
    }
 
Alexey Viktorov:

但事件是 OnChartEvent 中才有的变量,在测试器中没有处理。

我想在 OnTick() 中做这样的事情:

因此,在处理事件 后--在事件类型检查模块结束时,您在 last_event 变量中有什么?该变量应在智能交易系统中重置。在将事件发送到图表并写入事件列表后,库本身会调用重置最后一个事件的方法,而不是强行调用。

 
Alexey Viktorov:

但事件是 OnChartEvent 中才有的变量,在测试器中没有处理。

我想在 OnTick() 中做这样的事情:

请注意测试 EA 函数 OnDoEasyEvent() - 它会处理所有库事件。如果您想用开关来处理交易事件,请在这里操作。