MT4 iMAOnArray e iBandsOnArray effetto del numero di elementi sui calcoli - pagina 2

 
Sergey Efimenko:
Cosa vuoi dire, cosa mi aspetto? Ho scritto sopra, che ho bisogno di 300 ultimi valori attuali (attuali), e non 300 primi (iniziali), inoltre, che accedo a un array all'offset 299-0, ma ottengo dati all'offset da "fine array" a "fine array - 300" valori (nel mio caso da 4999 a 4700), cioè, all'offset 299 è un valore, che dovrebbe essere all'offset 4999 e analogamente all'offset 0 è un valore, che dovrebbe essere all'offset 4700. La domanda è: qual è lo scopo di calcolare i vecchi valori, quando i valori attuali non vengono calcolati?

Se fosse chiaro da quello che hai scritto, non ci sarebbero domande.

double  iMAOnArray(
   double       array[],          // массив               // С этим понятно...
   int          total,            // количество элементов // Это у тебя 300
   int          ma_period,        // период               // Это ???
   int          ma_shift,         // сдвиг средней        // понятно
   int          ma_method,        // метод усреднения     // понятно
   int          shift             // сдвиг                // А здесь чему равна i???
   );

Ti è stato chiesto di mostrare un esempio di codice, ma hai mostrato solo un frammento di un esempio. Sul resto si può solo intuire che è tutto in circolo. A quale valore di i volete ottenere gli ultimi valori attuali? A i = 4700 o dove?

 
Alexey Viktorov:

Se fosse chiaro da quello che hai scritto, allora non ci sarebbero domande.

Ti è stato chiesto di mostrare un esempio di codice e hai mostrato solo un pezzo di esempio. Sul resto si può solo intuire che è tutto in loop. A quale valore di i volete ottenere gli ultimi valori attuali? A i = 4700 o dove?

Se avete usato queste funzioni con la limitazione della lunghezza dell'array di calcolo nella pratica, capirete cosa intendo, altrimenti che senso ha il ragionamento teorico...? E cosa c'è di poco chiaro nel mio pezzo di codice? Ho citato sezioni assolutamente identiche con la sola differenza che nel primo caso non uso la limitazione della lunghezza per il calcolo dell'array. In questo caso non importa affatto quale periodo di calcolo, la media del turno o il metodo della media, perché sono gli stessi in entrambi i casi? Il valore di shift, come ho scritto sopra, è similmente usato esattamente allo stesso modo. Sostituite "i" con la vostra variabile shift nel ciclo, sostituite la funzione GetValue(i) con almeno Open[i], rendete i tre array menzionati 3 buffer di visualizzazione dell'indicatore e vedete come funzionano il primo e il secondo. Tuttavia, ecco un esempio del codice completo della variante semplice dell'indicatore in due varianti per una migliore comprensione del problema:

//questo funziona bene:
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[],BufferMA[],BufferBMA[]; bool firstrun=true;
int init() { firstrun=true; SetIndexBuffer(0,Buffer); SetIndexBuffer(1,BufferMA); SetIndexBuffer(2,BufferBMA); return(0); }
int start() { int i,limit; int counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; limit=Bars-counted_bars-1;
   if(firstrun) {ArrayInitialize(Buffer,Open[Bars-1]); ArrayInitialize(BufferMA,Open[Bars-1]); ArrayInitialize(BufferBMA,Open[Bars-1]); firstrun=false; }
   for(i=limit; i>=0; i--) { Buffer[i]=Open[i]; BufferMA[i]=iMAOnArray(Buffer,0,12,0,0,i); BufferBMA[i]=iBandsOnArray(Buffer,0,12,2,0,MODE_MAIN,i); }
return(0); }

//non funziona correttamente:

#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[],BufferMA[],BufferBMA[]; bool firstrun=true;
int init() { firstrun=true; SetIndexBuffer(0,Buffer); SetIndexBuffer(1,BufferMA); SetIndexBuffer(2,BufferBMA); return(0); }
int start() { int i,limit; int counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; limit=Bars-counted_bars-1;
   if(firstrun) {ArrayInitialize(Buffer,Open[Bars-1]); ArrayInitialize(BufferMA,Open[Bars-1]); ArrayInitialize(BufferBMA,Open[Bars-1]); firstrun=false; }
   for(i=limit; i>=0; i--) { Buffer[i]=Open[i]; BufferMA[i]=iMAOnArray(Buffer,300,12,0,0,i); BufferBMA[i]=iBandsOnArray(Buffer,300,12,2,0,MODE_MAIN,i);  }
return(0); }

Dopo aver disegnato gli indicatori sul grafico, andate all'inizio (a sinistra) del grafico e guardate 1 indicatore da 12 barre in poi, è l'inizio del riempimento "non vuoto" di 2 e 3 dell'array, ricordate approssimativamente i primi valori che differiscono da 0, poi spostate il grafico sulle quotazioni attuali e guardate i valori a partire da 300 barre, quindi i valori di 2 (in basso) indicatore saranno uguali a quelli che avete visto all'inizio del grafico di 1 indicatore, mentre in idea, i valori dovrebbero corrispondere all'attuale. Spero di essermi spiegato chiaramente. Inoltre, se metti i grafici su un grafico online, il primo funzionerà bene e il secondo si "appenderà al suo".

 
Sergey Efimenko:


Non solo il codice non ha stile, ma si inserisce il codice come testo semplice. Si prega di inserire il codice correttamente.
 

Presenterò il vostro codice in una forma più leggibile e in una nuova notazione (davvero, per quanto tempo ancora possiamo usare questo anacronistico int start() negli indicatori????):

Indicatore 1:

//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[];
double BufferMA[];
double BufferBMA[];
bool firstrun=true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   firstrun=true;
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,BufferMA,INDICATOR_DATA);
   SetIndexBuffer(2,BufferBMA,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int i,limit;
   limit=rates_total-prev_calculated-1;
   if(prev_calculated==0)
     {
      ArrayInitialize(Buffer,open[rates_total-1]);
      ArrayInitialize(BufferMA,open[rates_total-1]);
      ArrayInitialize(BufferBMA,open[rates_total-1]);
     }
   for(i=limit; i>=0; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]=iMAOnArray(Buffer,0,12,0,MODE_SMA,i);
      BufferBMA[i]=iBandsOnArray(Buffer,0,12,2,0,MODE_MAIN,i);
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Indicatore 2:

//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[];
double BufferMA[];
double BufferBMA[];
bool firstrun=true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   firstrun=true;
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,BufferMA,INDICATOR_DATA);
   SetIndexBuffer(2,BufferBMA,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int i,limit;
   limit=rates_total-prev_calculated-1;
   if(prev_calculated==0)
     {
      ArrayInitialize(Buffer,open[rates_total-1]);
      ArrayInitialize(BufferMA,open[rates_total-1]);
      ArrayInitialize(BufferBMA,open[rates_total-1]);
     }
   for(i=limit; i>=0; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]=iMAOnArray(Buffer,300,12,0,MODE_SMA,i);
      BufferBMA[i]=iBandsOnArray(Buffer,300,12,2,0,MODE_MAIN,i);
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

E il risultato dell'esecuzione:

Risultato

о

File:
Test.mq4  3 kb
Test300.mq4  3 kb
 
Sergey Efimenko:

Se avete usato queste funzioni

Se non l'avessi fatto, non starei facendo domande per suggerire la giusta soluzione.

Che senso ha prendere 300 barre se si deve calcolare un periodo di 12? Anche se vi serve "perché", dovreste capire quali sarebbero i 12 elementi nel calcolo della media. E il suggerimento sulla direzione dell'indicizzazione dell'array era molto corretto.

Per la comprensione fate esperimenti con il calcolo manuale su carta o su una calcolatrice, o in Excel.

 

Quando guardo le risposte mi rendo conto che sto solo perdendo il mio tempo qui, cercando di mostrare l'essenza del problema, e ottenendo la "bellezza" del codice in risposta (grazie naturalmente, ma il codice proposto è stato scritto in due minuti solo per mostrare l'essenza del problema e non richiede alcuna leggibilità o altre conversioni)...

E soprattutto felice della risposta prima del mio post... Quale calcolatrice, quali calcoli manuali, quale indicizzazione? Cari utenti, vi prego di capire l'essenza della situazione per non perdere non solo il vostro tempo ma anche quello di qualcun altro. Si prega di rileggere attentamente i miei post, ma se è difficile, risponderò brevemente: la direzione dell'indicizzazione dell'array in entrambi i casi è corretta, la dimensione dei calcoli necessari e altri parametri modificabili, come è mostrato nel codice primario è impostata con variabili esterne, la variante di creare una propria funzione è stata discussa sopra (ed è effettivamente l'unica soluzione corretta), ma voglio ripetere, voglio ottenerla da MT4 integrata.

In generale grazie a tutti, riassumo: o servicedesk o analoghi propri delle funzioni.

 

E sono scoraggiato dalla risposta prima del mio post...

Se sei così testardo, => servicedesk, e loro rispondono a queste domande solo per noia, e raramente si annoiano.

Lasciami provare di nuovo...

iMAOnArray() prende, nel tuo caso, 300 barre e calcola il valore medio delle ultime 12 barre su trecento. Per calcolare la media delle prime 12 barre, dovresti invertire l'indicizzazione dell'array, ArraySetAsSeries(BufferMA, false); o prendere solo 12 barre.

BufferMA[i]=iMAOnArray(Buffer,12,12,0,MODE_SMA,i);

Così si scopre che invece di cercare di capire come funziona e come usarlo, avete semplicemente affermato che non funziona o funziona in modo errato. E non è giusto secondo voi.

Cosa c'è dopo la bellezza del codice: Pensi che sia interessante che qualcuno si rompa gli occhi leggendo il tuo codice quando è tutto scritto in una sola riga? Sbagliato. Non l'ho letto personalmente. Grazie al piccolo batterista per la sua pazienza più volte al giorno per dirigere tutti... al posto sbagliato.

 

Volevo rispondere molto "in dettaglio", ma poi, dopo aver riletto di nuovo i post, ho cancellato la mia risposta, e alla fine ho capito che stavo solo perdendo tempo qui, spiegando la stessa cosa più volte con parole diverse...

PS Tutti i ringraziamenti e davvero grazie "Barabashke" (Vladimir), ha fatto bene, ma tutta questa situazione non valeva il suo lavoro, sarò ancora più grato se non sarà difficile da fare, uno screenshot in una chiave precedente, aggiungendo una terza opzione e mostrando cosa accadrebbe se si segue il consiglio di cambiare la direzione di indicizzazione. Per porre fine alla questione di come funziona la funzione.

 
Sergey Efimenko:

Volevo rispondere molto "in dettaglio", ma poi, dopo aver riletto di nuovo i post, ho cancellato la mia risposta, e alla fine ho capito che stavo solo perdendo tempo qui, spiegando la stessa cosa più volte con parole diverse...

PS Tutti i ringraziamenti e davvero grazie "Barabashke" (Vladimir), ha fatto bene, ma tutta questa situazione non valeva il suo lavoro, sarò ancora più grato se non sarà difficile da fare, uno screenshot in una chiave precedente, aggiungendo una terza opzione e mostrando cosa accadrebbe se si segue il consiglio di cambiare la direzione di indicizzazione. Per porre fine alla questione di come funziona la funzione.

Opzione 3:

//+------------------------------------------------------------------+
//|                                         Test300AsSeriesFalse.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[];
double BufferMA[];
double BufferBMA[];
bool firstrun=true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   firstrun=true;
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,BufferMA,INDICATOR_DATA);
   SetIndexBuffer(2,BufferBMA,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   ArraySetAsSeries(open,false);
//---
   int i,limit;
   limit=rates_total-prev_calculated-1;
   if(prev_calculated==0)
     {
      ArrayInitialize(Buffer,open[rates_total-1]);
      ArrayInitialize(BufferMA,open[rates_total-1]);
      ArrayInitialize(BufferBMA,open[rates_total-1]);
     }
   for(i=limit; i>=0; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]=iMAOnArray(Buffer,300,12,0,MODE_SMA,i);
      BufferBMA[i]=iBandsOnArray(Buffer,300,12,2,0,MODE_MAIN,i);
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

E il risultato complessivo:

Opzioni 1, 2 e 3

 

No, Vladimir. È un po' sbagliato.

In questo caso, dovreste applicare ArraySetAsSeries(array, false); a un array di trecento elementi tra i quali è considerato iMAOnArray(). Ma è meglio usare CopyOpen() invece del ciclo di riempimento dell'array.

Da quanto ho capito, in questa variante sarà meglio

   for(i=limit; i>=0; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]=iMAOnArray(Buffer,12,12,0,MODE_SMA,i);
      BufferBMA[i]=iBandsOnArray(Buffer,12,12,2,0,MODE_MAIN,i);
     }