Mehrfarbige Indikatoren in MQL5 - Erstellung und Anwendung

Дмитрий Александрович | 13 Januar, 2016

Einleitung

Dank der Mühen und des Strebens der MetaTrader 5-Entwickler ist die Sprache MQL5 entstanden. Alle Neuerungen sind kaum aufzuzählen, aber ich will versuchen, eine Seite dieser Sprache zu beschreiben und zu zeigen und zwar die Möglichkeit der Erstellung mehrfarbiger Indikatoren. In MQL4 kann die Farbe lediglich für eine Indikatorlinie im Ganzen über ihre volle Länge angegeben werden. Einen Indikator in verschiedenen Farben konnte man nur mithilfe einer partiellen Überlagerung der Indikatorpuffer erzeugen, was sehr umständlich war.

In MQL5 haben die Entwickler uns eine neue Möglichkeit eröffnet und zwar die Möglichkeit der Zuweisung einer eigenen Farbe zu jedem einzelnen Abschnitt der Indikatorkurve (bei Verwendung von Linien) sowie zu einzelnen Objekten (Balken, Kerzen, Histogrammen, Pfeilen). Zum besseren Verständnis dieses Beitrags könnte es hilfreich sein, einen Blick in die Dokumentation zu MQL5 zu werfen.

In diesem Beitrag möchte ich folgende Themen erörtern:

Sehen wir uns zwei Arten von mehrfarbigen Zeichenstilen genauer an, DRAW_COLOR_LINE und DRAW_COLOR_CANDLES, die übrigen Zeichenstile unterscheiden sich lediglich durch die Anzahl der Puffer.

Wozu braucht man mehrfarbige Indikatoren?

Mithilfe mehrfarbiger Indikatoren kann man:

Lassen Sie Ihrer Fantasie freien Lauf, um den Handel etwas angenehmer zu gestalten!

Kurze Wiederholung der Grundlagen von MQL5

Beginnen wir mit den Grundsätzen des Indikators.

Im Allgemeinen empfängt der Indikator die eingehenden Daten (Preise sowie Werte anderer Indikatoren), führt Berechnungen aus und füllt einige Puffer mit den berechneten Daten. Anschließend bildet das Ausgabegerät die von dem Indikator gemäß der vorgegebenen Darstellungsart angelegten Angaben aus den Puffern ab.

Die Art der Darstellung wird von dem Indikator und/oder dem Benutzer in den Indikatoreigenschaften festgelegt. Bei den Puffern handelt es sich um allgemeine Datenfelder (global Arrays) des Typs „double“. Mehrere Puffer können in grafischen Elementen gebündelt werden, wenn ein Zeichenstil vorgegeben ist, der mehr als einen Puffer erfordert. Wenn Sie noch nie einen benutzerdefinierten Indikator angelegt haben, sollten Sie folgende Artikel lesen (dort werden die Grundlagen gut erläutert): „MQL5: Erstellen Ihres eigenen Indikators“ und „Benutzerdefinierte Indikatoren in MQL5 für Anfänger“.

Ich werde jetzt den mindestens erforderlichen Code für einen mehrfarbigen Indikator vorstellen und seine Bestandteile beschreiben:

//+------------------------------------------------------------------+
//|                                         test_color_indicator.mq5 |
//|                                                             ProF |
//|                                                          http:// |
//+------------------------------------------------------------------+
#property copyright "ProF"                      //Author
#property indicator_separate_window             //The indicator is plotted in a separate window
#property indicator_buffers 2                   //Number of indicator buffers
#property indicator_plots 1                     //Number of indicator plots
#property indicator_type1 DRAW_COLOR_HISTOGRAM  //Drawing style - Color Histogram
#property indicator_width1 3                    //Line width of a graphic plot (optional)
#property indicator_color1 Red,Green,BlueViolet //Specify 3 colors for a graphic plot

//Declaration of buffers
double buffer_line[]/*Data Buffer*/, buffer_color_line[]/*Color index buffer*/;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//Assign the data array with indicator's buffer
   SetIndexBuffer(0,buffer_line,INDICATOR_DATA);

//Assign the color indexes array with indicator's buffer
   SetIndexBuffer(1,buffer_color_line,INDICATOR_COLOR_INDEX);

//Specify the number of color indexes, used in the graphic plot
   PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);

//Specify colors for each index
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Blue);   //Zeroth index -> Blue
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,Orange); //First index  -> Orange
   return(0);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
   //For each bar we fill the data buffer and index color buffer with values
   for(int i=prev_calculated;i<=rates_total-1;i++)
     {
      //Lets add a simple drawing condition -> If opening price is greater than closing price, then:
      if(open[i]>close[i])
        {   buffer_color_line[i]=0;   }       //Assign color with index=zero (0)
      else
        {  buffer_color_line[i]=1;   }       //Assign color with index=one (1)
      
      //Specify the data for plotting, in our case it's the opening price
      buffer_line[i]=open[i];
     }

   return(rates_total-1); //Return the number of calculated bars, 
                         //subtract 1 for the last bar recalculation
  }
//+------------------------------------------------------------------+
Untersuchen wir die Einzelheiten der Programmierung mehrfarbiger Indikatoren:
#property indicator_buffers 2 //Number of indicator's buffers
#property indicator_plots 1   //Number of graphic plots
In der ersten Zeile legen wir die Anzahl der Puffer des Indikators fest, in unserem Fall sind dies zwei:
  1. der Puffer für die Indikatordaten, in unserem Fall der Eröffnungspreise; sowie
  2. der Puffer für die Kennziffern der Farben.

In der zweiten Zeile geben wir die Anzahl der Zeichenelemente an. Es ist wichtig, zwischen den Zeichenelementen und den Puffern des Indikators zu unterscheiden. Die Zeichenelemente sind die Linien (Kerzen, Balken, Pfeile u.ä.) des Indikators. Bei einem Indikatorpuffer handelt es sich um ein Datenfeld (ein Array) mit den für die Abbildung erforderlichen Daten, ein Datenfeld mit den Farbkennziffern oder ein Datenfeld für die internen Berechnungen des Indikators (Letzteres wird im Indikatorfenster nicht abgebildet).

Die Anzahl der grafischen Elemente kann gleich oder größer als die Anzahl der Puffer sein, das hängt von dem Zeichenstil und der für die Berechnung erforderlichen Pufferzahl ab. Eine Übersicht über die Zeichenstile und die Anzahl der zu ihrer Ausführung erforderlichen Puffer bietet das Kapitel „Zeichenstile“ der Dokumentation zu MQL5.

Jetzt fängt es an „interessant“ zu werden:

#property indicator_type1 DRAW_COLOR_HISTOGRAM  //Drawing style-color histogram
#property indicator_width1 3                    //Drawing line width (optional)
#property indicator_color1 Red,Green,BlueViolet //Specify 3 colors for a graphic plot
In der ersten Zeile legen wir den Zeichenstil (die Art der grafischen Darstellung) fest, in unserem Fall ist dies ein „Histogramm ab einer Nulllinie“. Für diese Art der Darstellung benötigen wir einen Datenpuffer und einen Puffer für die Kennziffern der Farben. Alle Zeichenstile, die das Wort „COLOR“ beinhalten, erfordern einen Puffer für die Kennziffern der Farben.

In der zweiten Zeile erfolgt die Festlegung der Linienstärke des grafischen Elementes auf drei .Pixel; wird in dieser Zeile keine Linienbreite angegeben wird, bleibt diese standardmäßig bei einem Pixel

In der dritten Zeile geben wir die Farben zu den Kennziffern der grafischen Elemente an, in unserem Fall sind das drei Farben: Rot (Red), Grün (Green) und Indigo (BlueViolet). Die Farbkennziffern beginnen bei Null mit: 0 = Red, 1 = Green und 2 = BlueViolet. Diese Farben werden zur Festlegung der Farben der grafischen Elemente benötigt. Die Angabe der Farben über #property indicator_color1 ist eine von zwei Möglichkeiten dazu. Bei diesem Verfahren wird die Farbe „statisch“ zugewiesen, das heißt bei der Zusammenstellung des Programms. Die zweite Möglichkeit betrachten wir weiter unten.

double buffer_line[]/*Data buffer*/, buffer_color_line[]/*Color indexes buffer*/;
Hier deklarieren wir zwei Datenfelder (Arrays), die wir als Puffer verwenden werden, einen für die Daten des Indikators und den zweiten für die Kennziffern der Farben, beide sind vom Typ „double“.

Sehen wir uns jetzt die Ereignisverarbeitungsfunktion zur Bereitstellung des Indikators an:

SetIndexBuffer(0,buffer_line,INDICATOR_DATA);
Hier führen wir einen Indikatorpuffer mit einem Datenfeld zusammen und weisen ihm die Art "INDICATOR_DATA" zu, was bedeutet, dass in diesem Puffer die Indikatorwerte (das heißt die Daten auf die der Indikator ausgelegt ist) gespeichert werden. Beachten Sie bitte, dass der erste Parameter gleich Null (0) ist, es handelt sich dabei um die Kennziffer des Puffers.
SetIndexBuffer(1,buffer_color_line,INDICATOR_COLOR_INDEX);
Hier führen wir einen Indikatorpuffer mit einem Datenfeld zusammen und weisen ihm die Art "INDICATOR_COLOR_INDEX" zu, was bedeutet, dass in diesem Puffer die Kennziffern der Farben eines jeden Balkens des Indikators gespeichert werden. Beachten Sie bitte, dass der erste Parameter gleich Eins (1) ist, das ist die Kennziffer dieses Puffers.

Die Anordnung der Puffer muss eine ganz bestimmte sein: zuerst der bzw. die Puffer für die Daten oder Werte des Indikators, danach der/die für die Kennziffern der Farben.

Nun, jetzt kommen wir endlich zur zweiten Möglichkeit der Festlegung der Farben der grafischen Elemente, genauer gesagt der Zuordnung von Farbkennziffern.

//Specify the number of color indexes, used in the graphics
PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);
Hier geben wir die Anzahl der Kennziffern für die Farben an. Der erste Parameter der Funktion ist gleich „0“, das ist die Kennziffer des grafischen Elements. Beachten Sie bitte, dass wir in diesem Fall die Anzahl der Farbkennziffern selbst bestimmen müssen (bei dem ersten Verfahren wird sie bei der Programmzusammenstellung vom Compiler automatisch berechnet).
PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Blue);   //Zeroth index -> Blue
PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,Orange); //First index  -> Orange
Hier legen wir die Farbe zu jeder Kennziffer fest. Der erste Parameter der Funktion ist die Kennziffer des grafischen Elements und der dritte die Kennziffer der Farbe beginnend bei Null. Die zweite Möglichkeit zur Festlegung der Farbkennziffern zeichnet sich dadurch aus, dass die Anzahl der Kennziffern und der Farben „dynamisch“ angegeben werden können, z. B. mithilfe einer Funktion. Werden beide Verfahren verwendet, so „überschreibt“ die dynamische Festlegung der Farbkennziffern das statische (erste) Verfahren.

Kommen wir jetzt zu der Funktion OnCalculate, in der wir die Werte der Puffer zur Abbildung des Indikators berechnen. Als Auswahlkriterium für die Farben der Säulen des Histogramms haben wir das einfachste gewählt, wenn der Eröffnungskurs über dem Schlusskurs liegt, weisen wir dem aktuellen Element des Pufferdatenfeldes „buffer_color_line“ die Farbkennziffer Null (o) zu. Die Farbkennziffer Null (0) entspricht der Farbe „Blue“ wie oben festgelegt.

Liegt der Eröffnungskurs dagegen unterhalb des Schlusskurses, weisen wir die Farbkennziffer „1“ zu, der die Farbe „Orange“ entspricht. Und so sieht dieses einfache Beispiel aus:

Testindikator

Wie Sie sehen, ist das fast schon zu leicht, man braucht nur etwas Fantasie, die Mittel werden sich schon finden.

Verfahren zur Festlegung der Farbe

Widmen wir uns der Festlegung der Farbe jetzt etwas ausführlicher.

Gemäß der Dokumentation kann die Farbe in MQL5 auf unterschiedliche Weise festgelegt werden:

Sehen wir sie uns der Reihe nach an.

Buchstaben

color color_var = C'10,20,255';
color color_var = C'0x0A,0x14,0xFF';
Die Farben werden gemäß dem RGB-Modell (mit R für Rot, G für Grün und B für Blau) bestimmt, wobei jede Farbe aus diesen drei „Grundfarben“ gemischt werden kann. Entsprechend repräsentiert die erste Zahl die Farbe Rot, die zweite steht für Grün und die dritte für Blau. Die Dezimalzahlen können jeweils zwischen 0 und 255 liegen. In hexadezimaler Form zwischen 00 und FF.

In der ersten und der zweiten Zeile wird der Variablen color_var die Farbe „Blau“ (Blue) zugewiesen. Allerdings in unterschiedlichen Zahlensystemen, in der ersten Zeile nach dem Dezimalsystem, in der zweiten hexadezimal. Es besteht kein Unterschied, wir können es machen, wie es uns am liebsten ist. Je kleiner die Zahl, desto dunkler die Farbe, Weiß (White) ist demnach: „C‘255,255,255‘“ oder „C‘0xFF,0xFF,0xFF‘“ und Schwarz (Black) entsprechend: „C‘0,0,0‘“ oder „C‘0x00,0x00,0x00‘“.

Numerisch

color color_var = 0xFFFFFF;  // white
color color_var = 0x0000FF;  // red
color color_var = 16777215   // white
color color_var = 0x008000   // green
color color_var = 32768      // green
Hier werden die Farben durch Hexadezimal- und Dezimalzahlen festgelegt. „0x0000FF“ zum Beispiel entspricht „C‘0xFF,0x00,0x00‘“, wie wir sehen, haben das erste und das letzte Zahlenpaar die Plätze getauscht.

Um die Dezimalzahl 16777215 zu erhalten, müssen wir die Hexadezimalzahl FFFFFF entsprechend umrechnen.

Farbbezeichnungen

color color_var = Red;    //red
color color_var = Blue;   //blue
color color_var = Orange; //orange
Das ist der einfachste Weg, aber er lässt lediglich die Auswahl aus den Webfarben nicht jedoch das Anlegen eigener Farben zu.

Fassen wir kurz zusammen, wie Farben zugewiesen werden

Alle drei Verfahren sind gleichwertig, wie das Beispiel zeigt:

color color1 = C'255,0,0';
color color2 = C'0xFF,0x00,0x00';
color color3 = 0x0000FF;
color color4 = 255;
color color5 = Red;

Alert((color1==color2)
       && (color1==color2)
       && (color1==color4)
       && (color1==color5)); //prints true

Eine Übung

Wir haben die Grundlagen wiederholt, jetzt schauen wir uns an, wie die Kerzen in einem Diagramm in Abhängigkeit von den Werten eines anderen Indikators, beispielsweise RSI, eingefärbt werden können. Um die Kerzen mehrfarbig zu gestalten, müssen wir einen Indikator programmieren, der in dem Diagramm mithilfe der bunten Kerzen abgebildet wird.

Es folgt der Code des Indikators, liegen die RSI-Werte unter 50 %, werden blaue Kerzen (Blue) ausgegeben, ansonsten ist ihre Farbe „Orange“.

Um meine Leser nicht zu verwirren, habe ich bewusst darauf verzichtet, den Code durch Überprüfungen der Richtigkeit der Daten oder die Bearbeitung von Fehlern zu überfrachten. In der endgültigen Ausführung des Indikators müssen diese Details jedoch vorhanden sein.

//+------------------------------------------------------------------+
//|                                                   cand_color.mq5 |
//|                                                             ProF |
//|                                                          http:// |
//+------------------------------------------------------------------+
#property copyright "ProF"                      //Author
#property indicator_chart_window                //Indicator in separate window

                                          //Specify the number of buffers of the indicator
//4 buffer for candles + 1 color buffer + 1 buffer to serve the RSI data
#property indicator_buffers 6

//Specify the names in the Data Window
#property indicator_label1 "Open;High;Low;Close"

#property indicator_plots 1                     //Number of graphic plots
#property indicator_type1 DRAW_COLOR_CANDLES    //Drawing style - color candles
#property indicator_width1 3                    //Width of the graphic plot (optional)

                                          //Declaration of buffers
double buffer_open[],buffer_high[],buffer_low[],buffer_close[]; //Buffers for data
double buffer_color_line[];    //Buffer for color indexes
double buffer_tmp[1];           //Temporary buffer for RSI data copying
double buffer_RSI[];            //Indicator buffer for RSI
int handle_rsi=0;               //Handle for the RSI indicator
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
/**
        *       The order of the buffers assign is VERY IMPORTANT!
        *  The data buffers are first
        *       The color buffers are next
        *       And finally, the buffers for the internal calculations.
        */
//Assign the arrays with the indicator's buffers
   SetIndexBuffer(0,buffer_open,INDICATOR_DATA);
   SetIndexBuffer(1,buffer_high,INDICATOR_DATA);
   SetIndexBuffer(2,buffer_low,INDICATOR_DATA);
   SetIndexBuffer(3,buffer_close,INDICATOR_DATA);

//Assign the array with color indexes with the indicator's color indexes buffer
   SetIndexBuffer(4,buffer_color_line,INDICATOR_COLOR_INDEX);

//Assign the array with the RSI indicator data buffer
   SetIndexBuffer(5,buffer_RSI,INDICATOR_CALCULATIONS);

//Define the number of color indexes, used for a graphic plot
   PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);

//Set color for each index
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Blue);   //Zeroth index -> Blue
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,Orange); //First index  -> Orande
   
//Get handle of RSI indicator, it's necessary to get the RSI indicator values
   handle_rsi=iCustom(_Symbol,_Period,"Examples\\RSI");
   return(0);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//In the loop we fill the data buffers and color indexes buffers for each bar
   for(int i=prev_calculated;i<=rates_total-1;i++)
     {
      //Copying the RSI indicator's data to the temporary buffer - buffer_tmp
      CopyBuffer(handle_rsi,0,BarsCalculated(handle_rsi)-i-1,1,buffer_tmp);
      //Copying the values from the temporary buffer to the indicator's buffer
      buffer_RSI[i]=buffer_tmp[0];

      //Set data for plotting
      buffer_open[i]=open[i];  //Open price
      buffer_high[i]=high[i];  //High price
      buffer_low[i]=low[i];    //Low price
      buffer_close[i]=close[i];//Close price

                               //Add a simple condition -> If RSI less 50%:
      if(buffer_RSI[i]<50)
        {   buffer_color_line[i]=0;   } //Assign the bar with color index, equal to 0
      else
        {  buffer_color_line[i]=1;   }  //Assign the bar with color index, equal to 1
     }
   return(rates_total-1); //Return the number of calculated bars, 
                         //Subtract 1 for the last bar recalculation
  }
//+------------------------------------------------------------------+

Und so sieht das dann aus:

Mehrfarbiger Indikator in Abhängigkeit von den RSI-Werten

Nicht schlecht, aber wir gehen noch weiter.

Jetzt färben wir die Kerzen entsprechend dem RSI-Niveau mit mehreren Farben ein, sozusagen mit einem Farbverlauf.

Die Farben können von Hand festgelegt werden, aber 30 bis 40 Farben anzulegen, ist weder besonders angenehm noch einfach. Wir machen es anders und schreiben zwei Funktionen. Die Erste zur Festlegung der Kennziffern für die Farben und eine Zweite, um die den eingehenden Argumenten entsprechende Farbe zu beziehen. In den Kommentaren (//) wird das Vorgehen beschrieben.

//+------------------------------------------------------------------+
//|                                               cand_color_RSI.mq5 |
//|                                                             ProF |
//|                                                          http:// |
//+------------------------------------------------------------------+
#property copyright "ProF"                      //Author
#property indicator_chart_window                //Indicator in a separate window

//Specify the number of indicator's buffers
//4 buffers for candles + 1 buffer for color indexes + 1 buffer to store the data of RSI
#property indicator_buffers 6

//Specify the names, shown in the Data Window
#property indicator_label1 "Open;High;Low;Close"

#property indicator_plots 1                     //Number of graphic plots
#property indicator_type1 DRAW_COLOR_CANDLES    //Drawing style - colored candles
#property indicator_width1 3                    //Width of a line (optional)

                                          //Declaration of buffers
double buffer_open[],buffer_high[],buffer_low[],buffer_close[];//Buffers for data
double buffer_color_line[];     //Buffer for color indexes
double buffer_tmp[1];          //Temporary buffer for RSI values
double buffer_RSI[];            //Indicator buffer for RSI
int handle_rsi=0;               //Handle of the RSI indicator
//+------------------------------------------------------------------+
//|    Set colors for a graphic plot                          |
//+------------------------------------------------------------------+
/*
*       The function sets colors for a graphic plot 
*       50 colors from Green to Blue.
*       The index of a graphic plot is passed to the function.

void setPlotColor(int plot)
  {
   PlotIndexSetInteger(plot,PLOT_COLOR_INDEXES,50); //Specify the number of colors

                                               //In the loops we specify the colors
   for(int i=0;i<=24;i++)
     {
      PlotIndexSetInteger(plot,PLOT_LINE_COLOR,i,StringToColor("\"0,175,"+IntegerToString(i*7)+"\""));
     }
   for(int i=0;i<=24;i++)
     {
      PlotIndexSetInteger(plot,PLOT_LINE_COLOR,i+25,StringToColor("\"0,"+IntegerToString(175-i*7)+",175\""));
     }
  }
//+------------------------------------------------------------------+
//|  Get index of the color                                          |
//+------------------------------------------------------------------+
/*
*       The function returns the index of the color
*       The first parameter is the current value of the indicator
*       The second parameter is the minimal value of the indicator
*       The third parameter is the maximal value of the indicator
*/
int getPlotColor(double current,double min,double max)
  {
   return((int)NormalizeDouble((50/(max-min))*current,0));
  }
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
/**
        *       The order of the indicator's buffers is VERY IMPORTANT!
        *  The data buffers are first
        *       The color buffers are next
        *       And finally, the buffers for the internal calculations.
        */
//Assign the arrays with the indicator buffers
   SetIndexBuffer(0,buffer_open,INDICATOR_DATA);
   SetIndexBuffer(1,buffer_high,INDICATOR_DATA);
   SetIndexBuffer(2,buffer_low,INDICATOR_DATA);
   SetIndexBuffer(3,buffer_close,INDICATOR_DATA);

//Assign the array with the color indexes buffer
   SetIndexBuffer(4,buffer_color_line,INDICATOR_COLOR_INDEX);

//Assign the array with RSI indicator buffer
   SetIndexBuffer(5,buffer_RSI,INDICATOR_CALCULATIONS);

//Specify color indexes
   setPlotColor(0);

//Get handle of the RSI indicator, it's necessary get its values
   handle_rsi=iCustom(_Symbol,_Period,"Examples\\RSI",6);
   return(0);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//For each bar we fill the data buffers and buffer with color indexes using the loop
   for(int i=prev_calculated;i<=rates_total-1;i++)
     {
      //Copying the RSI indicator data to the temporary buffer buffer_tmp
      CopyBuffer(handle_rsi,0,BarsCalculated(handle_rsi)-i-1,1,buffer_tmp);
      //Then copying the data from the temporary buffer
      buffer_RSI[i]=buffer_tmp[0];

      //Specify the data for plotting
      buffer_open[i]=open[i];  //Open price
      buffer_high[i]=high[i];  //High price
      buffer_low[i]=low[i];    //Low price
      buffer_close[i]=close[i];//Close price

      //Paint the candles depending on RSI indicator values
      //RSI = 0     - candle is Green
      //RSI = 100   - candle is Blue
      //0<RSI<100   - candle color is between Green and Blue 
      buffer_color_line[i]=getPlotColor(buffer_RSI[i],0,100);

     }
   return(rates_total-1); //Return the number of calculated bars, 
                         //Subtract 1 for the last bar recalculation
  }
//+------------------------------------------------------------------+

Und so sieht es aus:

RSI-Farbverlauf

Experimentieren Sie ruhig mit diesem Beispiel, indem Sie andere Farben einsetzen. Oder versuchen Sie, den RSI durch einen anderen Indikator zu ersetzen.

Übung macht den Meister.

Zeichenstile ändern: Bei bereits bestehenden und geprüften Abbildungen

Es können auch bereits vorhandene Indikatoren eingefärbt werden, dazu ist es erforderlich: die Art der grafischen Darstellung in mehrfarbig zu ändern, Puffer hinzuzufügen, sie mit dem Puffer des Indikators zu verknüpfen und die Bedingungen für das Einfärben festzulegen.

Die folgende Übersicht zeigt eine Synopse des jeweils ursprünglichen und des mehrfarbigen Zeichenstils:

Vor der Überarbeitung
Nach der Überarbeitung
DRAW_LINEDRAW_COLOR_LINE
DRAW_SECTIONDRAW_COLOR_SECTION
DRAW_HISTOGRAMDRAW_COLOR_HISTOGRAM
DRAW_HISTOGRAM2DRAW_COLOR_HISTOGRAM2
DRAW_ARROWDRAW_COLOR_ARROW
DRAW_ZIGZAGDRAW_COLOR_ZIGZAG (Beispiel)
DRAW_CANDLESDRAW_COLOR_CANDLES

Es folgt der Programmcode für den überarbeiteten Indikator RSI, der jetzt entsprechend seinen eigenen Werten eingefärbt wird.

Alle Überarbeitungen sind kommentiert (//).

//+------------------------------------------------------------------+
//|                                                          RSI.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "2009, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property description "Relative Strength Index"
//--- indicator settings
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_level1 30
#property indicator_level2 70
/////////////////////////////////////////////////////////////////////
#property indicator_buffers 4 //The number of buffers has increased by 1
#property indicator_width1 5  //The line width has set to 4 pixels
/////////////////////////////////////////////////////////////////////
#property indicator_plots   1
/////////////////////////////////////////////////////////////////////
//Drawing style has been changed from DRAW_LINE to DRAW_COLOR_LINE
#property indicator_type1   DRAW_COLOR_LINE
/////////////////////////////////////////////////////////////////////
#property indicator_color1  DodgerBlue
//--- input parameters
input int InpPeriodRSI=14; // Period
//--- indicator buffers
double    ExtRSIBuffer[];
double    ExtPosBuffer[];
double    ExtNegBuffer[];
//--- global variable
int       ExtPeriodRSI;

//////////////////////////////////////////////////////////////////////
double buffer_color[]; //Declare an array for color indexes

//Added two functions
//+------------------------------------------------------------------+
//|    Set color for a graphic plot                                  |
//+------------------------------------------------------------------+
/*
*       The function specify the color for a graphic plot 
*       50 colors from Green to Blue are available.
*       The index of a graphic plot is passed to the function.
*/
void setPlotColor(int plot)
  {
   PlotIndexSetInteger(plot,PLOT_COLOR_INDEXES,50); //Set number of colors

                                                    //Specify colors in loop
   for(int i=0;i<=24;i++)
     {
      PlotIndexSetInteger(plot,PLOT_LINE_COLOR,i,StringToColor("\"0,175,"+IntegerToString(i*7)+"\""));
     }
   for(int i=0;i<=24;i++)
     {
      PlotIndexSetInteger(plot,PLOT_LINE_COLOR,i+25,StringToColor("\"0,"+IntegerToString(175-i*7)+",175\""));
     }
  }
//+------------------------------------------------------------------+
//|  Get index of the color                                           |
//+------------------------------------------------------------------+
/*
*       The function returns the color index
*       The first parameter is the current value of the indicator
*       The second parameter is the minimal value of the indicator
*       The third parameter is the maximal value of the indicator
*/
int getPlotColor(double current,double min,double max)
  {
   return((int)NormalizeDouble((50/(max-min))*current,0));
  }
//////////////////////////////////////////////////////////////////////


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- check for input
   if(InpPeriodRSI<1)
     {
      ExtPeriodRSI=12;
      Print("Incorrect value for input variable InpPeriodRSI =",InpPeriodRSI,
            "Indicator will use value =",ExtPeriodRSI,"for calculations.");
     }
   else ExtPeriodRSI=InpPeriodRSI;
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtRSIBuffer,INDICATOR_DATA);
   
/////////////////////////////////////////////////////////////////////
//Assign the array with buffer of color indexes
        SetIndexBuffer(1,buffer_color,INDICATOR_COLOR_INDEX);
//The order of buffers is changed!
        SetIndexBuffer(2,ExtPosBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,ExtNegBuffer,INDICATOR_CALCULATIONS);
//Set colors
   setPlotColor(0);
/////////////////////////////////////////////////////////////////////

//--- set accuracy
   IndicatorSetInteger(INDICATOR_DIGITS,2);
//--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodRSI);
//--- name for DataWindow and indicator subwindow label
   IndicatorSetString(INDICATOR_SHORTNAME,"RSI("+string(ExtPeriodRSI)+")");
//--- initialization done
  }
//+------------------------------------------------------------------+
//| Relative Strength Index                                          |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   int    i;
   double diff;
//--- check for rates count
   if(rates_total<=ExtPeriodRSI)
      return(0);
//--- preliminary calculations
   int pos=prev_calculated-1;
   if(pos<=ExtPeriodRSI)
     {
      //--- first RSIPeriod values of the indicator are not calculated
      ExtRSIBuffer[0]=0.0;
      ExtPosBuffer[0]=0.0;
      ExtNegBuffer[0]=0.0;
      double SumP=0.0;
      double SumN=0.0;
      for(i=1;i<=ExtPeriodRSI;i++)
        {
         ExtRSIBuffer[i]=0.0;
         ExtPosBuffer[i]=0.0;
         ExtNegBuffer[i]=0.0;
         diff=price[i]-price[i-1];
         SumP+=(diff>0?diff:0);
         SumN+=(diff<0?-diff:0);
        }
      //--- calculate first visible value
      ExtPosBuffer[ExtPeriodRSI]=SumP/ExtPeriodRSI;
      ExtNegBuffer[ExtPeriodRSI]=SumN/ExtPeriodRSI;
      ExtRSIBuffer[ExtPeriodRSI]=100.0-(100.0/(1.0+ExtPosBuffer[ExtPeriodRSI]/ExtNegBuffer[ExtPeriodRSI]));
      //--- prepare the position value for main calculation
      pos=ExtPeriodRSI+1;
     }
//--- the main loop of calculations
   for(i=pos;i<rates_total;i++)
     {
      diff=price[i]-price[i-1];
      ExtPosBuffer[i]=(ExtPosBuffer[i-1]*(ExtPeriodRSI-1)+(diff>0.0?diff:0.0))/ExtPeriodRSI;
      ExtNegBuffer[i]=(ExtNegBuffer[i-1]*(ExtPeriodRSI-1)+(diff<0.0?-diff:0.0))/ExtPeriodRSI;
      ExtRSIBuffer[i]=100.0-100.0/(1+ExtPosBuffer[i]/ExtNegBuffer[i]);
/////////////////////////////////////////////////////////////////////
//Paint it
                buffer_color[i] = getPlotColor(ExtRSIBuffer[i],0,100);
/////////////////////////////////////////////////////////////////////
     }
//--- OnCalculate done. Return new prev_calculated.
   return(rates_total);
  }
//+------------------------------------------------------------------+

Was geschehen ist, können Sie sehen, wenn Sie die Farbe der Kerzen mit der Farbe des Indikators RSI selbst vergleichen.

RSI mehrfarbig

Beziehen der Indikatorfarbe aus einem Expert-System/Indikator/Skript

Die Möglichkeit, eine Linienfarbe abzurufen, kann für den automatisierten Handel in einem Expert-System oder zu anderen Zwecken mitunter recht nützlich sein.

Die Umsetzung ist recht einfach, ich zeige es Ihnen am Beispiel eines Skripts.

//+------------------------------------------------------------------+
//|                                                         test.mq5 |
//|                                                             ProF |
//|                                                          http:// |
//+------------------------------------------------------------------+
#property copyright "ProF"
#property link      "http://"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
        int handle = 0; //handle of the indicator
        double tmp[1];  //temporary array for color index buffer.
        //Get the handle of our modified RSI
        handle = iCustom(_Symbol,_Period,"Examples\\RSI",6);
        
        //Let's remember, that values are stored in the buffer 1 of our modified RSI
        //The color indexes are stored in the buffer 0
        //Copying the data from the buffer "1" of the RSI indicator.
        CopyBuffer(handle,1,0,1,tmp);
        
        //Show alert with last color index, returned by RSI
        Alert(tmp[0]); //For example, if returned 0, it means that RSI
        //is painted with Green color and its current level is near 0.
  }
//+-----------------------------------------------------------------+
Beachten Sie bitte, dass wir nur die Kennziffer der Farbe abrufen können, nicht die Farbe selbst!

Sie sollten wissen, welche Farbkennziffer welcher Farbe in dem Indikator entspricht, von dem Sie die Farbkennziffer abrufen. Und Sie müssen wissen, in welchem Puffer die Kennziffer der Farbe gespeichert wird.

Um das herauszufinden, müssen Sie wissen, nach welchen Kriterien der Indikator die Farbkennziffern vergibt, oder diese aus ihrer Erfahrung anhand des oben genannten Skripts festlegen oder wie es Ihnen sonst beliebt.

Fazit

Wir haben folgende Zeichenstile erörtert: DRAW_COLOR_LINE und DRAW_COLOR_CANDLES. Wir haben Kerzen eingefärbt und erfahren, wie man den Indikator RSI färbt (DRAW_LINE -> DRAW_COLOR_LINE). Außerdem haben wir gelernt, wie man den Wert des Farbkennziffernpuffers abruft.

MQL5 bietet schöne Möglichkeiten zur Einfärbung von Indikatoren, alles bleibt allein Ihrer Fantasie, Ihrem Vermögen und Ihrer Erfahrung überlassen. Durch die Verwendung mehrfarbiger Linien verbessert sich auch die Wahrnehmung eines so dynamischen Wesens, wie es der Markt ist.

Nutzen Sie die neuen Möglichkeiten, um sich beim Handel mehr Komfort zu verschaffen.