The great and terrible MT4 forever (or how to strategise a transition) - page 14

 
Ihor Herasko:

Yes, that's my point too. It turns out that the script manages to close one of the positions, when in fact there are two, but PositionsTotal() returns 1. And then, after closing, the cycle end condition is met, i.e. PositionsTotal() returns 2.

You can insert printouts to fully see what's going on.

 
fxsaber:

Printouts can be inserted to fully see what is going on.

Yes, to confirm that the reasoning is correct:

#include <Trade\Trade.mqh>

void OnStart()
{
  CTrade Trade;
  
  while (!IsStopped() && (PositionsTotal() <= 1)) // Закончим, когда появится более одной позиции.
    if (PositionsTotal() == 1)
    {
      Trade.PositionClose(PositionGetTicket(0)); // Если есть позиция - закрываем.
      Print("Закрытие, т. к. PositionsTotal() равно 1");
    }
    else if (!OrdersTotal())
    {
      Trade.Buy(0.01); // Если нет позиции и ордера - открываем позицию.
      
Print("Открытие. PositionsTotal: ", PositionsTotal()); 
    }
    
  Print("Выход. PostionsTotal: ", PositionsTotal());
}

Result:

2021.05.05 10:11:43.393 Test (EURUSD,M1)        Открытие. PositionsTotal: 0
2021.05.05 10:11:43.488 Test (EURUSD,M1)        Закрытие, т. к. PositionsTotal() равно 1
2021.05.05 10:11:43.535 Test (EURUSD,M1)        CTrade::OrderSend: market sell 0.01 position #2249868517  EURUSD [position closed]
2021.05.05 10:11:43.535 Test (EURUSD,M1)        Закрытие, т. к. PositionsTotal() равно 1
2021.05.05 10:11:43.615 Test (EURUSD,M1)        Открытие. PositionsTotal: 0
2021.05.05 10:11:43.697 Test (EURUSD,M1)        Закрытие, т. к. PositionsTotal() равно 1
2021.05.05 10:11:43.777 Test (EURUSD,M1)        Открытие. PositionsTotal: 0
2021.05.05 10:11:43.859 Test (EURUSD,M1)        Закрытие, т. к. PositionsTotal() равно 1
2021.05.05 10:11:43.941 Test (EURUSD,M1)        Открытие. PositionsTotal: 0
2021.05.05 10:11:44.023 Test (EURUSD,M1)        Открытие. PositionsTotal: 1
2021.05.05 10:11:44.101 Test (EURUSD,M1)        Закрытие, т. к. PositionsTotal() равно 1
2021.05.05 10:11:44.101 Test (EURUSD,M1)        Выход. PostionsTotal: 2

In fact, the position is left alone hanging.

P. S. Corrected the post, because I put the wrong thing in the code because of the copy-paste.
 
Ihor Herasko:

In fact, the position was left alone hanging.

In the log, it is likely that the recording time of the last trade follows the recording time of the script closing.

It is also important to print OrdersTotal.
 
fxsaber:

In the log, it is likely that the time of the last trade record follows the time of the script's closing record.

Are you referring to these two records?

2021.05.05 10:11:44.101 Test (EURUSD,M1)        Закрытие, т. к. PositionsTotal() равно 1
2021.05.05 10:11:44.101 Test (EURUSD,M1)        Выход. PostionsTotal: 2

I think everything is correct here in terms of ordering. There are in fact two positions but PositionsTotal() has not yet received an update. Therefore, it returns 1 and the position is closed. And after the trade operation is executed, it is updated to the state that corresponds to the one that existed before the trade operation was executed. So, we get 2.

 
fxsaber:

The problem has been discussed for a long time. Almost everyone has encountered it. It is the first time that a stable reproducible code has been found.

A solution has been found.

And what is the solution?

What was the difficulty in finding a stable reproducing code? One action to open or close, and the next with a decision based on the numbers of positions in the market or in the history.
 
Ihor Herasko:

Are you referring to these two records?

No, the last record of trading activity is in the second log.

 
fxsaber:

It is also important to print OrdersTotal.

I have added prints. Now two positions remain, as expected:

#include <Trade\Trade.mqh>

void OnStart()
{
  CTrade Trade;
  
  while (!IsStopped() && (PositionsTotal() <= 1)) // Закончим, когда появится более одной позиции.
    if (PositionsTotal() == 1)
    {
      Trade.PositionClose(PositionGetTicket(0)); // Если есть позиция - закрываем.
      Print("Закрытие, т. к. PositionsTotal() равно 1");
    }
    else if (!OrdersTotal())
    {
      printf("Перед открытием. PositionsTotal: %d, OrdersTotal: %d", PositionsTotal(), OrdersTotal());
      Trade.Buy(0.01); // Если нет позиции и ордера - открываем позицию.
      printf("После открытия. PositionsTotal: %d, OrdersTotal: %d", PositionsTotal(), OrdersTotal());
    }
    
  Print("Выход. PostionsTotal: ", PositionsTotal());
}

Result:

2021.05.05 10:22:50.583 Test (EURUSD,M1)        Перед открытием. PositionsTotal: 0, OrdersTotal: 0
2021.05.05 10:22:50.663 Test (EURUSD,M1)        После открытия. PositionsTotal: 0, OrdersTotal: 1
2021.05.05 10:22:50.679 Test (EURUSD,M1)        Перед открытием. PositionsTotal: 0, OrdersTotal: 0
2021.05.05 10:22:50.757 Test (EURUSD,M1)        После открытия. PositionsTotal: 2, OrdersTotal: 0
2021.05.05 10:22:50.757 Test (EURUSD,M1)        Выход. PostionsTotal: 2
 
Dmitry Fedoseev:

What is the solution?

the number of positions in the market or in the history.

There was no difficulty, I wrote it on the fly.

 

It opens positions like this without stopping at all

#include <Trade\Trade.mqh>
CTrade Trade;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int total=PositionsTotal();
   int Ordertotal=OrdersTotal();
   while(!IsStopped() && (total <= 1))  // Закончим, когда появится более одной позиции.
      if(total == 1)
         Trade.PositionClose(PositionGetTicket(0)); // Если есть позиция - закрываем.
      else
         if(!Ordertotal)
            Trade.Buy(0.01); // Если нет позиции и ордера - открываем позицию.
  }
//+------------------------------------------------------------------+

Photo by

 
SanAlex:

It opens positions like this without stopping at all

Well, who's going to update the total? ))