Errori, bug, domande - pagina 1999

 
Alexey Viktorov:

Prendiamo ad esempio un array di buffer di indicatori: quando si inizializza un indicatore, il buffer ha una lunghezza zero. Cosa c'è da inizializzare con degli zeri? Quando viene aggiunto un altro indice, è forzato ad essere azzerato e poi riempito con qualche valore? A cosa serve questo azzeramento o riempimento con EMPTY_VALUE? E se c'è bisogno di assegnare PLOT_EMPTY_VALUE e non 0 o EMPTY_VALUE o di forzare uno, ma abbiamo bisogno di un altro... In qualunque modo la si tagli, si finisce per perdere il proprio tempo...

E un array personalizzato... L'array è dichiarato per qualche dato diverso da zero e EMPTY_VALUE. Allora qual è lo scopo di inizializzarlo forzatamente con qualcosa?

Così si scopre che le prestazioni sono influenzate nella maggior parte dei casi.

È evidente che sono fuori dalla vita. A mio avviso, il buffer dell'indicatore ha sempre una lunghezza pari al numero di barre. E il rifiuto della sua inizializzazione in MT5 porta alla visualizzazione di spazzatura sullo schermo. Si scopre che l'inizializzazione esplicita è obbligatoria. E non è chiaro perché viene semplicemente trasferito dal nucleo (come era in MT4) al programmatore MQL. Non ho visto alcun argomento reale che in qualche modo si possa accelerare senza inizializzazione e ottenere comunque la visualizzazione della spazzatura.

Non sto dicendo nulla su un array dinamico personalizzato - c'è davvero una regola: chi lo ha allocato, è responsabile della corretta pulizia. ArrayInitialize è utile in molti casi. Non è una questione di velocità, ma di correttezza del programma. Priorità: veloce e/o corretta. Di solito, alcuni controlli per la correttezza e la preparazione dei dati richiedono tempo aggiuntivo (anche se minimo), ma non se ne può fare a meno - i miracoli non accadono mai.

 
Stanislav Korotky:

Non sto dicendo nulla su un array dinamico personalizzato - lì vale davvero la regola: chi lo ha allocato è responsabile della sua corretta pulizia.

Non insultare gli array.

#property strict

void OnStart()
{
  uchar Array[];
  
  const int Size = ArrayResize(Array, 10000);
  
  bool Res = false;
  
  for (int i = 0; (i < Size) && (!Res); i++)
    Res = Array[i];
    
  Print(Res);
}

In MT4 restituirà sempre falso, perché senza spazzatura - tutti zeri. In MT5 è vero.

Pertanto, lo stesso codice nel tester MT4 mostrerà sempre risultati identici da un'esecuzione all'altra. In un tester MT5 non lo farà.

 
fxsaber:

In MT4 restituirà sempre falso, perché senza spazzatura è tutto a zero. In MT5 è vero.

È un test che MT4 riempie l'array con degli zeri? Poi dobbiamo tenere a mente che se ArrayResize usa un terzo parametro con riserva, allora le successive riallocazioni all'interno della riserva non inizializzeranno nulla. Ci sarà della spazzatura. Raccomando di fare un'inizializzazione esplicita, in modo da non essere accidentalmente sorpresi in seguito, come nell'esempio di ottimizzazione che ha stimolato questa discussione.

Per coloro che si preoccupano della frenata a causa dell'inizializzazione, oserei dire che di solito ci sono molti altri luoghi e tecniche in cui l'efficienza può essere migliorata in misura molto maggiore.

 
Stanislav Korotky:

È un test per MT4 che riempie l'array di zeri? Poi dovete tenere a mente che se ArrayResize usa un terzo parametro con riserva, allora le successive riallocazioni all'interno della riserva non inizializzeranno nulla. Ci sarà della spazzatura.

Non ci saranno rifiuti.

Raccomando di fare un'inizializzazione esplicita in modo da non essere accidentalmente sorpresi in seguito, come nell'esempio di ottimizzazione che ha stimolato questa discussione.

Questo non salverà

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

Bug, bug, domande

fxsaber, 2017.09.12 11:18

Anche se ho scritto perfettamente (senza fare errori - cosa che non faccio), è normale prendere la libreria di qualcun altro (a volte senza codice sorgente - nel Marketplace) e usarla, sperando che sia scritta con competenza. E non c'è nessuna assicurazione che dopo questo si possa incorrere in risultati diversi nel tester. E trovare la vera causa sarà MOLTO difficile. E ripararlo è a volte impossibile.

L'obiettivo è che da esecuzione a esecuzione il risultato sia riproducibile - identico, anche con un errore.

 
fxsaber:

Non ci saranno rifiuti.



Dobbiamo correggere la documentazione allora?

Inizializzare un array con l'espressioneArrayInitialize(array, init_val) non significa inizializzare gli elementi della riserva allocata per questo array con lo stesso valore. Quando lafunzione ArrayResize() aumenta successivamente la dimensione dell'array all'interno della riserva corrente, gli elementi i cui valori non sono definiti e molto spesso non sono uguali ainit_val vengono aggiunti alla fine dell'array.

 
Stanislav Korotky:

Dobbiamo correggere la documentazione allora?

Inizializzare un array con l'espressioneArrayInitialize(array, init_val) non significa che gli elementi della riserva, allocati per questo array, siano inizializzati con lo stesso valore. QuandoArrayResize() aumenta successivamente la dimensione dell'array all'interno della riserva corrente, vengono aggiunti alla fine dell'array gli elementi i cui valori non sono definiti e, molto spesso, non sono uguali ainit_val.

Non si fa, perché semplicemente non c'è una cosa del genere nella documentazione di MT4.


È orribile pensare che qualche libreria matematica (Include\Math -7Mb di codice sorgente) non abbia inizializzato in uno/due punti! E come eliminare questo errore, che dà diverse corse singole nel tester MT5, e lo stesso in MT4?

 
Stanislav Korotky:

Devo essere indietro con i tempi. Mi sembra che il buffer dell'indicatore abbia sempre una lunghezza uguale al numero di barre. E il rifiuto della sua inizializzazione in MT5 porta alla visualizzazione di spazzatura sullo schermo. Si scopre che l'inizializzazione esplicita è obbligatoria. E non è chiaro perché viene semplicemente trasferito dal nucleo (come era in MT4) al programmatore MQL. Non ho visto alcuna argomentazione reale che in qualche modo sia possibile accelerare senza inizializzazione e ottenere comunque la visualizzazione della spazzatura.

Non sto dicendo nulla su un array dinamico personalizzato - c'è davvero una regola: chi lo ha allocato, è responsabile della corretta pulizia. ArrayInitialize è utile in molti casi. Non è una questione di velocità, ma di correttezza del programma. Priorità: veloce e/o corretta. Di solito, alcuni controlli per la correttezza e la preparazione dei dati richiedono tempo aggiuntivo (anche se minimo), ma non se ne può fare a meno - i miracoli accadono.

Non hai prestato attenzione alla frase

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

Bug, bug, domande

Alexey Viktorov, 2017.09.12 10:50

Prendiamo ad esempio l'array del buffer dell'indicatore: quando si inizializza l'indicatore, il buffer ha lunghezza zero. Cosa c'è da inizializzare con degli zeri? Quando viene aggiunto un altro indice è forzato ad essere azzerato e poi riempito con qualche valore? A cosa serve questo azzeramento o riempimento con EMPTY_VALUE? E se c'è bisogno di assegnare PLOT_EMPTY_VALUE e non 0 o EMPTY_VALUE o di forzare uno, ma abbiamo bisogno di un altro... In qualunque modo la si tagli, si finisce per perdere il proprio tempo...

E un array personalizzato... L'array è dichiarato per qualche dato diverso da zero e EMPTY_VALUE. Quindi perché dovrebbe essere forzatamente inizializzato con qualcosa?

Così si scopre che influisce sulle prestazioni nella maggior parte dei casi.



E non ha senso farlo in OnCalculate. Perché avremmo bisogno di inizializzare l'array con qualcosa e poi riempirlo con alcuni valori della formula? Quando si aggiunge una barra, rispettivamente una cella dell'array, che senso ha riempirla con qualcosa e poi immediatamente con un valore della formula o un valore vuoto?

 
Alexey Viktorov:

E già in OnCalculate non ha senso. Perché avremmo bisogno di inizializzare l'array con qualcosa e poi riempirlo immediatamente con alcuni valori della formula? Quando si aggiunge una barra, e rispettivamente una cella dell'array, che senso ha riempirla con qualcosa e poi immediatamente con un valore della formula o un valore vuoto?

Solo i nuovi elementi della matrice sono inizializzati. E il punto è sempre lo stesso: risultati identici da un'esecuzione all'altra, anche se c'è un errore nel codice (spesso non il vostro). Ho dato un esempio con la libreria matematica sopra.

La spazzatura è malvagia.

 
fxsaber:

Non fatelo, perché semplicemente non c'è nella documentazione di MT4.

Da dove l'ho preso allora? Vai qui.

ArrayInitialize - Операции с массивами - Справочник MQL4
ArrayInitialize - Операции с массивами - Справочник MQL4
  • docs.mql4.com
ArrayInitialize - Операции с массивами - Справочник MQL4
 
Stanislav Korotky:

Da dove l'ho preso allora? Vai qui.

Quindi non si tratta di ArrayResize, ma di ArrayInitialize. ArrayResize garantisce gli zeri in MT4.


Per interesse, ho cercato in tutte le mie fonti per MT5 quanto spesso uso ArrayInitialize. Solo alcune volte. Sembra essere meno di una percentuale di tutti gli array dinamici. E dove l'ho usato, ho dovuto usare nulls di proposito, quindi ho usato una notazione più corta invece di for.