Features of the mql5 language, subtleties and tricks - page 88

 

Forum on trading, automated trading systems and trading strategies testing

Bugs, bugs, questions

fxsaber, 2016.07.19 12:41

What is the point ofENUM_DEAL_PROPERTY_INTEGER::DEAL_TICKET if the only place where it can be applied is HistoryDealGetInteger(TicketDeal, DEAL_TICKET)?

On the example of ORDER_TICKET, the idea should be clear.

Forum on trading, automated trading systems and testing trading strategies

OrderCloseTime () in MQL5?

fxsaber, 2018.07.18 03:51

datetime OrderCloseTime( const ulong Ticket )
{
  return((HistoryOrderGetInteger(Ticket, ORDER_TICKET) == Ticket) || HistoryOrderSelect(Ticket) ? (datetime)HistoryOrderGetInteger(Ticket, ORDER_TIME_DONE) : 0);
}

So we can check if the current history table, previously generated through HistorySelect-functions, contains the record we need. The same applies to DEAL_TICKET.

 

Forum on trading, automated trading systems and trading strategies testing

Save position price level through clearing (is it possible?)

fxsaber, 2018.07.17 20:45

// Возвращает цену открытия выбранной позиции без учета клиринга
double GetSummaryPositionPrice()
{
  double TotalVolume = 0;
  double TotalDealPrice = 0;
  
  if (HistorySelectByPosition(PositionGetInteger(POSITION_IDENTIFIER)))
  {
    const int DealsTotal = HistoryDealsTotal();
    
    for (int i = 0; i < DealsTotal; i++)
    {
      const ulong DealTicket = HistoryDealGetTicket(i);
      
      if (HistoryDealGetInteger(DealTicket, DEAL_ORDER))
      {
        const double DealVolume = (HistoryDealGetInteger(DealTicket, DEAL_TYPE) ? -1 : 1) * HistoryDealGetDouble(DealTicket, DEAL_VOLUME);
        const double DealPrice = HistoryDealGetDouble(DealTicket, DEAL_PRICE);
  
        if (TotalVolume * DealVolume >= 0)
          TotalDealPrice = (TotalDealPrice * TotalVolume + DealPrice * DealVolume) / (TotalVolume + DealVolume);
        else if (MathAbs(DealVolume) - MathAbs(TotalVolume) > 0.005)
          TotalDealPrice = DealPrice;
          
        TotalVolume += DealVolume;
      }      
    }
  }
  
  return(TotalDealPrice);
}
 

Perhaps not everyone knows that the GetMicrosecondCount function, unlike GetTickCount, is tied to the local computer time, i.e. if this time changes (e.g. due to synchronization with Internet time), the GetMicrosecondCount values will also change by a corresponding value.This should be kept in mind if this function is used for measuring time intervals. As a matter of fact, you should not use it for such purposes. GetTickCount, on the other hand, does not have these problems.

As a demonstration, you can run this code and change the computer time while it is running.

  datetime time= TimeLocal();
  ulong    microsec= GetMicrosecondCount();
  uint     ticks= GetTickCount();
  
  while(!IsStopped())
  {
    Comment(int(TimeLocal()-time),"   ",(GetMicrosecondCount()-microsec)/1000000,"   ",(GetTickCount()-ticks)/1000);
    Sleep(10);
  }
 
Alexey Navoykov:

Perhaps not everyone knows that the GetMicrosecondCount function, unlike GetTickCount, is tied to the local computer time.

I did not know that, thank you!

 

A variant of the GetTickCount function that excludes overflows (provided that the interval between function calls does not exceed 50 days)

ulong GetTickCountLong()
{
  static ulong sum=0;
  static uint  lasttickcount=0;
  uint tickcount= GetTickCount();
  if (tickcount<lasttickcount) sum+=0x100000000;
  lasttickcount= tickcount;
  return sum + tickcount;
}
 
Alexey Navoykov:

Perhaps not everyone knows that the GetMicrosecondCount function, unlike GetTickCount, is tied to the local computer time, i.e. if this time changes (e.g. due to synchronization with Internet time), the GetMicrosecondCount values will also change by a corresponding value.This should be kept in mind if this function is used for measuring time intervals. As a matter of fact, you should not use it for such purposes. GetTickCount, on the other hand, does not have these problems.

As a demonstration, you can run such code and change the computer time while it is running.

Well, then it is a bug the developers should fix. Because then the function does not fit the description:

Функция GetMicrosecondCount() возвращает количество микросекунд, прошедших с момента начала работы MQL5-программы.
The value of this function compared to GetTickCount is microseconds, not milliseconds (1000 times higher accuracy). It's also non-inflatable.
That's why it's not quite correct to speak about its substitutability.
 
Alexey Navoykov:

Perhaps not everyone knows that the GetMicrosecondCount function, unlike GetTickCount, is tied to the local computer time, i.e. if this time changes (e.g. due to synchronization with Internet time), the GetMicrosecondCount values will also change by a corresponding value.This should be kept in mind if this function is used for measuring time intervals. As a matter of fact, you should not use it for such purposes. GetTickCount, on the other hand, does not have these problems.

As a demonstration, you can run this code and change the computer's time while it is running.

One more important observation: it follows from this that it is absolutely inappropriate to use the GetTickCount function instead of GetMicrosecondCount.
I think that will be a surprise for many people.

In examining the work of a simple script:

void OnStart()
  {
   uint i=GetTickCount();
   uint i0=GetTickCount();
   while(i==i0) i0=GetTickCount(); 
   
   int N1=1;
   ulong t1=GetMicrosecondCount();
   uint i1=GetTickCount();
   uint i2=GetTickCount();
   while(i1==i2) { i2=GetTickCount(); N1++;}
   t1=GetMicrosecondCount()-t1;
   
   ulong t=GetMicrosecondCount();
   ulong t0=GetMicrosecondCount();
   while(t==t0) t0=GetMicrosecondCount(); 
   int N2=1;
   ulong t2=GetMicrosecondCount();
   ulong t3=GetMicrosecondCount();
   while(t2==t3) { t3=GetMicrosecondCount(); N2++;}
   ulong t4=t3-t2;

   Print("1 значение в милисекундах:  " +(string)i1+", следующее значение   "+ (string)i2 + ", разница - " +(string)t1 + 
   " микросекунд, время выполнения функции GetTickCount (одного прохода цикла) = " +DoubleToString((double)t1*1000.0/N1,3)+ " наносекунды");
   
   Print("1 значение в микросекундах: " +(string)t2+", следующее значение   "+ (string)t3 + ", разница - " +(string)t4 + 
   " микросекунд, время выполнения функции GetMicrosecondCount (одного прохода цикла) = " +DoubleToString((double)t4*1000.0/N2,3)+ " наносекунды");
  }

The result of the work:

2018.07.27 00:23:02.261 TestTimeCount   1 значение в милисекундах:  25225093, следующее значение   25225109, разница - 15663 микросекунд, время выполнения функции GetTickCount (одного прохода цикла) = 2.323 наносекунды
2018.07.27 00:23:02.261 TestTimeCount   1 значение в микросекундах: 20247, следующее значение   20248, разница - 1 микросекунд, время выполнения функции GetMicrosecondCount (одного прохода цикла) = 33.333 наносекунды
2018.07.27 00:23:03.590 TestTimeCount   1 значение в милисекундах:  25226421, следующее значение   25226437, разница - 15586 микросекунд, время выполнения функции GetTickCount (одного прохода цикла) = 2.324 наносекунды
2018.07.27 00:23:03.590 TestTimeCount   1 значение в микросекундах: 22835, следующее значение   22836, разница - 1 микросекунд, время выполнения функции GetMicrosecondCount (одного прохода цикла) = 30.303 наносекунды
2018.07.27 00:23:04.920 TestTimeCount   1 значение в милисекундах:  25227750, следующее значение   25227765, разница - 15657 микросекунд, время выполнения функции GetTickCount (одного прохода цикла) = 2.309 наносекунды
2018.07.27 00:23:04.920 TestTimeCount   1 значение в микросекундах: 23701, следующее значение   23702, разница - 1 микросекунд, время выполнения функции GetMicrosecondCount (одного прохода цикла) = 27.027 наносекунды

we can draw the following conclusions:

  • The value of the GetTickCount () function changes not every millisecond but every 15.625milliseconds(1/64 of a second, 64=2^6), whereas the value of the GetMicrosecondCount() function changes every micro second. It means that the GetMicrosecondCount function is 15625 times more accurate than GetTickCount, not 1000.
  • but the GetTickCount() function is approximately 12-15 times faster than GetMicrosecondCount().
 
Nikolai Semko:

Well then this is a bug, which the developers would do well to fix. Because then the function does not correspond to the description:

The value of this function compared to GetTickCount is microseconds, not milliseconds(1000 times more accurate). It's also non-inflateable.
That's why it's not quite correct to talk about its substitutability.

If you measure execution time of some parts of the program, system performance fluctuations level out all this accuracy, and the error is on milliseconds or even tens of milliseconds. If you measure very small segments with duration less than 1 millisecond, then what's the point in it. The share of error in measurements will be very high.

 
Alexey Navoykov:

I haven't seen any practical use of microseconds yet. If you measure the execution time of some program sections, then fluctuations in system performance level out all this accuracy, and the error there is in milliseconds, or even tens of milliseconds. If you measure very small segments of duration less than 1 millisecond, then what is the point. The share of error of measurements will be very high.

  1. See my previous post.
  2. I have a lot of examples with practical use of microseconds.

 
Nikolai Semko:

Another important observation, which implies that using the GetTickCount function instead of GetMicrosecondCount is absolutely inappropriate.
I think this will be a surprise for many programmers.

Examining the work of a simple script:

the following conclusions can be drawn:

  • The value of the GetTickCount () function changes not every millisecond but every 15.6 milliseconds, while the value of the GetMicrosecondCount () function changes every micro second. It means that GetMicrosecondCount is 15600 times more accurate than GetTickCount, not 1000.
  • but GetTickCount() is approximately 12-15 times faster than GetMicrosecondCount().

The significant argument

Reason: