Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 238

 

Non avrei mai immaginato di utilizzare un pezzo di codice generato dalla macchina nel codice sorgente. Soprattutto in un luogo di archiviazione per le prestazioni.


Di seguito è riportato il codice generato.

switch (this.Flag)
{
case 0:
  return(false);
case 1:
  return(Tick.bid >= this.bid.Max);
case 2:
  return(Tick.ask <= this.ask.Min);
case 3:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min));
case 4:
  return(Tick.bid <= this.bid.Min);
case 5:
  return((Tick.bid >= this.bid.Max) || (Tick.bid <= this.bid.Min));
case 6:
  return((Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min));
case 7:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min));
case 8:
  return(Tick.ask >= this.ask.Max);
case 9:
  return((Tick.bid >= this.bid.Max) || (Tick.ask >= this.ask.Max));
case 10:
  return((Tick.ask <= this.ask.Min) || (Tick.ask >= this.ask.Max));
case 11:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.ask >= this.ask.Max));
case 12:
  return((Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 13:
  return((Tick.bid >= this.bid.Max) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 14:
  return((Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 15:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
}

Per la generazione è stato scritto uno script molto più conciso. Può essere utile per testare rapidamente le ipotesi ed evitare errori umani.

 
fxsaber #:

Non avrei mai immaginato di utilizzare un pezzo di codice generato dalla macchina nel codice sorgente. Soprattutto in un luogo di importanza archivistica per le prestazioni.


Di seguito è riportato il codice generato.

Per la generazione è stato scritto uno script molto più conciso. Questo può essere utile per testare rapidamente le ipotesi ed evitare errori umani.

Attenzione, lo stesso ChatGPT commette molti errori, sia nella sintassi che nella logica, quindi bisogna ricontrollare tutto.

Ma è un ottimo generatore, che aiuta a esprimere le idee in codice.

 
fxsaber #:

Di seguito è riportato il codice generato.

Per la generazione è stato scritto uno script molto più conciso. Questo può essere utile per testare rapidamente le ipotesi ed evitare errori umani.

Non ci sono abbastanza informazioni di base: il nuovo codice è diventato più veloce di quello vecchio oppure no?

Se no, perché cambiare il vecchio codice comprensibile con il nuovo incomprensibile?

Se sì, perché il compilatore MQL non è riuscito a generare subito il codice ottimale in termini di prestazioni, visto che ha molte più possibilità di chattare.

 
Aleksey Vyazmikin #:

Attenzione, lo stesso ChatGPT commette molti errori, sia di sintassi che di logica, quindi è necessario ricontrollare tutto.

Ma è un ottimo programma, che aiuta a esprimere le idee in codice.

Generazione dello script.

// Генерация switch-кода.
string GetString( const int Num )
{
  static const string Condition[] = {"(Tick.bid >= this.bid.Max)", "(Tick.ask <= this.ask.Min)",
                                     "(Tick.bid <= this.bid.Min)", "(Tick.ask >= this.ask.Max)"};
  string Str = NULL;

  for (int i = 0; i < ArraySize(Condition); i++)
    if ((bool)(Num & (1 << i)))
      Str += ((Str == NULL) ? NULL : " || ") + Condition[i];

  return(Str);
}

void OnStart()
{
  for (int i = 0; i < 16; i++)
    Print("case " + (string)i + ":\n  return(" + GetString(i) + ");");
}
 
A100 #:

Non ci sono abbastanza informazioni di base: il nuovo codice è diventato più veloce del vecchio o no?

Il nuovo codice è più veloce.

Se sì, allora perché il compilatore MQL non è riuscito a generare subito il codice ottimale in termini di prestazioni, mentre ha molte più possibilità di farlo rispetto alla chat.

Si tratta di ottimizzazione algoritmica, non di ottimizzazione del compilatore.

 
fxsaber #:

Il nuovo è più veloce.

Si tratta di ottimizzazione algoritmica, non di ottimizzazione del compilatore.

Quanto più veloce? Dell'1,5% o di 1,5 volte? E come se fosse più veloce? O sulla base di misurazioni corrette?

Quindi non gli avete dato un codice, ma un algoritmo?

 
A100 #:

Quanto più velocemente? Dell'1,5% o di 1,5 volte? E in base alla sensazione o a misure specifiche?

Quindi non gli avete dato un codice, ma un algoritmo?

È quello che utilizza il codice sorgente di Virtual. Bisogna fare quattro controlli per ogni tick.

return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));


Ma in alcune situazioni (interruttore 0-15) si possono fare meno controlli: 0-4. Dipende dal TS.


Ad esempio, se il TS apre/chiude le posizioni solo con ordini di mercato e non utilizza SL/TP, non è necessario effettuare un solo controllo.

Se invece vengono utilizzati contemporaneamente tutti i tipi di ordini, è necessario effettuare tutti e quattro i controlli: non ci sarà alcuna accelerazione.


Per questo motivo è necessario prendere un TS specifico ed esaminare i risultati delle misurazioni per esso. TS diversi hanno risultati di accelerazione diversi.


Era possibile classificare i casi (numero di casi) in più varianti. Francamente non ci sono riuscito.

 

In MQL5, esiste una funzione StringReserve, con la quale possiamo teoricamente ridurre il numero di riallocazioni di memoria per la nostra stringa: abbiamo allocato un buffer abbastanza grande in una sola volta e poi lavoriamo in esso.

Ma, come dimostra la pratica, ogni successiva assegnazione di un valore a questa stringa cambia la dimensione del suo buffer (cioè, apparentemente, si verifica una riallocazione di memoria).

Di conseguenza, invece di

string str;
str.Reserve(8192);
str="test";

ha senso usare

string str;
str.Reserve(8192);
StringSetLength(str,0);  // или str.SetLen(0); - в документации есть, но у меня в 4073 не поддерживается
str+="test";
 
JRandomTrader #:

ha senso utilizzare

Esattamente. Questo meccanismo funziona benissimo con il completamento delle stringhe. Ad esempio, quando si generano rapporti HTML di grandi dimensioni.

 

Come posso scoprire se un simbolo ha dei dati, in modo da non lasciarlo nella finestra [Market Watch] se non li ha?

Utilizzo tale controllo in un ciclo:

ulong first_server_date = (ulong)SeriesInfoInteger(symbol, PERIOD_M1, SERIES_SERVER_FIRSTDATE);

if(first_server_date == NULL) {
  SymbolSelect(symbol, false);
  continue;
}

Ma poi non posso rimuovere manualmente i simboli dalla finestra [Market Watch], né uno per uno né tutti insieme, mentre l'Expert Advisor è sul grafico: