组织订单周期

 
"mql4语言特点、复杂性和 技巧 "无关的评论已被移至本主题。
 

继续在MT4下推出MQL5库的主题

#property strict

// https://www.mql5.com/ru/docs/standardlibrary/graphics/cgraphic
#include <Graphics\Graphic.mqh> // MQL5\Include\Graphics\Graphic.mqh

void OnStart()
{
  double Y[] = {1, 2};
  
  GraphPlot(Y);
}
 

通常在测试器中,如果速度滑块设置为31,就会很慢,如果设置为32,测试就会以超快的速度冲向结论。

我通过在代码中插入一个通过计数器的延迟来摆脱它。

input int gDelay = 10000;        // Счетчик для задержки, off=0

void OnTick()
{
  int delayCount = 0;
  while(delayCount < gDelay) ++delayCount;
}

通过输入的延迟可以根据EA的速度和处理器的功率来调整。

在速度32时,我现在可以以适合我的速度移动到感兴趣的点。

 

下面我们将谈到一个不仅涉及MT4,而且涉及MT5与其他平台的话题。但逻辑将用MQL4编写,以方便感知,所以在这个分支中。


大多数情况下,订单修改/删除的主干(任何订单的主要内容)归结为以下逻辑

// Самый распространенный костяк логики модификации ордеров
for (int i = OrdersTotal() - 1; i >= 0; i--)
  if (OrderSelect(i, SELECT_BY_POS))
    OrderModify(OrderTicket(), Price, SL, TP, OrderExpiration());


现在,这种做法很罕见,但更正确了

// Редкий, но правильный костяк модификации ордеров
for (int i = OrdersTotal() - 1; i >= 0; i--)
  if (OrderSelect(i, SELECT_BY_POS))
    if (OrderModify(OrderTicket(), Price, SL, TP, OrderExpiration()))     
    {
      i = OrdersTotal(); // Хотя бы так
      
      // А лучше так
//      OnTick(); break; // вместо строки выше лучше делать такой вызов (переполнения стека от рекурсивных вызовов быть не должно)
    }


在发送交易指令 后,交易环境会发生变化,因此建议在交易服务器回复后立即从头执行TS的整个交易逻辑。

 
fxsaber:

现在的做法很罕见,但更正确了

这种变体以任何错误修改列表中的最后一个订单,拥有超过1个订单的专家顾问就会 "失去 "所有其他订单的视线。

我的秘诀是:循环处理它的所有订单,处理每一个订单(必要时,在处理之前更新市场信息),在下一个tick,下一个方法。在某些情况下,如果当前的循环出现了错误,那么下一个方法(OnTick调用)可能会在当前循环结束后立即进行。

 
Andrey Khatimlianskii:

当出现任何错误时,该选项会循环修改列表中的最后一个订单,一个拥有超过1个订单的EA会 "失去 "所有其他订单的视野。

由于这个条件的存在,不会出现循环。

if (OrderModify(OrderTicket(), Price, SL, TP, OrderExpiration()))

我的处方:循环处理你所有的订单,处理每一个订单(如有必要,在处理之前更新市场信息),在下一个刻度,下一个方法。在某些情况下,如果当前的循环有错误,可以在当前循环结束后立即进行下一个方法(OnTick调用)。

然后在终端日志中可以看到更多交易请求的 错误。

 
fxsaber:

由于这个条件的存在,不会出现循环。

是的,错了,读作!!OrderModify。

如果修改成功,也不能从列表开始重复处理,因为在这种情况下,有一个订单也会被修改(如拉到价格后面),而其他的订单可能会被长期搁置,无人问津。

我的食谱仍然有效。


fxsaber:

然后你可以在终端日志中看到更多的交易请求 错误。

我没有得到这个消息。

 
Andrey Khatimlianskii:

如果修改成功,也不能从列表开始重复处理,因为在这种情况下,有一个订单会被修改(如拉到价格后面),而其他的订单可能会被长期搁置,无人问津

这种逻辑从一开始就有问题。我们必须做出有意识的选择:是拥有一个实际的订单,还是拥有许多不相关的订单。

我的处方仍然有效。

我没有得到这个。

让OrderModify运行5秒钟。在其执行时间内,让一个部分限价单在交易服务器上被执行几次,产生十几笔交易。

 
fxsaber:

这种逻辑从一开始就有问题。你必须做出有意识的选择:是选择一个实际的订单还是选择许多不相关的订单。

一个订单不能同时出现在不同的级别。或者说,我们是否应该为每个级别配备一个不同的EA?对于绝大多数战略来说,这是一个值得怀疑的解决方案。

作为一种特殊情况,几个头寸(通过趋势获得,有几个入口),并为它们设置追踪止损。只拉动一个交易的SL,还是修改所有的交易?在一个急剧的运动中,同样急剧的后续回滚,只修改一个订单的选项将失去很多(而且我们不会得到其余的,因为每一个对OnTick的新调用将修改列表中的第一个订单)。


fxsaber:

让OrderModify运行5秒钟。在其执行过程中,我们假设一个部分限价单在交易服务器上被执行了几次,产生了十几笔交易。

假设:我们将处理所有已经(和应该)执行的订单,并在下一个tick或第一个周期后直接传递给新的订单。

否则,我们总是冒着与最后一个订单的一个--最后--执行部分合作的风险。也许是最小的部分。把一个大订单挂在那里无人问津。

 
Andrey Khatimlianskii:

一个订单不能同时出现在不同的级别。或者说,我们是否应该为每个级别配备一个不同的EA?对于绝大多数战略来说,这是一个值得怀疑的解决方案。

作为一种特殊情况,几个头寸(通过趋势获得,有几个入口),并为它们设置追踪止损。只拉动一个交易的SL,还是修改所有的交易?如果我们有一个急剧的移动,随后又有同样急剧的回撤,那么只修改一个订单的选项将失去很多(我们不会达到其余的,因为每一个对OnTick的新调用将修改列表中的第一个订单)。

我不明白为什么OnTick会只修改一个订单?所有这些都将被修改。

比方说。我们将处理所有已经(和应该)处理的订单,并在下一次打勾时或在第一个周期后立即转入新的订单。

否则,我们将始终冒着与一个--最后一个--最后一个订单的执行部分合作的风险。也许是最小的部分。把一个大订单挂在那里无人问津。

我提请注意 "骨干 "这个词。以地段优先选择或其他形式的肉,总是可以建立起来的。另一方面,核心逻辑保持不变:在一个成功的交易订单 之后,从头开始运行整个交易逻辑。

 
fxsaber:

我不明白为什么OnTick只修改一个订单?都将被修改。

因为价格会移动,在每一次对OnTick的新调用中,都会满足对相同的、列表中第一个订单的新修改条件。特别是如果修改将持续5秒;)


fxsaber:

注意 "骨干 "这个词。以地段优先选择的形式的肉或其他东西总是可以被添加。另一方面,核心逻辑保持不变:在一个成功的交易订单 后,从头开始运行所有的交易逻辑。

这样的 "骨干 "会破坏一个EA在多个订单中工作的逻辑。
如果它不会给拥有一个订单的系统带来任何好处,而且会破坏其他系统,那么它有什么意义呢?

在处理订单之前,按数量和/或与价格的距离进行排序是一个很好的解决方案。但我们不应该假设每个从论坛上复制代码的人都会实现它。
从这个意义上说,我的代码是比较安全的。