Discussione sull’articolo "Applicazione di un Indicatore ad un Altro"

 

Il nuovo articolo Applicazione di un Indicatore ad un Altro è stato pubblicato:

Quando si scrive un indicatore che utilizza la forma abbreviata della chiamata di funzione OnCalculate(), potresti non considerare il fatto che un indicatore può essere calcolato non solo dai dati di prezzo, ma anche dai dati di un altro indicatore (indipendentemente dal fatto che sia integrato o uno personalizzato). Vuoi migliorare un indicatore per la sua corretta applicazione ai dati dell'altro indicatore? In questo articolo, esamineremo tutti i passaggi necessari per tale modifica.

Autore: MetaQuotes

 

Grazie per un altro buon articolo. Tradizionalmente, gli articoli di MQL Community sono diventati per me un modo per ottenere un'istruzione post-secondaria (vale a dire la guida dell'editor MQL incorporata).

Sul punto, ho notato un piccolo difetto nel codice. Secondo l'idea dell'autore

//--- flag per l'emissione una tantum dei valori di price[]

variabile

   bool printed=false;

dovrebbe essere spostata al di fuori della funzione OnCalculate(), altrimenti la stampa dell'array avverrà a ogni evento.

C'è anche un refuso qui

Правило передачи PLOT_DRAW_BEGIN в параметр begin: Значение входного параметра begin в OnCalculate(), при расчетах пользовательского индикатора A на данных другого (базового) индикатора B, всегда равно значению свойства PLOT_DRAW_BEGIN  нулевого графического построения базового индикатора B.

Quindi, se abbiamo creato un indicatore RSI (indicatore A) con un periodo di 14 e poi abbiamo costruito il nostro indicatore personalizzato True Strength Index (indicatore B) sui dati dell'indicatore RSI(14), allora:

A giudicare dalla regola e dalla logica, l'indicatore A è un TSI personalizzato e l'indicatore B (di base) è un RSI.

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
Основы языка / Функции / Функции обработки событий - Документация по MQL5
 

Questo articolo contiene le conoscenze dettagliate.

Grazie.

 

Ciao,

Questo articolo è davvero interessante e apre nuove opportunità per la gestione degli indicatori.

Poiché sono un principiante in MQL5, ho cercato di implementare la possibilità di applicare un indicatore ad un altro. Ho scritto un piccolo codice che duplica soltanto

una media mobile adattativa sperando di poterla utilizzare su qualsiasi indicatore del grafico.

Purtroppo, nella lista dei parametri che appare quando si lancia l'indicatore non ho il caso "apply to : previuos indicator's data".

Come dovrebbe essere organizzato il codice per avere la possibilità di applicarlo ad un altro indicatore?

Ecco il mio codice:

#property indicator_separate_window
#property indicator_minimum             1.3
#property indicator_maximum             1.35
//#proprietà indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   1
//--- tracciare il dMA
#property indicator_label1  "dAMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- parametri di ingresso
input int      AMAPeriod=9;
input int      FastEMA=2;
input int      SlowEMA=20;
//--- buffer di indicatori
double         AMABuffer[];
double         dAMABuffer[];

int            h_dAMA;
int            h_AMA;
//+------------------------------------------------------------------+
//| Funzione di inizializzazione dell'indicatore personalizzata |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- mappatura dei buffer degli indicatori
   SetIndexBuffer(0,dAMABuffer,INDICATOR_DATA);
   SetIndexBuffer(1,AMABuffer,INDICATOR_CALCULATIONS);
   
   
   
   //PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MAPeriod+1);
   
   h_AMA=iAMA(_Symbol,PERIOD_CURRENT,AMAPeriod,FastEMA,SlowEMA,0,PRICE_CLOSE);
   if(h_AMA == INVALID_HANDLE)
    {
      Print("AMA indicator initialization error, Code = ", GetLastError());
      return(-1);
    }
   ArraySetAsSeries(AMABuffer,true);
   ArraySetAsSeries(dAMABuffer,true);
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MathMax(AMAPeriod,SlowEMA));
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Funzione di iterazione dell'indicatore personalizzata|
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,    // dimensione dell'array price[]
                const int prev_calculated,// numero di barre elaborate alla chiamata precedente
                const int begin,          // da dove partono i dati significativi
                const double &price[]     // array per il calcolo
                )
  {
   
   if(BarsCalculated(h_AMA)<rates_total) return(0);
//--- possiamo copiare non tutti i dati
   int to_copy;
   if(prev_calculated>rates_total || prev_calculated<=0) 
     {
      to_copy=rates_total;
      if(CopyBuffer(h_AMA,0,0,to_copy,AMABuffer)<=0) return(0);
      for (int i=0;i<to_copy-MathMax(AMAPeriod,SlowEMA);i++)
          {
            dAMABuffer[i]=AMABuffer[i];
          }
     }
   else
     {
      to_copy=rates_total-prev_calculated+MathMax(AMAPeriod,SlowEMA)-1;
      //--- l'ultimo valore viene sempre copiato
      to_copy++;
      if(CopyBuffer(h_AMA,0,0,to_copy,AMABuffer)<=0) return(0); 
      for (int i=0;i<to_copy;i++)
         {
            dAMABuffer[i]=AMABuffer[i];
         }
     }
//--- prova a copiare
   
   Print(dAMABuffer[0]); //per vedere se arriviamo alla fine
//--- restituisce il valore di prev_calculated per la chiamata successiva
//---
//--- restituisce il valore di prev_calculated per la chiamata successiva
   return(rates_total);
  }
//+------------------------------------------------------------------+
 

Ciao,

Ho capito il problema: sei in grado di applicare un indicatore solo ad un altro che si trova nella stessa finestra.

Avete un'idea di come applicare un indicatore (e visualizzarlo in una finestra separata) ad un altro che si trova nella finestra principale?

Grazie

Bests

 

Esiste la possibilità di creare un indicatore in modo programmatico (ad esempio tramite iCustom) e di dirgli di prendere in input i dati di un altro indicatore? O, ancora meglio, di fornirgli direttamente un array di dati su cui costruire l'indicatore.

 
ds2:

Esiste la possibilità di creare un indicatore in modo programmatico (ad esempio tramite iCustom) e di dirgli di prendere in input i dati di un altro indicatore? O, meglio ancora, di fornirgli direttamente un array di dati su cui costruire l'indicatore.

Vedere la funzione iCustom:

Se nell'indicatore viene utilizzata la prima forma di chiamata, quando si lancia un indicatore personalizzato nella scheda "Parametri" è possibile specificare in aggiunta su quali dati verrà calcolato. Se il parametro "Applica a" non viene selezionato esplicitamente, il calcolo viene eseguito per impostazione predefinita sui valori di "Chiusura".

Quando si richiama un indicatore personalizzato da un programma mql5, il parametro Applied_Price o l'handle di un altro indicatore devono essere passati per ultimi dopo tutte le variabili di input fornite dall'indicatore personalizzato.

 

Salve,

Questo è un ottimo articolo ma ho alcune domande.

1. Solo gli indicatori che utilizzano la forma breve della funzioneOnCalculate() possono essere applicati ad un altro indicatore o anche gli indicatori che utilizzano la forma lunga della funzioneOnCalculate() possono essere applicati? In caso affermativo, è possibile applicare un indicatore con la forma lunga della funzioneOnCalculate() a un altro indicatore?

2. L'applicazione di un indicatore ad un altro (TSI su RSI) genera alcuni problemi di visualizzazione (vedi immagine allegata). Mentre RSI è tracciato da 0 a 100, il secondo indicatore (TSI) ha valori inferiori a 0, valori che non sono visibili sul grafico. Qual è il problema e perché il grafico non si adatta a visualizzare correttamente entrambi gli indicatori. Possiamo risolvere questo problema o si tratta di un bug di MetaTrader?

File:
RSIcTSI.png  32 kb
 
Rosh:

Ho deciso di costruire un indicatore a partire da un indicatore e mi sono imbattuto in una confusione.

Entrambi gli indicatori sono costruiti sulla base

int OnCalculate (const int rates_total,      // dimensione dell'array price[]
                 const int prev_calculated,  // barre elaborate nella chiamata precedente
                 const int begin,            // indice da cui partono i dati significativi в массиве price[]
                 const double& price[]       // array per il calcolo
   );

Di conseguenza, l'utente ha la possibilità di impostare il campo prezzo_applicato nei parametri.

La mia difficoltà è come passare il campo prezzo_applicato all'indicatore interno (da cui è costruito l'indicatore esterno)?

La soluzione più semplice è creare un input e avvertire l'utente che l'input prezzo_applicato e il parametro prezzo_applicato devono essere gli stessi, ma questo è un po' strano.

 

Avete guardato l'esempio di OnCalculate()?

Для получения значений пользовательского индикатора из других mql5-программ используется функция iCustom(), возвращающая хэндл индикатора для последующих операций. При этом также можно указать необходимый массив  price[] или хэндл другого индикатора. Этот параметр должен передаваться последним в списке  входных переменных пользовательского индикатора.
 
Пример:

void OnStart()
  {
//---
   string terminal_path=StatusInfoString(STATUS_TERMINAL_PATH);
   int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL);
   if(handle_customMA>0)
      Print("handle_customMA = ",handle_customMA);
   else
      Print("Cannot open or not EX5 file '"+terminal_path+"\\MQL5\\Indicators\\"+"Custom Moving Average.ex5'");
  }

In questo esempio, l'ultimo parametro passato è il valore PRICE_TYPICAL (dall'enumerazione ENUM_APPLIED_PRICE ), che indica che l'indicatore personalizzato sarà costruito dai prezzi tipici ottenuti come (High+Low+Close)/3. Se il parametro non viene specificato, l'indicatore viene costruito in base ai valori di PRICE_CLOSE, ossia in base ai prezzi di chiusura di ogni barra.

 
Rosh:

Si è guardato l'esempio di OnCalculate()?


Sì, l'ho fatto,

int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL);

applied_price è specificato esplicitamente quando viene chiamato iCustom, ma nell'indicatore da cui viene chiamato iCustom, dove si trova?

Perché l'utente lo imposta nei parametri, non negli input.

int OnInit()
  {
//--- mappatura dei buffer degli indicatori
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   hndl=iCustom(_Symbol,_Period,"MyInd",param_ind,???? вот тут нужно указать аплиед_прайс который будет задавать пользователь);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Funzione di iterazione dell'indicatore personalizzata |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
 //...
 return(rates_total);
}

PS il trucco è che l'utente, avendo impostato una volta il parametro applied_price e non più, non si è preoccupato che questo valore passasse attraverso l'intera piramide di chiamate.