Organising the order cycle - page 5

 
Vasiliy Sokolov:

Looping is one of the most dangerous programming techniques. It causes strange, infrequent errors that are almost impossible to analyze.

On the contrary, you should try to end a user thread as quickly as possible instead of looping. If you want to keep your hand on the pulse - analyze OnTradeTransaction in MT5. MT4 is generally not suitable for such games, because simplicity is worse than theft, as they say.

I meant not a concrete realization, but the principle of TS shaking after any pause. Well and where there is a terrible fixation - is not clear. As it is not clear, why there is a rush to finish a user thread.

 
fxsaber:

Where is the scary looping there - it's not clear.

Calling OnTick from OnTick is a non-trivial loop through recursion:

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

Neither is it clear why there is a rush to terminate the user thread.

We are working with an event-driven model. Therefore we need to handle the current event as fast as possible to wait for the next one. Time spent in the thread is a black hole. The more time we spend in the flow, the more outdated the trading environment we are working with.

 
Vasiliy Sokolov:

Calling OnTick from OnTick is a non-trivial loop through recursion:

Apparently, this is the only thing that deters.

We are working with an event model. Therefore, we need to handle the current event as fast as possible in order to wait for the next one. Time spent in the flow is a black hole. The more time we spend in the flow, the more outdated the trading environment we work with.

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

s. We don't understand each other at all. I don't think there can be any dialogue between us.

 
Vasiliy Sokolov:
:

Where did you see a pause in your code, the mere presence of which is the only reason for shaking the TS from scratch? You do not have it!

 
fxsaber:

Where did you see a pause in your code, the mere presence of which is the only reason for shaking the TS from scratch? You do not have it!

So this code is an illustration of why the current thread must be terminated as soon as possible. You should not even try to request the trade environment in 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)
}

Once we are at the point where the two variables are compared, we cannot compare them because the environment keeps changing. The values in total_1 and total_2 are either no longer equal to each other, or they are both obsolete, or they do not contain the existing number of orders, or they contain the correct values. It is pointless to fight a changing trading environment in OnTick, instead just exit OnTick, immediately after the for loop, and wait for new events indicating that the trading environment has changed.

 
Vasiliy Sokolov:

So this code is an illustration of why the current thread should be terminated as quickly as possible. You cannot even attempt to query the trading environment in OnTick:

Once we are at the point where the two variables are compared, we cannot compare them because the environment keeps changing. The values in total_1 and total_2 are either no longer equal to each other, or they are both obsolete, or they do not contain the existing number of orders, or they contain the correct values. It is pointless to struggle with changing trade environment in OnTick, instead, we just need to exit OnTick, right after the for loop, and wait for new events indicating that the trade environment has changed.

So why did you put pauses?!


Once again, after any pause (slips or synchronous trade orders) TC must be shaken up - the trading logic must be started from zero. Accordingly, if asynchronous trade orders are used, the pauses mentioned do not occur and there is an exit from the Event-Function waiting for a new event. If there are no asynchronous operations, the entire trading logic can even be placed in a looped script.

 
fxsaber:

So why did you put pauses?!

Once again, after any pause (slips or synchronous trade orders) the TS must be restarted - the trading logic must be started from zero. Accordingly, if asynchronous trade orders are used, the pauses mentioned do not occur and there is an exit from the Event-Function waiting for a new event. If there are no asynchronous operations, the entire trading logic can even be placed in a looped script.

I will speak about Thomas, and you will speak about Yury. In short, let's finish our dialogue. Go on creating your own looped scripts. Yes, it really works, but it cannot be recommended as a working method.

 

I am interested to know their opinion on this situation in MT4, how do they handle it?


The Expert Advisor's ToR is to keep pending orders and open positions on a certain fixed distance from the current price on every tick.


Let the broker modifications take a little longer than the average time interval between price ticks.


So, we run in a reverse cycle (in decreasing direction of SELECT_BY_POS) and make corresponding OrderModify.


So, during this loop, packed into OnTick, the following may happen

  1. OrdersTotal may increase (by hand, for example, opened or partial fillings).
  2. Re-indexing of pending orders and positions may occur (for example, some pending orders were executed during the cycle, or some pending orders were manually deleted, and some pending orders were placed on a machine with a short ping).
  3. 1st or 2nd point, but no OrderSelect and OrderModify error occurs. Just during the cycle because of p.1/2 some orders/positions will end up missing.

What to do?

The question is indirectly related to the discussion above, but this is not for its continuation (topic closed). I need to solve some not obvious nuances in MT4Orders for MT5. So it would be useful to hear the opinion on the described situations from those who are good at MT4 specifically. And I am not the only one who may find it useful.


Solve the problem through OnTimer - this is probably the first suggestion. But we do not need it - only OnTick.

 
fxsaber:

I am interested to know their opinion on this situation in MT4, how do they handle it?


The Expert Advisor's ToR is to keep pending orders and open positions on a certain fixed distance from the current price on every tick.


Let the broker modifications take a little longer than the average time interval between price ticks.


So, we run in a reverse cycle (in decreasing direction of SELECT_BY_POS) and make corresponding OrderModify.


So, during this loop, packed into OnTick, the following may happen

  1. OrdersTotal may increase (by hand, for example, opened or partial fillings).
  2. Re-indexing of pending orders and positions may occur (for example, some pending orders were executed during the cycle, or some pending orders were manually deleted, and some pending orders were placed on a machine with a short ping).
  3. 1st or 2nd point, but no OrderSelect and OrderModify error occurs. Just during the cycle because of p.1/2 some orders/positions will end up missing.

What to do?

The question is indirectly related to the discussion above, but this is not for its continuation (topic closed). I need to solve some not obvious nuances in MT4Orders for MT5. So it would be useful to hear the opinion on the described situations from those who are good at MT4 specifically. And I am not the only one who may find it useful.


Solve the problem through OnTimer - this is probably the first suggestion. But let us skip it - only OnTick.

Firstly, the situation is non-standard and very few people, if any, have ever solved it.

Purely theoretically:

We don't have to arrange a reverse loop for OrderModify, so let it be direct.

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

Then let's check for changes of the list of orders

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

If the amount of orders has changed, we will start this loop anew with a new amount of orders.

One more question:

fxsaber:

  1. OrdersTotal may increase (by hand, for example, opened or partial fillings).
  2. Re-indexing of pending orders and positions may happen (for example, some pending order was executed during a cycle, or some pending orders were manually deleted, and some pending orders were placed on a short ping).
  3. 1st or 2nd point, but no OrderSelect and OrderModify error occurs. It's just that during the cycle due to p.1/2 some orders/positions will end up missing.

It's understandable that if they were added, they or others will be missed. But what if they were simply deleted? We would not be able to go beyond the order list?