组织订单周期 - 页 5

 
Vasiliy Sokolov:

循环是最危险的编程技术之一。它导致奇怪的、不经常出现的错误,几乎不可能进行分析。

相反,你应该尝试尽快结束一个用户线程,而不是循环。如果你想 "掌握脉搏"--分析MT5的OnTradeTransaction。MT4一般不适合此类游戏,因为俗话说,简单不如偷。

我指的不是具体的实现,而是任何停顿后TS摇晃的原则。那么,在哪里有一个可怕的定势--并不清楚。因为不清楚,为什么要急于完成一个用户线程。

 
fxsaber:

因此,那里的可怕循环在哪里--并不清楚。

从OnTick调用OnTick是一个通过递归进行的非复杂的循环。

// Редкий, но правильный костяк модификации ордеров
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; // вместо строки выше лучше делать такой вызов (переполнения стека от рекурсивных вызовов быть не должно)
    }

也不清楚为什么急于终止用户线程。

我们正在使用一个事件驱动的模型。因此,我们需要尽可能快地处理当前事件,以等待下一个事件。花费在这个问题上的时间是一个黑洞。我们在流动中花费的时间越多,我们所处的交易环境就越过时。

 
Vasiliy Sokolov:

从OnTick调用OnTick是一个 通过递归进行的非复杂 的循环。

显然,这是唯一能阻止的事情。

我们正在用一个事件模型工作。因此,我们需要尽可能快地处理当前事件,以便等待下一个事件。在流动中度过的时间是一个黑洞。我们在流动中花费的时间越多,我们工作的交易环境就越过时

好吧,这不是真的!
 
:
void OnTick()
{
   for(int i = 0; i < symbols.Total(); i++)
   {
      request.symbol = symbols.At(i); 
      OrderSendAsynch(request, result); // Начиная с этой строки, анализировать торговое окружение в текущем потоке не имеет смысла
                                        // Единственная верная стратегия - как можно быстрее завершить цикл, и выйти из OnTick
                                        // Для дальнейшего анализа например в OnTransaction
   }
}

s. 我们完全不了解对方。我认为我们之间不可能有任何对话。

 
Vasiliy Sokolov:
:

你在哪里看到了你的代码中的停顿,仅仅是它的存在就是从头开始摇动TS的唯一原因?你没有这个能力!

 
fxsaber:

你在哪里看到了你的代码中的停顿,仅仅是它的存在就是从头开始摇动TS的唯一原因?你没有这个能力!

所以这段代码说明了为什么必须尽快终止当前线程。你甚至不应该尝试在OnTick中请求交易环境。

void OnTick()
{
   for(int i = 0; i < symbols.Total(); i++)
   {
      request.symbol = symbols.At(i); 
      OrderSendAsynch(request, result); // Начиная с этой строки, анализировать торговое окружение в текущем потоке не имеет смысла
                                        // Единственная верная стратегия - как можно быстрее завершить цикл, и выйти из OnTick
                                        // Для дальнейшего анализа например в OnTransaction      
   }
   // Далее торговое окружение начинает меняться. Мы не можем анализировать его в OnTick
   // Бессмысленно зацикливать OnTick дальше.
   // Результат работы этого кода будет неопределен
   Sleep(50);
   int total_1 = OrdersTotal();
   Sleep(50);
   int total_2 = OrdersTotal();
   //Результат операции не определен
   if(total_1 == total_2)
}

一旦我们处在两个变量的比较点上,我们就无法进行比较,因为环境一直在变化。total_1和total_2中的值要么不再相等,要么都是过时的,要么不包含现有的订单数,要么包含正确的值。在OnTick中对抗不断变化的交易环境是毫无意义的,相反,只需在for循环后立即退出OnTick,并等待表明交易环境已经改变的新事件。

 
Vasiliy Sokolov:

所以这段代码说明了为什么要尽快终止当前线程。你甚至不能尝试在OnTick中查询交易环境。

一旦我们处在两个变量的比较点上,我们就无法进行比较,因为环境一直在变化。total_1和total_2中的值要么不再相等,要么都是过时的,要么不包含现有的订单数,要么包含正确的值。在OnTick中纠结于交易环境的变化是没有意义的,相反,我们只需要在for循环之后退出OnTick,并等待新的事件表明交易环境已经改变。

那么,你为什么要加停顿呢?


再次,在任何暂停(滑点或同步交易订单)之后,TC必须摇身一变 - 交易逻辑必须从零开始。因此,如果使用异步交易订单,就不会发生上述的暂停,而且会有一个退出事件函数,等待一个新的事件。如果没有异步操作,整个交易逻辑甚至可以放在一个循环的脚本中。

 
fxsaber:

那么,你为什么要加停顿呢?

再次,在任何暂停(滑点或同步交易订单)之后,必须重新启动TS - 交易逻辑必须从零开始。因此,如果使用异步交易订单,就不会发生上述的暂停,而且会有一个退出事件函数,等待一个新的事件。如果没有异步操作,整个交易逻辑甚至可以放在一个循环的脚本中。

我将谈论托马斯,而你将谈论尤里。简而言之,让我们完成我们的对话。继续创造你自己的循环脚本。是的,它确实有效,但不能被推荐为一种工作方法。

 

我很想知道他们对MT4中这种情况的看法,他们是如何处理的?


专家顾问的职责是使挂单和未结头寸 在每个刻度上与当前价格保持一定的固定距离。


让经纪人修改的时间比价格点之间的平均时间间隔长一点。


因此,我们在一个反向循环中运行(以SELECT_BY_POS的递减方向),并进行相应的OrderModify。


因此,在这个循环中,打包到OnTick,可能会发生以下情况

  1. OrdersTotal可能会增加(通过手工,例如,打开或部分填充)。
  2. 挂单和头寸的重新索引可能会发生(例如,一些挂单在周期内被执行,或一些挂单被手动删除,一些挂单被放置在一个短坪的机器上)。
  3. 第一或第二点,但没有发生OrderSelect和OrderModify错误。只是在循环过程中,由于P.1/2的原因,一些订单/位置最终会丢失。

该怎么做?

这个问题与上面的讨论有间接关系,但这不是为了继续讨论(话题已结束)。我需要解决MT4Orders在MT5上的一些不明显的细微差别。因此,如果能听到那些擅长MT4的人对所述情况的意见,会很有帮助。而且我并不是唯一一个可能发现它有用的人。


通过OnTimer解决这个问题--这可能是第一个建议。但我们不需要它,只需要OnTick。

 
fxsaber:

我很想知道他们对MT4中这种情况的看法,他们是如何处理的?


专家顾问的职责是使挂单和未结头寸 在每个刻度上与当前价格保持一定的固定距离。


让经纪人修改的时间比价格点之间的平均时间间隔长一点。


因此,我们以反向循环方式运行(以SELECT_BY_POS的递减方向),并进行相应的OrderModify。


因此,在这个循环中,打包到OnTick,可能会发生以下情况

  1. OrdersTotal可能会增加(通过手工,例如,打开或部分填充)。
  2. 挂单和头寸的重新索引可能会发生(例如,一些挂单在周期内被执行,或一些挂单被手动删除,一些挂单被放置在一个短坪的机器上)。
  3. 第一或第二点,但没有发生OrderSelect和OrderModify错误。只是在循环过程中,由于P.1/2的原因,一些订单/位置最终会丢失。

该怎么做?

这个问题与上面的讨论有间接关系,但这不是为了继续讨论(话题已结束)。我需要解决MT4Orders在MT5上的一些不明显的细微差别。因此,如果能听到那些擅长MT4的人对所述情况的意见,会很有帮助。而且我并不是唯一一个可能发现它有用的人。


通过OnTimer解决这个问题--这可能是第一个建议。但让我们跳过它--只有OnTick。

首先,这种情况是非标准的,很少有人,如果有的话,曾经解决过这个问题。

纯粹是理论上的。

我们不需要为OrderModify安排一个反向循环,所以让它直接进行。

int i, total = OrdersTotal();
for(i = 0; i < total; i++)

然后让我们检查一下订单列表的变化

if(total != OrdersTotal())
 {
  i = 0;
  total = OrdersTotal();
  continue;
 }

如果订单量发生了变化,我们将以新的订单量重新开始这个循环。

还有一个问题。

fxsaber:

  1. OrdersTotal可能会增加(通过手工,例如,打开或部分填充)。
  2. 挂单和头寸的重新索引可能会发生(例如,一些挂单在一个周期内被执行,或者一些挂单被手动删除,一些挂单 被放在一个短平快上)。
  3. 第一或第二点,但没有发生OrderSelect和OrderModify错误。只是在循环过程中,由于P.1/2的原因,一些订单/位置最终会丢失

可以理解的是,如果他们被加入,他们或其他人将被错过。但如果它们被简单地删除了呢?我们将不能超越订单清单?