Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 88

 

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Bug, bug, domande

fxsaber, 2016.07.19 12:41

Che senso ha avereENUM_DEAL_PROPERTY_INTEGER::DEAL_TICKET se l'unico posto dove applicarlo è HistoryDealGetInteger(TicketDeal, DEAL_TICKET)?

Con l'esempio di ORDER_TICKET l'idea dovrebbe essere chiara.

Forum sul trading, sistemi di trading automatico e test di strategie di trading

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);
}

Così possiamo controllare se la tabella della storia corrente, precedentemente generata attraverso la funzione HistorySelect, contiene il record di cui abbiamo bisogno. Lo stesso vale per DEAL_TICKET.

 

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Salvare il livello di prezzo della posizione tramite compensazione (è possibile?)

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);
}
 

Non tutti sanno che la funzione GetMicrosecondCount, a differenza di GetTickCount, è legata all'ora locale del computer. Ciò significa che se questa ora cambia (ad esempio a causa della sincronizzazione con l'ora di Internet), anche i valori GetMicrosecondCount cambieranno di un valore corrispondente.Questo dovrebbe essere tenuto a mente se questa funzione è usata per misurare intervalli di tempo; infatti, non dovrebbe essere usata per questo scopo. GetTickCount, d'altra parte, non ha questi problemi.

Come dimostrazione, potete eseguire questo codice e cambiare l'ora del computer mentre è in esecuzione.

  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:

Forse non tutti sanno che la funzione GetMicrosecondCount, a differenza di GetTickCount, è legata all'ora locale del computer.

Non lo sapevo, grazie!

 

Una variante della funzione GetTickCount che evita gli overflow (a condizione che l'intervallo tra le chiamate alla funzione non superi i 50 giorni)

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:

Non tutti sanno che la funzione GetMicrosecondCount, a differenza di GetTickCount, è legata all'ora locale del computer. Ciò significa che se questa ora cambia (ad esempio a causa della sincronizzazione con l'ora di Internet), anche i valori GetMicrosecondCount cambieranno di un valore corrispondente.Questo dovrebbe essere tenuto a mente se questa funzione è usata per misurare intervalli di tempo; infatti, non dovrebbe essere usata per questo scopo. GetTickCount, d'altra parte, non ha questi problemi.

Per dimostrarlo, potete eseguire questo codice e cambiare l'ora del computer durante l'esecuzione del codice.

Beh, questo è un bug che gli sviluppatori dovrebbero risolvere. La funzione quindi non corrisponde alla descrizione:

Функция GetMicrosecondCount() возвращает количество микросекунд, прошедших с момента начала работы MQL5-программы.
Il valore di questa funzione rispetto a GetTickCount è di microsecondi, non di millisecondi (precisione 1000 volte superiore). È anche non gonfiabile.
Ecco perché non è del tutto corretto parlare della sua sostituibilità.
 
Alexey Navoykov:

Non tutti sanno che la funzione GetMicrosecondCount, a differenza di GetTickCount, è legata all'ora locale del computer. Ciò significa che se questa ora cambia (ad esempio a causa della sincronizzazione con l'ora di Internet), anche i valori GetMicrosecondCount cambieranno di un valore corrispondente.Questo dovrebbe essere tenuto a mente se questa funzione è usata per misurare intervalli di tempo; infatti, non dovrebbe essere usata per questo scopo. GetTickCount, d'altra parte, non ha questi problemi.

Per dimostrarlo, possiamo eseguire questo codice e cambiare il tempo del computer durante la sua esecuzione.

Un'altra osservazione importante - ne consegue che è assolutamente inappropriato usare la funzione GetTickCount invece di GetMicrosecondCount.
Penso che sarà una sorpresa per molte persone.

Esaminando il funzionamento di un semplice 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)+ " наносекунды");
  }

Il risultato del lavoro:

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

possiamo trarre le seguenti conclusioni:

  • Il valore della funzione GetTickCount() non cambia ogni millisecondo ma ogni 15,625millisecondi(1/64 di secondo, 64=2^6), mentre il valore della funzione GetMicrosecondCount() cambia ogni micro secondo. Significa che la funzione GetMicrosecondCount è 15625 volte più precisa di GetTickCount, non 1000.
  • ma la funzione GetTickCount() è circa 12-15 volte più veloce di GetMicrosecondCount().
 
Nikolai Semko:

Bene, allora questo è un bug che gli sviluppatori farebbero bene a risolvere. Perché allora la funzione non corrisponde alla descrizione:

Il valore di questa funzione rispetto a GetTickCount è microsecondi, non millisecondi (1000 volte più preciso). È anche non gonfiabile.
Ecco perché non è del tutto corretto parlare della sua sostituibilità.

Se si misura il tempo di esecuzione di alcune sezioni del programma, le fluttuazioni delle prestazioni del sistema livellano tutta questa precisione e c'è un errore in millisecondi o anche decine di millisecondi. Se si misurano segmenti molto piccoli con durata inferiore a 1 millisecondo, allora che senso ha. La quota di errore di misurazione sarà molto alta.

 
Alexey Navoykov:

Non ho ancora visto alcun uso pratico dei microsecondi. Se si misura il tempo di esecuzione di alcune sezioni del programma, le fluttuazioni delle prestazioni del sistema livelleranno tutta questa precisione, e l'errore è sui millisecondi, o anche decine di millisecondi. Se si misurano segmenti molto piccoli con durata inferiore a 1 millisecondo, allora qual è il punto. L'errore di misurazione sarà molto alto.

  1. vedere il mio post precedente
  2. Ho un sacco di esempi con l'uso pratico dei microsecondi.

 
Nikolai Semko:

Un'altra importante osservazione suggerisce che usare la funzione GetTickCount invece di GetMicrosecondCount è abbastanza inappropriato.
Penso che sarà una sorpresa per molti programmatori.

Esaminando il funzionamento di un semplice script:

si possono trarre le seguenti conclusioni:

  • Il valore della funzione GetTickCount () cambia ogni 15,6 millisecondi invece che ogni millisecondo, mentre il valore della funzione GetMicrosecondCount() cambia ogni micro secondo. Significa che GetMicrosecondCount è 15600 volte più preciso di GetTickCount, non 1000.
  • ma GetTickCount() è circa 12-15 volte più veloce di GetMicrosecondCount().

L'argomento significativo

Motivazione: