Discussione sull’articolo "Scambio di Dati tra Indicatori: È Facile"

 

Il nuovo articolo Scambio di Dati tra Indicatori: È Facile è stato pubblicato:

Vogliamo creare un tale ambiente che fornisca l'accesso ai dati degli indicatori allegati a un grafico e che abbia le seguenti proprietà: assenza di copia dei dati; modifica minima del codice dei metodi disponibili, se è necessario utilizzarli; È preferibile il codice MQL (ovviamente dobbiamo usare DLL, ma useremo solo una dozzina di stringhe di codice C++). L'articolo descrive un metodo semplice per sviluppare un ambiente di programma per il terminale MetaTrader, che fornirebbe i mezzi per accedere ai buffer degli indicatori da altri programmi MQL.

Come possiamo notare, non è difficile. Ottieni l'elenco dei descrittori da una sottostringa e leggi i valori del buffer dell'indicatore usando le nostre funzioni. E infine, scriviamo un po' di spazzatura (nel nostro esempio, scriviamo i valori che corrispondono all'indice dell'elemento dell'array).

Ora eseguendo l'indicatore di test (il nostro ATR target dovrebbe ancora essere allegato al grafico). Come vediamo in Fig.3, i valori di ATR sono nella sottofinestra inferiore (nel nostro indicatore di test), vediamo la linea retta al suo posto - infatti, è riempita con i valori corrispondenti agli indici dell'array.

 

Autore: Alexey Subbotin

 
C'è un avvertimento molto serio per coloro che utilizzano chiamate frequenti di funzioni DLL come Get/Set.


Per motivi di sicurezza del sistema, ogni chiamata a DLL passa attraverso uno speciale stripper, che rallenta l'esecuzione. La chiamata di funzione DLL non è una banale chiamata XXXX, ma un complesso wrapping con mascheramento degli indirizzi, controllo dello stack e crash all'interno della DLL. MQL5 fa in modo che se una funzione all'interno della DLL incasina lo stack o si blocca, l'esecuzione dello script si interrompe senza bloccare il terminale stesso.

Un consiglio generale sull'uso delle funzioni DLL: cercate di fare chiamate rare con una grande quantità di lavoro all'interno, piuttosto che decine di migliaia di chiamate al secondo con risultati piccoli.

 

Mi chiedo. Perché non andare oltre?

Come ha sottolineato Renat, chiamare funzioni economiche da una dll è costoso.

Quindi perché non copiare i dati direttamente nell'array previsto a questo scopo?

 
TheXpert:

Mi chiedo. Perché non andare oltre?

A chi è rivolta la domanda: all'autore o agli sviluppatori?

Se agli sviluppatori, cosa suggerite esattamente?

 

C'è un errore nella funzione StringExplode? Nella sua forma attuale, non copia l'ultimo componente della stringa se non c'è un delimitatore dopo di esso (cioè alla fine della stringa). IMHO, la fine della stringa dovrebbe essere presa anche se non c'è un delimitatore alla fine. Esempio: si inserisce la stringa"EURUSD,EURJPY" con il delimitatore "," e la funzione ora seleziona solo EURUSD.

Ecco la versione corretta della funzione, per comodità ho riportato il numero di elementi:

int StringExplode(string s, string separator, string &result[])
{
  int i, pos;
  ArrayResize(result, 0);
   
  for(i = 0; ; i++)
  {
    ArrayResize(result, ArraySize(result) + 1);
    pos = StringFind(s, separator);
    if(pos >= 0)
    {
      result[i] = StringSubstr(s, 0, pos);
      s = StringSubstr(s, pos + StringLen(separator));
    }
    else
    {
      result[i] = s;
      i++;
      break;
    }
  }
  
  return(i);
}
 
Renat:
C'è un avvertimento molto serio per chi utilizza chiamate frequenti di funzioni DLL come Get/Set.


Per la sicurezza del sistema, ogni chiamata a DLL passa attraverso uno speciale stripper, che ne rallenta l'esecuzione. La chiamata di funzione DLL non è una banale chiamata XXXX, ma un complesso wrapping con mascheramento degli indirizzi, controllo dello stack e crash all'interno della DLL. MQL5 fa in modo che se una funzione all'interno della DLL incasina lo stack o si blocca, l'esecuzione dello script si interrompe senza bloccare il terminale stesso.

Un consiglio generale sull'uso delle funzioni DLL: cercate di fare chiamate rare con una grande quantità di lavoro all'interno, piuttosto che decine di migliaia di chiamate al secondo con il trasferimento di piccoli risultati.

A proposito, un'altra osservazione sulle chiamate multiple alla DLL: durante i test ho notato che a ogni chiamata si verificano perdite di memoria di diversi byte

marketeer:

Non c'è nessun errore nella funzione StringExplode? Nella sua forma attuale non copia l'ultimo componente della stringa se non c'è un delimitatore dopo di esso (cioè alla fine della stringa). IMHO, la fine della stringa dovrebbe essere presa anche se non c'è un delimitatore alla fine. Esempio: si inserisce la stringa"EURUSD,EURJPY" con il delimitatore "," e la funzione ora seleziona solo EURUSD.

Ecco la versione corretta della funzione, per comodità ho riportato il numero di elementi:


Grazie, non ci avevo fatto caso. Si vede perché l'ultimo elemento del descrittore è un numero casuale, che non ha alcun significato.

---------

Grazie! Implementerò tutti i suggerimenti di miglioramento per quanto possibile. L'idea in sé è buona, vorrei che non si bloccasse.

 
Renat:

A chi è rivolta la domanda: all'autore o agli sviluppatori?

Se agli sviluppatori, cosa suggerite esattamente?

Autore. Si può passare la dimensione dell'array insieme ad esso, quindi si può organizzare la copia una tantum dell'array direttamente dalla memoria alla memoria - molto economico e aggira i problemi di MQL4 con i riferimenti elemento per elemento. Ora ho molte cose da fare, altrimenti avrei scritto un esempio.... Spero che abbiate capito il succo del discorso.

In anticipo... -- Se si utilizzano i blocchi e si implementa correttamente il trasferimento, questo approccio dovrebbe essere sicuro.

 

Quanto è complicato!...

Con l'aiuto di Ilnur un anno fa ho scritto una libreria in MQL4 per lavorare con la memoria. È possibile allocare memoria, spostare puntatori, scrivere e leggere, trasferire il nome di un'area di memoria a qualsiasi altro programma.

Tutto si basa sulla mappatura. È molto più semplice di quella proposta.

 
Zhunko:

Quanto è complicato!...

Con l'aiuto di Ilnur un anno fa ho scritto una libreria in MQL4 per lavorare con la memoria. È possibile allocare memoria, spostare puntatori, scrivere e leggere, trasferire il nome di un'area di memoria a qualsiasi altro programma.

Tutto si basa sulla mappatura. È molto più semplice di quello proposto.

Il punto è che nell'approccio proposto non è necessario allocare la memoria e spostare i puntatori. Le letture e le scritture sono organizzate direttamente nel buffer. È molto più semplice della mappatura.
 
Renat:
C'è un avvertimento molto serio per chi utilizza chiamate frequenti di funzioni DLL come Get/Set.


Per motivi di sicurezza del sistema, ogni chiamata a DLL passa attraverso uno speciale stripper, che ne rallenta l'esecuzione. La chiamata di funzione DLL non è una banale chiamata XXXX, ma un complesso wrapping con mascheramento degli indirizzi, controllo dello stack e crash all'interno della DLL. MQL5 fa in modo che se una funzione all'interno della DLL incasina lo stack o si blocca, l'esecuzione dello script si interrompe senza bloccare il terminale stesso.

Un consiglio generale sull'uso delle funzioni DLL: cercate di fare chiamate rare con una grande quantità di lavoro all'interno, non decine di migliaia di chiamate al secondo con risultati piccoli.

Correzione: dalla build 240 sono stati eliminati i ritardi nelle chiamate alle DLL. Ora vengono eseguite praticamente senza ritardi come in nativo.
 

Grazie mille all'autore, non si tratta di una piccola biblioteca, con un uso corretto e

e "incroci che non contraddicono le leggi della genetica" si possono ottenere buoni risultati.

Io, ad esempio, ho finalmente "tirato" i dati dai grafici offline, in modalità online))). Piattaforma MT4.


Un cucchiaio di catrame)))

Più di una volta si sono verificate situazioni in cui nell'elenco delle variabili globali

nell'elenco delle variabili globali erano "vecchie" per qualche motivo non cancellate.

Non riesco ancora a capirne la ragione.