Caractéristiques du langage mql5, subtilités et techniques - page 88

 

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading

Bugs, bugs, questions

fxsaber, 2016.07.19 12:41

Quel est l'intérêt d'avoirENUM_DEAL_PROPERTY_INTEGER::DEAL_TICKET si le seul endroit où l'appliquer est HistoryDealGetInteger(TicketDeal, DEAL_TICKET) ?

Avec l'exemple de ORDER_TICKET, l'idée devrait être claire.

Forum sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

OrderCloseTime () dans 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);
}

Nous pouvons donc vérifier si la table d'historique actuelle, générée précédemment par la fonction HistorySelect, contient l'enregistrement dont nous avons besoin. Il en va de même pour DEAL_TICKET.

 

Forum sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

Sauvegarder le niveau de prix de la position via le clearing (est-ce 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);
}
 

Tout le monde ne sait pas que la fonction GetMicrosecondCount, contrairement à GetTickCount, est liée à l'heure locale de l'ordinateur, ce qui signifie que si cette heure change (par exemple en raison d'une synchronisation avec l'heure Internet), les valeurs GetMicrosecondCount changeront également d'une valeur correspondante.Il faut en tenir compte si cette fonction est utilisée pour mesurer des intervalles de temps ; en fait, elle ne devrait pas être utilisée à cette fin. GetTickCount, en revanche, ne présente pas ces problèmes.

À titre de démonstration, vous pouvez exécuter ce code et modifier l'heure de l'ordinateur pendant son exécution.

  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:

Tout le monde ne sait peut-être pas que la fonction GetMicrosecondCount, contrairement à GetTickCount, est liée à l'heure locale de l'ordinateur.

Je ne le savais pas, merci !

 

Une variante de la fonction GetTickCount qui évite les débordements (à condition que l'intervalle entre les appels à la fonction ne dépasse pas 50 jours).

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:

Tout le monde ne sait pas que la fonction GetMicrosecondCount, contrairement à GetTickCount, est liée à l'heure locale de l'ordinateur, ce qui signifie que si cette heure change (par exemple en raison d'une synchronisation avec l'heure Internet), les valeurs GetMicrosecondCount changeront également d'une valeur correspondante.Il faut en tenir compte si cette fonction est utilisée pour mesurer des intervalles de temps ; en fait, elle ne devrait pas être utilisée à cette fin. GetTickCount, en revanche, ne présente pas ces problèmes.

Pour le démontrer, vous pouvez exécuter ce code et modifier l'heure de l'ordinateur pendant l'exécution du code.

Eh bien, c'est un bug que les développeurs devraient corriger. La fonction ne correspond alors pas à la description :

Функция GetMicrosecondCount() возвращает количество микросекунд, прошедших с момента начала работы MQL5-программы.
La valeur de cette fonction par rapport à GetTickCount est de l'ordre de la microseconde et non de la milliseconde (précision 1000 fois supérieure). Il est également non gonflable.
C'est pourquoi il n'est pas tout à fait correct de parler de sa substituabilité.
 
Alexey Navoykov:

Tout le monde ne sait pas que la fonction GetMicrosecondCount, contrairement à GetTickCount, est liée à l'heure locale de l'ordinateur, ce qui signifie que si cette heure change (par exemple en raison d'une synchronisation avec l'heure Internet), les valeurs GetMicrosecondCount changeront également d'une valeur correspondante.Il faut en tenir compte si cette fonction est utilisée pour mesurer des intervalles de temps ; en fait, elle ne devrait pas être utilisée à cette fin. GetTickCount, en revanche, ne présente pas ces problèmes.

Pour le démontrer, nous pouvons exécuter ce code et modifier l'heure de l'ordinateur pendant son exécution.

Une autre observation importante - il en découle qu'il est absolument inapproprié d'utiliser la fonction GetTickCount au lieu de GetMicrosecondCount.
Je pense que ce sera une surprise pour beaucoup de gens.

En examinant le fonctionnement d'un 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)+ " наносекунды");
  }

Le résultat du travail :

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 наносекунды

nous pouvons tirer les conclusions suivantes :

  • La valeur de la fonction GetTickCount() ne change pas toutes les millisecondes mais toutes les 15,625millisecondes(1/64 de seconde, 64=2^6), alors que la valeur de la fonction GetMicrosecondCount() change toutes les micro deuxième. Cela signifie que la fonction GetMicrosecondCount est 15625 fois plus précise que GetTickCount, et non 1000.
  • mais la fonction GetTickCount() est environ 12 à 15 fois plus rapide que GetMicrosecondCount().
 
Nikolai Semko:

Eh bien, c'est un bogue que les développeurs feraient bien de corriger. Car alors la fonction ne correspond pas à la description :

La valeur de cette fonction par rapport à GetTickCount est de l'ordre de la microseconde et non de la milliseconde (1000 fois plus précise). Il est également non gonflable.
C'est pourquoi il n'est pas tout à fait correct de parler de sa substituabilité.

Si vous mesurez le temps d'exécution de certaines sections de programme, les fluctuations des performances du système annulent toute cette précision et l'erreur se compte en millisecondes, voire en dizaines de millisecondes. Si vous mesurez de très petits segments dont la durée est inférieure à 1 milliseconde, alors à quoi bon. La part d'erreur de mesure sera très élevée.

 
Alexey Navoykov:

Je n'ai pas encore vu d'utilisation pratique des microsecondes. Si vous mesurez le temps d'exécution de certaines sections de programme, les fluctuations des performances du système annuleront toute cette précision, et l'erreur sera de l'ordre de la milliseconde, voire de la dizaine de millisecondes. Si vous mesurez de très petits segments dont la durée est inférieure à une milliseconde, alors à quoi bon. L'erreur de mesure sera très élevée.

  1. voir mon message précédent
  2. J'ai beaucoup d'exemples d'utilisation pratique des microsecondes.

 
Nikolai Semko:

Une autre observation importante suggère qu'il est absolument inapproprié d'utiliser la fonction GetTickCount au lieu de GetMicrosecondCount.
Je pense que ce sera une surprise pour de nombreux programmeurs.

En examinant le fonctionnement d'un simple script :

les conclusions suivantes peuvent être tirées :

  • La valeur de la fonction GetTickCount () change toutes les 15,6 millisecondes au lieu de chaque milliseconde, tandis que la valeur de la fonction GetMicrosecondCount() change toutes les micro deuxième. Cela signifie que GetMicrosecondCount est 15600 fois plus précis que GetTickCount, et non 1000.
  • mais GetTickCount() est environ 12 à 15 fois plus rapide que GetMicrosecondCount().

L'argument de poids