Diskussion zum Artikel "Anwenden von Indikatoren auf Indikatoren"

 

Neuer Artikel Anwenden von Indikatoren auf Indikatoren :

Möchten Sie einen Indikator verbessern und seine korrekte Anwendung auf die Daten anderer Indikatoren ermöglichen? In diesem Beitrag betrachten wir die Schritte, die für diese Anpassung benötigt werden.

Autor: MetaQuotes Software Corp.

 

Danke für einen weiteren guten Artikel. Traditionell sind die Artikel der MQL-Community für mich ein Weg, um eine postsekundäre Ausbildung zu erhalten (d.h. die eingebaute MQL-Editor-Anleitung)

Zu diesem Punkt ist mir ein kleiner Fehler im Code aufgefallen. Nach der Idee des Autors

//--- Kennzeichen für die einmalige Ausgabe von Preis[]-Werten

die Variable

   bool printed=false;

außerhalb der Funktion OnCalculate() verschoben werden, da sonst bei jedem Ereignis das Array gedruckt wird.

Außerdem gibt es hier einen Druckfehler

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

Wenn wir also einen RSI-Indikator (Indikator A) mit einer Periode von 14 erstellen und dann unseren benutzerdefinierten Indikator True Strength Index (Indikator B) auf den Daten des RSI(14)-Indikators aufbauen, dann:

Nach der Regel und der Logik ist Indikator A ein benutzerdefinierter TSI und Indikator B(basic) ein RSI.

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

Dieser Artikel enthält das detaillierte Wissen.

Danke!

 

Hallo,

Dieser Artikel ist wirklich interessant und eröffnet neue Möglichkeiten, Indikatoren zu verwalten.

Da ich ein Anfänger in MQL5 bin, habe ich versucht, die Möglichkeit zu implementieren, einen Indikator auf einen anderen anzuwenden. Ich habe einen kleinen Code, der nur duplizieren geschrieben

einen anpassungsfähigen gleitenden Durchschnitt in der Hoffnung, es auf jeden Indikator des Diagramms zu verwenden.

Leider habe ich in der Liste der Parameter, die erscheint, wenn Sie den Indikator starten, nicht den Fall "apply to : previuos indicator's data".

Wie sollte der Code aufgebaut sein, um die Möglichkeit zu haben, ihn auf einen anderen Indikator anzuwenden?

Hier ist mein Code:

#property indicator_separate_window
#property indicator_minimum             1.3
#property indicator_maximum             1.35
//#Eigenschaft indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   1
//--- dMA darstellen
#property indicator_label1  "dAMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- Eingabeparameter
input int      AMAPeriod=9;
input int      FastEMA=2;
input int      SlowEMA=20;
//--- Indikatorpuffer
double         AMABuffer[];
double         dAMABuffer[];

int            h_dAMA;
int            h_AMA;
//+------------------------------------------------------------------+
//| Benutzerdefinierte Initialisierungsfunktion für Indikatoren |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Zuordnung von Indikatorpuffern
   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);
  }
//+------------------------------------------------------------------+
//| Benutzerdefinierte Indikator-Iterationsfunktion|
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,    // Größe des Preis[]-Arrays
                const int prev_calculated,// Anzahl der beim vorherigen Aufruf verarbeiteten Takte
                const int begin,          // von wo aus die signifikanten Daten beginnen
                const double &price[]     // Array für die Berechnung
                )
  {
   
   if(BarsCalculated(h_AMA)<rates_total) return(0);
//--- wir können nicht alle Daten kopieren
   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;
      //--- letzter Wert wird immer kopiert
      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];
         }
     }
//--- versuchen zu kopieren
   
   Print(dAMABuffer[0]); //um zu sehen, ob wir bis zum Ende durchhalten
//--- Rückgabewert von prev_calculated für den nächsten Aufruf
//---
//--- Rückgabewert von prev_calculated für den nächsten Aufruf
   return(rates_total);
  }
//+------------------------------------------------------------------+
 

Hallo!

Ich habe das Problem verstanden: Sie können nur einen Indikator auf einen anderen anwenden, der sich im selben Fenster befindet.

Haben Sie eine Idee, wie man einen Indikator auf einen anderen, der sich im Hauptfenster befindet, anwenden (und ihn in einem separaten Fenster anzeigen) kann?

Danke

Beste Grüße

 

Gibt es eine Möglichkeit, einen Indikator programmatisch zu erstellen (z. B. über iCustom) und ihm mitzuteilen, dass er Daten aus einem anderen Indikator als Input nehmen soll? Oder, noch besser, ihm ein direktes Array von Daten zu geben, auf dem er aufgebaut werden soll.

 
ds2:

Gibt es eine Möglichkeit, einen Indikator programmatisch zu erstellen (z. B. über iCustom) und ihm mitzuteilen, dass er Daten aus einem anderen Indikator als Input nehmen soll? Oder, noch besser, ihm direkt ein Array von Daten zu geben, auf dem er aufgebaut werden soll.

Siehe die Funktion iCustom:

Wenn die erste Form des Aufrufs im Indikator verwendet wird, können Sie beim Starten eines benutzerdefinierten Indikators auf der Registerkarte "Parameter" zusätzlich angeben, auf welchen Daten er berechnet werden soll. Wenn der Parameter "Anwenden auf" nicht explizit ausgewählt wird, erfolgt die Berechnung standardmäßig anhand der "Close"-Werte.

Wenn Sie einen benutzerdefinierten Indikator von einem mql5-Programm aus aufrufen, sollte der Parameter Applied_Price oder das Handle eines anderen Indikators als letztes nach allen vom benutzerdefinierten Indikator bereitgestellten Eingabevariablen übergeben werden.

 

Hallo,

Dies ist ein sehr guter Artikel, aber ich habe einige Fragen.

1) Können nur die Indikatoren, die die Kurzform des OnCalculate() Funktionsaufrufs verwenden , auf einen anderen Indikator angewendet werden oder können auch die Indikatoren, die die Langform des OnCalculate() Funktionsaufrufs verwenden, angewendet werden? Wenn ja, wie kann ein Indikator mit der langen Form des OnCalculate() -Funktionsaufrufs auf einen anderen Indikator angewendet werden?

2. Die Anwendung eines Indikators auf einen anderen (TSI über RSI) führt zu einigen Darstellungsproblemen (siehe beigefügtes Bild). Während der RSI von 0 bis 100 geplottet wird, hat der zweite Indikator (TSI) auch Werte unter 0, die auf dem Chart nicht zu sehen sind. Das ist das Problem und der Grund, warum sich das Diagramm nicht richtig anpasst, um beide Indikatoren korrekt anzuzeigen. Können wir dieses Problem lösen oder ist es ein MetaTrader-Bug???

Dateien:
RSIcTSI.png  32 kb
 
Rosh:

Ich beschloss, einen Indikator aus einem Indikator zu erstellen und stieß dabei auf ein Missverständnis.

Beide Indikatoren sind auf der Basis

int OnCalculate (const int rates_total,      // Preis[] Array Größe
                 const int prev_calculated,  // Balken, die beim vorherigen Aufruf verarbeitet wurden
                 const int begin,            // Index, ab dem die signifikanten Daten beginnen в массиве price[]
                 const double& price[]       // Array für die Berechnung
   );

Dementsprechend hat der Benutzer die Möglichkeit, das Feld applied_price in den Parametern zu setzen.

Meine Schwierigkeit besteht darin, das Feld applied_price an den internen Indikator (aus dem der externe Indikator erstellt wird) zu übergeben.

Die einfachste Lösung besteht darin, eine Eingabe zu machen und den Benutzer zu warnen, dass die applied_price-Eingabe und der applied_price-Parameter identisch sein sollten, aber das ist irgendwie schief.

 

Haben Sie sich das Beispiel für OnCalculate() angesehen?

Для получения значений пользовательского индикатора из других 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 diesem Beispiel ist der letzte übergebene Parameter der Wert PRICE_TYPICAL (aus der Aufzählung ENUM_APPLIED_PRICE ), der angibt, dass der benutzerdefinierte Indikator anhand der typischen Preise erstellt wird, die als (High+Low+Close)/3 ermittelt werden. Wird der Parameter nicht angegeben, wird der Indikator anhand der PRICE_CLOSE-Werte gebildet, d. h. anhand der Schlusskurse der einzelnen Leisten.

 
Rosh:

Haben Sie sich das Beispiel für OnCalculate() angesehen?


Ja, das habe ich,

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

applied_price wird explizit angegeben, wenn iCustom aufgerufen wird, aber in dem Indikator, von dem aus iCustom aufgerufen wird, woher soll er kommen?

Weil der Benutzer ihn in den Parametern festlegt, nicht in den Eingaben.

int OnInit()
  {
//--- Zuordnung von Indikatorpuffern
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   hndl=iCustom(_Symbol,_Period,"MyInd",param_ind,???? вот тут нужно указать аплиед_прайс который будет задавать пользователь);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Benutzerdefinierte Indikator-Iterationsfunktion |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
 //...
 return(rates_total);
}

PS der Trick ist, dass der Benutzer, der einmal den applied_price Parameter gesetzt hat und sich nicht mehr darum kümmert, dass dieser Wert durch die ganze Pyramide von Aufrufen geht.