Direzione di Indicizzazione negli Array, Buffers e TimeSeries

L'indicizzazione predefinita di tutti gli array e buffer indicatore è da sinistra a destra. The index of the first element is always equal to zero. Così, il primo elemento di un buffer di array o indicatore con indice 0 è predefinito sulla posizione estrema sinistra, mentre l'ultimo elemento è sulla posizione estrema destra.

Un buffer indicatore è un array dinamico di tipo doppio, la cui grandezza è gestita dai terminali client, in modo che corrisponda sempre al numero di barre su cui viene calcolato l'indicatore. Un solito array dinamico di tipo double viene assegnato come un buffer utilizzando l'indicatore funzione SetIndexBuffer(). I buffers indicatore non richiedono l'impostazione delle loro grandezze con la funzione ArrayResize() - questo sarà fatto dal sistema di esecuzione del terminale.

Timeseries sono array con indicizzazione inversa, cioè il primo elemento di un timeseries è nella posizione estrema destra, e l'ultimo elemento è nella posizione di estrema sinistra. Timeseries vengno utilizzate per la memorizzazione di dati sui prezzi storici e contenere le informazioni di tempo, possiamo dire che i dati più recenti vengono inseriti nella posizione estrema destra delle timeseries, mentre i dati più vecchi sono in posizione di estrema sinistra.

Quindi l'elemento timeseries con indice 0 contiene le informazioni sulle ultime quotazioni di un simbolo. Se una timeseries contiene dati su un timeframe giornaliero, i dati del giorno corrente ancora incompleto si trovano sulla posizione zero, e la posizione di indice 1 contiene dati di ieri.

Modifica della Direzione di Indicizzazione

La Funzione ArraySetAsSeries() permette di cambiare il metodo di accesso agli elementi di un array dinamico, l'ordine fisico di memorizzazione dei dati nella memoria del computer non viene cambiato da questo. Questa funzione cambia semplicemente il metodo di indirizzazione degli elementi dell'array, in modo che quando si copia un array a un'altro utilizzando la funzione ArrayCopy(), il contenuto dell' array destinatario non dipende dalla direzione di indicizzazione nell' array di origine.

La direzione di indicizzazione non può essere modificata per array staticamente distribuiti. Anche se un array viene passato come parametro ad una funzione, il tentativo di cambiare la direzione di indicizzazione all'interno di questa funzione non porterà alcun effetto.

Per i buffer indicatore, come per gli array solitamente, la direzione di indicizzazione può anche essere impostato come invertita (come nelle timeseries), cioè il riferimento alla posizione zero nel buffer indicatore significherà riferimento all'ultimo valore sul buffer indicatore corrispondente e questo corrisponderà al valore dell'indicatore sull'ultima barra. Tuttavia, la posizione fisica delle barre indicatori non verrà modificata.

Ricezione di Dati Prezzi negli Indicatori

Ogni indicatore personalizzato deve necessariamente contenere la funzione OnCalculate(), a cui dati sui prezzi richiesti per il calcolo dei valori di buffer indicatori vengono passati. La direzione di indicizzazione in questi array passati può essere individuata con la funzione ArrayGetAsSeries().

Gli Array passati alla funzione riflettono dati sui prezzi, vale a dire questi array hanno il segno di una timeseries e la funzione ArrayIsSeries() restituirà true quando si controllano questi array. Tuttavia, qualsiasi direzione indicizzazione dovrebbe essere controllata solo per la funzione ArrayGetAsSeries().

Per non dipendere da valori predefiniti, ArraySetAsSeries() deve essere incondizionatamente chiamato per gli array che si stanno per lavorare, ed impostare la direzione desiderata.

Ricezione di Dati Prezzi e Valori degli Indicatori

La direzione di indicizzazione di default di tutti gli array negli Expert Advisor, indicatori e script è da sinistra a destra. Se necessario, in qualsiasi programma mql5 è possibile richiedere valori timeseries su qualsiasi simbolo e timeframe, così come i valori degli indicatori calcolati su qualsiasi simbolo e timeframe.

Utilizzare le funzioni Copy...() per questi scopi:

  • CopyBuffer - copia i valori di un buffer indicatore in un array di tipo double;
  • CopyRates - copia lo storico prezzi in un array di strutture MqlRates;
  • CopyTime - copia i valori Time in un array di tipo datetime;
  • CopyOpen - copia i valori Open in un array di tipo double;
  • CopyHigh - copia i valori High in un array di tipo double;
  • CopyLow - copia i valori Low in un array di tipo double;
  • CopyClose - copia i valori Close in un array di tipo double;
  • CopyTickVolume - copia i volumi tick volumi in un array di tipo long;
  • CopyRealVolume - copia i volumi equity in un array di tipo long;
  • CopySpread - copia la cronistoria dello spread in un array di tipo int;

 

Tutte queste funzioni funzionano in modo simile. Prendiamo in considerazione i dati ottenendo meccanismo sull'esempio di CopyBuffer(). È implicato che la direzione di indicizzazione dei dati richiesti è quella delle timeseries, e la posizione di indice 0 (zero) memorizza i dati della barra corrente ancora incompleta. Al fine di ottenere l'accesso a questi dati abbiamo bisogno di copiare il volume necessario di dati nell' array ricevente, ad esempio in un array buffer.

copyBuffer

Quando si copia è necessario specificare la posizione di partenza nell' array di origine, a partire dal quale i dati saranno copiati nell' array destinatario. In caso di successo, il numero specificato di elementi verrà copiato nell' array destinatario dall' array di origine (dal buffer indicatore in questo caso). Indipendentemente dal valore di indicizzazione nell'array destinatario, la copia viene sempre eseguita come è mostrato nella figura precedente.

Se si prevede che i dati sui prezzi saranno trattati in un ciclo con un gran numero di iterazioni, si consiglia di controllare il fatto di cessazione forzata del programma usando la funzione IsStopped():

int copied=CopyBuffer(ma_handle,// Handle indicatore
                      0,        // L'indice del buffer dell'indicatore
                      0,        // Posizione iniziale per la copia
                      number,   // Numero di valori da copiare 
                      Buffer    // L'array che riceve i valori
                      );
if(copied<0) return;
int k=0;
while(k<copied && !IsStopped())
  {
   //--- Prendi il valore per l'indice k
   double value=Buffer[k];
   // ... 
   // lavora con il valore
   k++;
  }

Esempio:

input int per=10; // periodo dell'esponente
int ma_handle;    // Handle indicatore
//+--------------------------------------------------------------------------------+
//| Funzione di inizializzazione dell' Expert                                      |
//+--------------------------------------------------------------------------------+
int OnInit()
  {
//---
   ma_handle=iMA(_Symbol,0,per,0,MODE_EMA,PRICE_CLOSE);
//---
   return(INIT_SUCCEEDED);
  }
//+--------------------------------------------------------------------------------+
//| Funzione tick dell'Expert                                                      |
//+--------------------------------------------------------------------------------+
void OnTick()
  {
//---
   double ema[10];
   int copied=CopyBuffer(ma_handle,// Handle indicatore
                         0,        // indice del buffer indicatore
                         0,        // posizione di partenza da cui copiare
                         10,       // numero di valori per la copia
                         10,       // array ricevente valori
                         );
   if(copied<0) return;
// .... ulteriore codice
  }

Vedi anche

Organizzazione di Accesso ai Dati