Die Realisierung der dreifarbigen Indikatoren und einige Möglichkeiten für eine maximale Vereinfachung des Indikatoren-Schreibens

Nikolay Kositsin | 14 April, 2016

Einleitung

In vielen Fällen gilt Farbe als die beste Informationsquelle. Ihre Änderung signalisiert anschaulich und zeitnah über aktuellen Veränderungen in den Eigenschaften des Marktes. Deshalb erscheinen die dreifarbigen Trendindikatoren sehr oft informativer und effizienter als ihre einfarbige Analoge. Schauen Sie einfach auf unser Beispiel, welches in zwei Varianten dargestellt ist:

In einer einfachen Version mit ungefärbten Indikatoren in Trendrichtung:


und eine Version, bei der die Indikatoren je nach der Trendrichtung differenziert gefärbt sind:



Sie können direkt sehen, dass es im zweiten Fall viel einfacher ist, mit dem Chart zu arbeiten. Der Aufbau solcher Indikatoren macht in MQL4 keine Probleme. Es gibt dadurch keinen ernsthaften Anstieg des Ressourcenverbrauchs. Also, diese Gelegenheit im Handeln nicht zu nutzen - wäre einfach die Möglichkeit zu verpassen, die anstrengende Arbeit einer konstanten Beobachtung über der Marktlage vereinfachen würde.

Lassen Sie uns lernen, solche Indikatoren zu bauen.


Der dreifarbige Indikator 3c_JJRSX1


Zunächst bauen wir einmal ein dreifarbiges lineares Chart basierend auf den Oszillator JJRSX:

iCustom(NULL,0,"JJRSX",Length,Smooth,Smooth_Phase,
        Input_Price_Customs,0,bar).

Es sollte keine Probleme beim Schreiben des dreifarbigen Analoges geben, welches über die Veränderungen der Trendsfarbe signalisiert:

/*
Für  die Arbeit  des Indikators  müssen  die Daten    
JJMASeries.mqh 
JurXSeries.mqh 
PriceSeries.mqh 
im Verzeichnis: MetaTrader\experts\include\ abgelegt werden 
Heiken Ashi#.mq4
im Verzeichnis: MetaTrader\indicators\
*/
//+------------------------------------------------------------------+ 
//|                                                    3c_JJRSX1.mq4 |
//|                           Copyright c 2006,     Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+ 
#property copyright "Copyright c 2006, Nikolay Kositsin"
#property link      "farria@mail.redcom.ru" 
//---- Darstellung des Indikators im getrennten Fenster
#property indicator_separate_window
//---- die Anzahl der Indikatorpuffers
#property indicator_buffers  3
//---- die Farben des Indikators
#property indicator_color1  BlueViolet
#property indicator_color2  Magenta
#property indicator_color3  Gray
//---- die Dicke der Indikator-Linien
#property indicator_width1 3
#property indicator_width2 3
#property indicator_width3 3
//---- Die Parameter der horizontalen Ebenen des Indikators
#property indicator_level1  0.5
#property indicator_level2 -0.5
#property indicator_level3  0.0
#property indicator_levelcolor MediumBlue
#property indicator_levelstyle 4
//---- Eingabeparameter des Indikators 
extern int        Length = 8;  // Die Glättungstiefe des Indikators
extern int        Smooth = 3; // die zusätzliche Glättungstiefe JMA
// die zusätzliche Glättung JMA, der sich im Bereich zwischen -100 ... +100 ändert, 
//beeinflusst auf die Qualität des vorübergehenden Prozess;
extern int  Smooth_Phase = 100;
/* Die Wahl der Preise, nach den der Indikator berechnet wird 
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED,
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW,
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int Input_Price_Customs = 0; 
//---- Indikatorpuffers
double Ind_Buffer1[];
double Ind_Buffer2[];
double Ind_Buffer3[]; 
//+------------------------------------------------------------------+  
//| JJRSX initialization function                                    |
//+------------------------------------------------------------------+ 
int init()
  {
// Die Darstellungsarten des Indikators
   SetIndexStyle(0,DRAW_HISTOGRAM, STYLE_SOLID);
   SetIndexStyle(1,DRAW_HISTOGRAM, STYLE_SOLID);
   SetIndexStyle(2,DRAW_HISTOGRAM, STYLE_SOLID);
// 4 Indikatorpuffers wurden für die Zählung verwendet 
   SetIndexBuffer(0,Ind_Buffer1);
   SetIndexBuffer(1,Ind_Buffer2);
   SetIndexBuffer(2,Ind_Buffer3);
// Die Einstellung der Indikator-Werten, die im Chart unsichtbar werden
   SetIndexEmptyValue(0,0); 
   SetIndexEmptyValue(1,0);
   SetIndexEmptyValue(2,0);
// Die Namen für Datenfenster und Labels für Unterfenster
   SetIndexLabel(0,"Up_Trend");
   SetIndexLabel(1,"Down_Trend");
   SetIndexLabel(2,"Straight_Trend");
   IndicatorShortName("JJRSX(Length="+Length+")");
// Einstellung der Genauigkeit der Format (Die Anzahl der Zeichen nach dem dezimalen Komma) 
//die Indikatorswerte zu visualisieren  
   IndicatorDigits(0);
// Die Korrektur für nicht akzeptablen Werte des Parameters Length
  if(Length<1)Length=1; 
// Die Bestimmung der Nummer des Bars, von der der Indikator entsteht  
   int draw_begin=3*Length+30+1; 
   SetIndexDrawBegin(0,draw_begin);
   SetIndexDrawBegin(1,draw_begin);
   SetIndexDrawBegin(2,draw_begin);   
//---- Das Ende des Initialisierens 
return(0);
  }
//+------------------------------------------------------------------+ 
//| JJRSX iteration function                                         |
//+------------------------------------------------------------------+ 
int start()
  {
// Eingabe der ganzen Speichervariablen
   static int time2;
// Eingabe der Speichervariablen mit Gleitkomma 
   static double VelueM;
// Eingabe der Variablen mit Gleitkomma   
    double Velue0,Velue1,trend; 
// Eingabe der ganzen Variablen und erhalten dadurch bereits berechneten Bars
    int bar,limit,MaxBar,Tnew,counted_bars=IndicatorCounted();
//  Überprüfung auf mögliche Fehler
    if (counted_bars<0)return(-1);
// das letzte berechnete Bar muss neuberechnet werden 
    if (counted_bars>0) counted_bars--;
// Die Bestimmung der Nummer des letzten Bars, von dem die Neuberechnung 
//  aller Bars beginnt
    MaxBar=Bars-3*Length-30; 
    //---- Die Bestimmung der Nummer des letzten Bars, von dem die Neuberechnung, 
    //der neuen  Bars beginnt
    limit=Bars-counted_bars-1; 
    //+--- Initialisieren der Null
    if (limit>=MaxBar)
      for(bar=Bars-1;bar>=MaxBar;bar--)
       {
        limit=MaxBar;
        Ind_Buffer1[bar]=0.0;
        Ind_Buffer2[bar]=0.0;
        Ind_Buffer3[bar]=0.0;
       }
//+--- Wiederherstellung der Werte der Variablen 
    Tnew=Time[limit+1];
    if (limit<MaxBar)
    if (Tnew==time2)
     {
      Velue1=VelueM;
     }
    else 
     {
      if (Tnew>time2)
           Print("Fehler bei der Wiederherstellung der Variablen!!! Tnew>time2");
      else Print("Fehler bei der Wiederherstellung der Variablen!!! Tnew<time2");
      Print("die Neuberechnung des Indikators wird auf allen Bars durchgeführt!");
      return(-1);  
     }
//----+ Die Hauptloop der Berechnung des Indikators
    while (bar>=0)
      {
       //+--- Speichern wir den Wert der Variablen +====+ 
     if (bar==1)
      {
       if(((limit==1)&&(time2==Time[2]))||(limit>1))
         {
          VelueM=Velue1;
          time2=Time[bar];
         }
      }
     //+---+====================================+          
        Velue0=iCustom(NULL,0,"JJRSX",Length,Smooth,Smooth_Phase,
                       Input_Price_Customs,0,bar);
        if (bar==MaxBar)
          {
           Velue1=Velue0;
           continue;
          }        
        //---- Der dreifarbige Code des Indikators 
        trend=Velue0-Velue1;     
        if(trend>0)     
          {
            Ind_Buffer1[bar]=Velue0; 
            Ind_Buffer2[bar]=0;      
            Ind_Buffer3[bar]=0;
          }
        else
          {
            if(trend<0)
              {
                Ind_Buffer1[bar]=0;
                Ind_Buffer2[bar]=Velue0; 
                Ind_Buffer3[bar]=0;
              }
            else 
              {
                Ind_Buffer1[bar]=0;
                Ind_Buffer2[bar]=0;
                Ind_Buffer3[bar]=Velue0;
              }
          }    
        //---- 
        Velue1=Velue0;
        //----+
        bar--;
     } 
    //---- Das Ende der Berechnung der Indikator-Werte
    return(0);
  }
//+--------------------------------------------------------------+


Drei Indikatorpuffer werden für den Indikator verwendet. Für die Werte des Anfangsindikators JJRSX auf dem ersten Bar wird die Variable Value1 verwendet. Um den Wert der Variable Value1 zwischen Ticks nicht zu verlieren, wird er in der statischen Variable ValueM gespeichert. Der Algorithmus des Indikators vergleicht den aktuellen Wert des Indikators mit dem Wert auf dem vorherigen Bar und legt diesen Wert in den notwendigen Indikatorpuffer. Um den ähnlichen Indikator auf der Grundlage eines anderen benutzerdefinierten Indikators zu machen, müssen Sie einfach den Namen des benutzerdefinierten Indikators in der Zeile des Aufrufs zum benutzerdefinierten Indikator ändern.

Velue0=iCustom(NULL,0,"JJRSX",Length,Smooth,Smooth_Phase, 
               Input_Price_Customs,0,bar);

In der Zeile

MaxBar = Bars - 3*Length - 30;

ändern Sie die Berechnungsformel, und es muss auch die Berechnungsformel in der Zeile

int draw_begin = 3*Length + 30 + 1;

im Initialisierungsblock geändert werden. Und ersetzen Sie natürlich die externen Variablen im Kopf des Indikators um die notwendigen Variablen. Sie können das Chart informativer gestalten, indem sie den Indikator BollingerBands zum Chart hinzufügen und die Möglichkeit nutzen, die Form des Indikators von linear in ein Punktdiagramm zu ändern. Außerdem, wenn dieser Indikator als Vorlage verwendet wird, werden einige Unannehmlichkeiten bei der Suche nach den Zeilen verursachen, die innerhalb des Programmcodes gewechselt werden müssen. Der Code wird aber nicht in anderen dreifarbigen Charts geändert. Es wäre vernünftiger, dieser Programmcode in der mqh-Datei zu platzieren und den im Inneren des Indikators durch den Operator #include zu verwenden, wir machen es genauso. In diesem Fall erhält der Code des Indikators eine einfache Form ohne übermäßige Elemente. Der Code ist dann leicht, als Vorlage beim Schreiben der anderen Oszillatorscharts zu verwenden:

/*
Für  die Arbeit  des Indikators  müssen  die Daten     
JJMASeries.mqh
PriceSeries.mqh
3c_BB_Osc.mqh  
im Verzeichnis: MetaTrader\experts\include\ abgelegt werden 
JJRSX.mq4 
Heiken Ashi#.mq4
im Verzeichnis: MetaTrader\indicators\
*/
//+------------------------------------------------------------------+  
//|                                                     3c_JJRSX.mq4 |
//|                               Copyright © 2006, Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Nikolay Kositsin"
#property link      "farria@mail.redcom.ru"
//---- Darstellung des Indikators im getrennten Fenster
#property indicator_separate_window
//---- die Anzahl der Indikatorpuffers
#property indicator_buffers 8 
//---- die Farben des Indikators 
#property indicator_color1 Gray 
#property indicator_color2 LimeGreen
#property indicator_color3 Red
#property indicator_color4 Purple
//---- Bollinger Bands Farben
#property indicator_color5 Blue
#property indicator_color6 Blue
#property indicator_color7 Magenta
#property indicator_color8 Magenta
//---- die Dicke der Indikator-Linien
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 1 
#property indicator_width4 1
//---- Der Stil der Mantellinie
#property indicator_style1 4
//---- Der Stil der Bollinger Bands Linie
#property indicator_style5 4
#property indicator_style6 4
#property indicator_style7 4
#property indicator_style8 4
//---- Die Parameter der horizontalen Ebenen des Indikators
#property indicator_level1 0.0
#property indicator_levelcolor SteelBlue
#property indicator_levelstyle 4
//---- Eingabeparameter des Indikators
extern int  Length = 8;  // die Glättungstiefe JurX
// die Glättungstiefe JJMA des erhaltenden Indikators
extern int  Smooth = 3; 
// Der Parameter, der sich im Bereich zwischen -100 ... +100 ändert, 
// beeinflusst auf die Qualität der vorübergehenden Glättungsprozesse
extern int  Phase = 100; 
/* Die Wahl der Preise, nach den der Indikator berechnet wird 
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED,
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW,
11-Heiken Ashi Low, 12-Heiken Ashi High,  13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int Input_Price_Customs = 0;
//---- Eingabe der Funktion COUNT_begin(),um die Nummer des Bars zu berechnen, 
// von der der Indikator entsteht und wird  
// Bollinger Bands berechnet 
int COUNT_begin()
{int count_begin=2*Length+30;return(count_begin);}
//---- Eingabe der Funktion digits() für die Einstellung der Genauigkeit der Format 
// (Die Anzahl der Zeichen nach dem dezimalen Komma) um  
// die Indikatorswerte zu visualisieren 
int digits(){return(2);}
//---- Die Einstellung der Indikator-Werten, die im Chart unsichtbar werden 
int EmptyValue=0.0;
//---- Die Definition den Namen des Indikators 
string Label = "JJRSX";
 
//---- Das Hinzufügen des Haupttextes des Indikators zu seinem Text
#include <3c_BB_Osc.mqh> 
//---- Eingabe der Funktion INDICATOR 
//---- Der Aufruf zum Anfangsindikator für die Erhaltung der Anfangswerte
double INDICATOR(int INDICATOR.bar)
 {
  return(iCustom( NULL, 0, "JJRSX", Length, Smooth, Phase, 
         Input_Price_Customs, 0, INDICATOR.bar) );
 }
//---- ---------------------------------------------------------------+

Der ganze übermäßige Code wird in der Datei 3c_BB_Osc.mqh platziert und wird im Indikator nur in einer Zeile

#include <3c_BB_Osc.mqh>

repräsentiert. Die mqh-Datei enthält auch die externen Variablen für Bollinger Bands und für die Stilwahl der Chart-Darstellung. Natürlich muss dann die Datei 3c_BB_Osc.mqh im Verzeichnis: \MetaTrader\EXPERTS\INCLUDE sein.



Der Algorithmus im Aufbau eines dreifarbigen Indikators


Nun zum Erstellen eines neuen dreifarbigen Oszillators müssen Sie die Datei einfach im Ordner unter diesen Namen \MetaTrader\EXPERTS\indicators speichern und die folgenden Änderungen machen:

1. Wählen Sie die gewünschten Farben der Indikatorselemente und ihre andere Parameter;
2. Schreiben Sie neue Eingabeparameter des Indikators ein, kopieren Sie einfach die Parameter aus dem benutzerdefinierten Indikator;
3. Schreiben Sie eine Formel für die Berechnung des Anfangsbars in der Funktion COUNT_begin() ein (in der Regel ist es ausreichend, die externe Variable des Indikators einzusetzen, die den Zeitraum oder die Summe dieser Variable mit der Variable bestimmt, welche die zusätzliche Glättung des Oszillators durchführt);
4. Schreiben Sie in der Zeile

digits()
  {
    return(2);
  }

den notwendigen Wert der Genauigkeit des Indikators ein. Wenn der Indikator sich von 0 bis 100 ändert, dann schreiben Sie Null ein, wenn der Indikator sich von 0 bis 1, dann schreiben Sie 2 ein (zwei Zeichen nach dem Komma!);
5. Stellen Sie die Indikatorswerte ein, die auf dem Chart unsichtbar sein werden;
6. Erstellen Sie einen Namen des Indikators;
7. Schreiben Sie den Aufruf zum benutzerdefinierten Indikator iCustom(). Danach kompilieren Sie den erhaltenden Code und der Indikator ist fertig!

Eine weitere Sache, die man dabei gern tun würde, ist ein wenig die Form des Oszillators zu glätten. Für diesen Fall müssen Sie einfach den Buchstaben "J" zum Namen der mqh-Datei hinzufügen: es war so

#include <3c_BB_Osc.mqh>

und es wird dann so

#include <3c_BBJ_Osc.mqh>

Bei der Kompilierung wird die Datei mit der JMA-Glättung des benutzerdefinierten Oszillators verwendet.


Der dreifarbige Indikator 3c_JJRSX2


Man könnte den Indikator weiter verbessern. Es wäre ziemlich bequem, einen weiteren einfarbigen schnellen JJRSX hinzuzufügen, der wird durchaus sinnvoll sein. Lassen Sie uns den Indikator ähnlich, wie im letzten Beispiel in zwei Teile teilen, platzieren wir einfach das Teil des Codes in der mqh-Datei, welches maximal die Wahrnehmung des Indikators vereinfacht (3c_BB_Osc2.mqh):

/*
Für  die Arbeit  des Indikators  müssen  die Daten     
JJMASeries.mqh
JurXSeries.mqh
PriceSeries.mqh
3c_BB_Osc2.mqh  
im Verzeichnis: MetaTrader\experts\include\ abgelegt werden 
JJRSX.mq4 
Heiken Ashi#.mq4
im Verzeichnis: MetaTrader\indicators\
*/
//+------------------------------------------------------------------+  
//|                                                    3c_JJRSX2.mq4 |
//|                               Copyright c 2006, Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+ 
#property copyright "Copyright c 2006, Nikolay Kositsin"
#property link      "farria@mail.redcom.ru"
//---- Darstellung des Indikators im getrennten Fenster
#property indicator_separate_window
//---- die Anzahl der Indikatorpuffers
#property indicator_buffers 8 
//---- die Farben des Indikators 
#property indicator_color1 Gold
#property indicator_color2 LimeGreen 
#property indicator_color3 Red
#property indicator_color4 Purple
//---- Bollinger Bands Farben
#property indicator_color5 Blue
#property indicator_color6 Blue
#property indicator_color7 Magenta
#property indicator_color8 Magenta
//---- die Dicke der Indikator-Linien
#property indicator_width1 1
#property indicator_width2 2
#property indicator_width3 1 
#property indicator_width4 1
//---- Der Stil der Mantellinie
#property indicator_style1 4
//---- Der Stil der Bollinger Bands Linie
#property indicator_style5 4
#property indicator_style6 4
#property indicator_style7 4
#property indicator_style8 4
//---- Die Parameter der horizontalen Ebenen des Indikators
#property indicator_level1  0.0
#property indicator_level2  0.8
#property indicator_level3 -0.8
//---- Eingabeparameter des Indikators
//---- Eingabeparameter des schnellen einfarbigen JJRSX
extern int  Length1 = 8;  // die Glättungstiefe JurX des Indikators
// die Glättungstiefe JJMA des erhaltenden Indikators
extern int  Smooth1 = 3;
// Der Parameter, der sich im Bereich zwischen -100 ... +100 ändert, 
//beeinflusst auf die Qualität der vorübergehenden Glättungsprozesse
extern int  Phase1 = 100;
//Die Wahl der Preise, nachdem der Indikator berechnet wird 
extern int Input_Price_Customs1 = 0;
/*(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED,
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW,
11-Heiken Ashi Low, 12-Heiken Ashi High,  13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
//---- Eingabeparameter des langsamen dreifarbigen JJRSX
extern int  Length2 = 40;  // die Glättungstiefe JurX des Indikators
// die Glättungstiefe JJMA des erhaltenden Indikators
extern int  Smooth2 = 12;
// Der Parameter, der sich im Bereich zwischen -100 ... +100 ändert, 
// beeinflusst auf die Qualität der vorübergehenden Glättungsprozesse
extern int  Phase2 = 100;
// Die Wahl der Preise, nachdem der Indikator berechnet wird 
extern int Input_Price_Customs2 = 0;
/*(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED,
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW,
11-Heiken Ashi Low, 12-Heiken Ashi High,  13-Heiken Ashi Open, 
14-Heiken Ashi Close.)*/
//---- Der Zeichenstil der horizontalen Ebenen der Indikatoren
extern int    Levels_Style = 3;         // Der Linienslil der Ebenen
extern int    Levels_Width = 0;         // Die Dicke der Ebenenlinien
extern color  Levels_Color = SlateGray; // Die Farbe der Ebenenlinien 
//---- Eingabe der Funktion COUNT_begin(),um die Nummer des Bars zu berechnen, 
// von der der Indikator entsteht und wird 
// Bollinger Bands berechnet 
int COUNT_begin(){int count_begin=2*Length2+30;return(count_begin);}
//---- Eingabe der Funktion digits() für die Einstellung der Genauigkeit der Format 
//(Die Anzahl der Zeichen nach dem dezimalen Komma) um die Indikatorswerte zu 
//visualisieren 
int digits(){return(2);}
//---- Die Einstellung der Indikator-Werten, die im Chart unsichtbar werden 
int EmptyValue=0.0;
//---- Die Definition den Namen des Indikators 
string Label = "JJRSX";
 
//---- Das Hinzufügen des Haupttextes des Indikators zu seinem Text
#include <3c_BB_Osc2.mqh> 
//---- Eingabe der Funktion INDICATOR1
//---- Der Aufruf zum Anfangsindikator für die Erhaltung der Anfangswerte
double INDICATOR1(int INDICATOR1.bar)
 {
  return(iCustom( NULL, 0, "JJRSX", Length1, Smooth1, Phase1, 
         Input_Price_Customs1, 0, INDICATOR1.bar) );
 }
//---- Eingabe der Funktion INDICATOR2
//---- Der Aufruf zum Anfangsindikator für die Erhaltung der Anfangswerte
double INDICATOR2(int INDICATOR2.bar)
 {
  return(iCustom( NULL, 0, "JJRSX", Length2, Smooth2, Phase2, 
         Input_Price_Customs2, 0, INDICATOR2.bar) );
 }
//---- --------------------------------------------------------------+

Der Indikatorcode ist nicht viel komplizierter geworden, nun sind da zwei Aufrufe zum benutzerdefinierten Indikator JJRSX und zwei Gruppen der externen Indikatorparameter, die gleich der Anzahl vom Indikator JJRSX sind. Ich denke, dass es keine Probleme bei der Verwendung dieser Indikatoren als Vorlagen für den Aufbau der ähnlichen Charts geben sollen, die basierend auf einigen anderen Oszillatoren sein werden.



Die dreifarbigen gleitenden Mittelwerte


Lassen Sie uns nun mit den Schreibensweisen der dreifarbigen Movings zu beschäftigen. Auf dem ersten Blick könnten wir einen gleichen Code damit schreiben, wie es im ersten Beispiel ist. Aber ein solches Chart hat einen Nachteil: wenn die Movingsrichtung sich an jedem Bar ändert, werden Farben in einander aufgelegt, was nicht normal ist. Die einzige Weise, diesen Nachteil zu vermeiden - ist die Verwendung drei zusätzlichen Puffers! Meiner Meinung nach machen drei zusätzlichen Puffers einen solchen Indikator nicht sperrig, wenn der übermäßige Code in einer mqh-Datei gesetzt wird. Im Bezug auf das Schreiben einer dreifarbigen Moving haben wir eine ähnliche Situation, wie in den vorherigen Beispielen:

/*
Für  die Arbeit  des Indikators  müssen  die Daten 
JJMASeries.mqh  
PriceSeries.mqh 
3Color.mqh
im Verzeichnis: MetaTrader\experts\include\ abgelegt werden 
J2JMA.mq4 
in das Verzeichnis: MetaTrader\experts\indicators\
*/
//+------------------------------------------------------------------+  
//|                                                     3c_J2JMA.mq4 | 
//|                           Copyright c 2006,     Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+  
#property copyright "Copyright c 2006, Nikolay Kositsin"
#property link "farria@mail.redcom.ru" 
//---- Darstellung des Indikators im Hauptfenster
#property indicator_chart_window 
//---- die Anzahl der Indikatorpuffers
#property indicator_buffers 6
//---- die Farben des Indikators
#property indicator_color1 Blue
#property indicator_color2 Blue
#property indicator_color3 Red
#property indicator_color4 Red 
#property indicator_color5 Gray
#property indicator_color6 Gray
//---- Eingabeparameter des Indikators
extern int Length1 = 5;   // Die   erste  Glättungstiefe 
extern int Length2 = 5;   // Die  zweite Glättungstiefe 
// Der Parameter der ersten Glättung, der sich im Bereich zwischen -100 ... +100 ändert,
//beeinflusst auf die Qualität des vorübergehenden Prozess; 
extern int Phase1  = 100;
// Der Parameter der zweiten Glättung, der sich im Bereich zwischen -100 ... +100 ändert, 
//beeinflusst auf die Qualität des vorübergehenden Prozess; 
extern int Phase2  = 100;
/* Die Wahl der Preise, nach den der Indikator berechnet wird 
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED,
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High,  13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int Input_Price_Customs = 0;
//---- Eingabe der Funktion digits() für die Einstellung der Genauigkeit der Format 
// (Die Anzahl der Zeichen nach dem dezimalen Komma) um die Indikatorswerte zu
// visualisieren 
int digits(){return(Digits);}
//---- Eingabe der Funktion COUNT_begin(),um die Nummer des Bars zu berechnen, 
//von der der Indikator entsteht
int COUNT_begin(){return(60);}
//---- Die Einstellung der Indikator-Werten, die im Chart unsichtbar werden 
int  EmptyValue=0;
//---- Label für den Indikator
string Label="J2JMA";                 
//---- Das Hinzufügen des Haupttextes des Indikators zu seinem Text
#include <3Color.mqh>
//---- Eingabe der Funktion INDICATOR
//---- Der Aufruf zum Anfangsindikator für die Erhaltung der Anfangswerte
double INDICATOR(int INDICATOR.bar)
 {
  return(iCustom(NULL,0,"J2JMA",Length1,Length2,Phase1,Phase2,0,
         Input_Price_Customs,0,INDICATOR.bar) );
 }
//---- --------------------------------------------------------------+

Es sollte beobachtet werden, dass es in der Funktion für die Movings und auch für die Einstellung der Genauigkeit des Formats nichts geändert werden soll

int digits()
  {
    return(Digits);
  }

! Wenn die Moving, die Sie dreifarbig machen wollen, ist unsicher (höckerig), dann kann es leicht geglättet werden. Dafür Fügen Sie einfach in der Zeile

#include <3Color.mqh>

den Buchstaben "J" und wir bekommen

#include <3ColorJ.mqh>



Die Vorlagen der Indikatoren, die auf der Basis von größeren Timeframes konstruiert wurden


Zum Schluss gebe ich noch ein Paar Vorlagen der Indikatoren, die auf der Basis von einem anderen noch größeren Timeframe konstruiert wurden, sie können auch basierend auf einer Moving oder Oszillator gebaut werden:

//----+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ 
//Version  July 1, 2006                                              |
//Editing   Nikolay Kositsin  15.06.2006  farria@mail.redcom.ru      |
//----+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ 
/*
Der Aufbau einer Moving am aktuellen Timeframe, die basierend auf Werten eines größeren Timeframe  
sein wird. Vorsicht!!! Die Indikatorwerte werden nicht 
auf  dem  letzten Bar neuberechnet, sondern  auf der Anzahl der Bars, die  einer 
Kerze von einem größeren Timeframe gleichwertig ist!
 
Für  die Arbeit  des Indikators  müssen  die Daten 
JJMASeries.mqh  
PriceSeries.mqh 
HTF.mqh
im Verzeichnis: MetaTrader\experts\include\ abgelegt werden 
J2JMA.mq4
Heiken Ashi#.mq4
im Verzeichnis: MetaTrader\indicators\
*/
//+------------------------------------------------------------------+ 
//|                                                    J2JMA_htf.mq4 |
//|                            Copyright c 2005, GS  Conversion only |
//|                    http://www.gustis.narod.ru/;     gsb51@mail.ru |
//+------------------------------------------------------------------+ 
#property copyright "  Copyright c 2005, GS  Conversion only"
#property link      " http://www.gustis.narod.ru/;     gsb51@mail.ru"
//---- Darstellung des Indikators im Hauptfenster
#property indicator_chart_window 
//---- die Anzahl der Indikatorpuffers
#property indicator_buffers  4
//---- die Farben des Indikators
#property indicator_color1 BlueViolet
#property indicator_color2 Lime
#property indicator_color3 Red
#property indicator_color4 Gray
//---- die Dicke der Indikator-Linie
#property indicator_width1 3
#property indicator_width2 1
#property indicator_width3 1
#property indicator_width4 3
//---- Der Linienstil des Indikators
#property indicator_style1 0
//---- Eingabeparameter des Indikators
//Die Parameter des benutzerdefinierten Indikators iCustom
extern int Length1 = 5;   // Die   erste  Glättungstiefe 
extern int Length2 = 5;   // Die  zweite Glättungstiefe 
// Der Parameter der ersten Glättung, der sich im Bereich zwischen -100 ... +100 ändert, 
//beeinflusst auf die Qualität des vorübergehenden Prozess; 
extern int Phase1  = 100;
// Der Parameter der zweiten Glättung, der sich im Bereich zwischen -100 ... +100 ändert, 
//beeinflusst auf die Qualität des vorübergehenden Prozess; 
extern int Phase2  = 100;
//Die Wahl der Preise, nachdem der Indikator berechnet wird 
extern int Input_Price_Customs = 0;
/*
//---- Eingabeparameter des Indikators HTF +--------------------------------------------+
extern int  TFrame_Period = 240; // Die große Periode in Minuten
// Glättung der erhaltenden Moving. Der optimalste Wert  
// wird das Verhältnis der Perioden des größeren Timeframes zur Chartsperiode 
extern int         Smooth = 48;
extern bool Trend_Visible = true;// Die Visualisierung der Trendanzeige
// Die minimale Geschwindigkeit der Moving, wird als Trend betrachtet
extern int  Trend_Minimum = 5;
extern int         Shift  = 0;   // Die Verschiebung des Indikators entlang der Zeitachse 
*/
//---- Eingabe der Funktion digits() für die Einstellung der Genauigkeit der Format 
// (Die Anzahl der Zeichen nach dem dezimalen Komma) um die Indikatorswerte zu 
// visualisieren 
int digits(){return(Digits);}
//---- Die Einstellung der Indikator-Werten, die im Chart unsichtbar werden 
int EmptyValue=0;
string Label="J2JMA";                 
//---- Das Hinzufügen des Haupttextes des Indikators zu seinem Text
#include <HTF.mqh>
//---- Eingabe der Funktion INDICATOR
//---- Der Aufruf zum Anfangsindikator für die Erhaltung der Anfangswerte
double INDICATOR(int INDICATOR.bar)
 {
  return(iCustom(NULL,TFrame_Period,"J2JMA",Length1,Length2,Phase1,Phase2,
         0,Input_Price_Customs,0,INDICATOR.bar) );
 }
//---- -----------------------------------------------------------+

Für die normale Arbeit der Moving sollten beide Charts geöffnet werden! Beachten Sie auch, dass alle Historydaten bis zum letzten Bar auf den beiden Charts von einem Broker sein müssen!

Anlässlich der letzten Moving sollte darauf hingewiesen werden, dass trotz ihrer scheinbaren indikativ Trendsrichtung, ist es nicht vernünftig, diese Moving zu einem Expert Advisor hinzuzufügen. Egal, welche Schätze die Aktion im Tester versprechen könnte, es wird nicht in der Realität passieren! Die Moving wird nicht auf dem letzten Bar des aktuellen Timeframes neuberechnet, sondern auf dem letzten Bar des größeren Timeframes! Mehrere Versuche dieser Sisyphusarbeit, wie erwartet, brachten keine Ergebnisse!


In diesem Fall sollten wir den Hauptpunkt des Algorithmus erklären, der auf der Grundlage dieses Indikators liegt. Die Werte selbst, auf deren Grundlage der Indikator gebaut wird, werden von den Bars des größeren Timeframes genommen. Nachdem wie die Glättung der Preisreihe berechnet wird, werden die erhaltenden Werte auf einen kleineren Timeframe übertragen, die fehlenden vorübergehenden Werte des kleineren Timeframes werden durch das Verfahren der linearen Interpolation hinzugefügt. Aber von daher, dass das Chart die Form einer polygonalen Linie hat, haben wir natürlich Lust, die Linie zu glätten. Das wurde eben in diesem Indikator gemacht!

Nach einer solchen Transformationen bekommt diese Kurve eine ziemlich anmutige Form, aber die wird immer noch um die Anzahl der Bars vom kleineren Timeframe neuberechnet, die einer Kerze von einem größeren Timeframe gleichwertig sind. Schließlich möchte ich noch dazu hinzufügen, dass die Fähigkeit, ein übermäßiger Programmcode in mqh-Datein zu setzen, ist besonders praktisch nicht nur beim Aufbau der Indikatoren, sondern auch Experten. Es ermöglicht eine riesige Menge Arbeit zu vereinfachen, und es macht von der Programmierung eine faszinierende und interessante Arbeit.

/*
//----+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ 
//Version  July 1, 2006                                              |
Editing   Nikolay Kositsin  15.06.2006  farria@mail.redcom.ru        |
//----+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ 
Der Aufbau einer Moving am aktuellen Timeframe, die basierend auf Werten eines größeren Timeframe  
sein wird. Vorsicht!!! Die Indikatorwerte werden nicht 
auf  dem  letzten Bar neuberechnet, sondern  auf der Anzahl der Bars, die  einer 
Kerze von einem größeren Timeframe gleichwertig ist!
 
Für  die Arbeit  des Indikators  müssen  die Daten 
JJMASeries.mqh  
PriceSeries.mqh 
HTF_Channal.mqh
im Verzeichnis: MetaTrader\experts\include\ abgelegt werden 
J2JMA.mq4
Heiken Ashi#.mq4
im Verzeichnis: MetaTrader\indicators\
*/
//+------------------------------------------------------------------+
//|                                            J2JMA channel_htf.mq4 |
//|                            Copyright c 2005, GS  Conversion only |
//|                    http://www.gustis.narod.ru/;     gsb51@mail.ru |
//+------------------------------------------------------------------+
#property copyright "  Copyright c 2005, GS  Conversion only"
#property link      " http://www.gustis.narod.ru/;     gsb51@mail.ru"
//---- Darstellung des Indikators im Hauptfenster
#property indicator_chart_window 
//---- die Anzahl der Indikatorpuffers
#property indicator_buffers  6
//---- die Farben des Indikators
#property indicator_color1 BlueViolet
#property indicator_color2 Gray
#property indicator_color3 Gray
#property indicator_color4 Lime
#property indicator_color5 Red
#property indicator_color6 Gray
//---- die Dicke der Indikator-Linie
#property indicator_width1 3
#property indicator_width2 0
#property indicator_width3 0
#property indicator_width4 1
#property indicator_width5 1
#property indicator_width6 1
//---- Der Linienstil des Indikators
#property indicator_style1 0
#property indicator_style2 4
#property indicator_style3 4
//---- Eingabeparameter des Indikators
//Die Parameter des benutzerdefinierten Indikators iCustom
extern int Length1 = 5;   // Die   erste  Glättungstiefe 
extern int Length2 = 5;   // Die  zweite Glättungstiefe 
// Der Parameter der ersten Glättung, der sich im Bereich zwischen -100 ... +100 ändert, 
//beeinflusst auf die Qualität des vorübergehenden Prozess; 
extern int Phase1  = 100;
// Der Parameter der zweiten Glättung, der sich im Bereich zwischen -100 ... +100 ändert, 
//beeinflusst auf die Qualität des vorübergehenden Prozess; 
extern int Phase2  = 100;
//Die Wahl der Preise, nachdem der Indikator berechnet wird 
extern int Input_Price_Customs = 0;
/*
//---- Eingabeparameter des Indikators HTF +--------------------------------------------+
extern int  TFrame_Period = 240; // Die große Periode in Minuten
extern int         Smooth = 48;  // Glättung der erhaltenden Moving
extern bool Trend_Visible = true;// Die Visualisierung der Trendanzeige
// Die minimale Geschwindigkeit der Moving, wird als Trend betrachtet
extern int  Trend_Minimum = 5;
extern int         Shift  = 0;   // Die Verschiebung des Indikators entlang der Zeitachse 
*/
//---- Eingabe der Funktion digits() für die Einstellung der Genauigkeit der Format 
// (Die Anzahl der Zeichen nach dem dezimalen Komma) um die Indikatorswerte zu 
// visualisieren 
int digits(){return(Digits);}
//---- Die Einstellung der Indikator-Werten, die im Chart unsichtbar werden 
int EmptyValue=0;
string Label="J2JMA";
//---- Das Hinzufügen des Haupttextes des Indikators zu seinem Text
#include <HTF_channel.mqh>
//---- Eingabe der Funktion INDICATOR
//---- Der Aufruf zum Anfangsindikator für die Erhaltung der Anfangswerte
double INDICATOR(int INDICATOR.bar)
 {
  return(iCustom(NULL,TFrame_Period,"J2JMA",Length1,Length2,Phase1,Phase2,
         0,Input_Price_Customs,0,INDICATOR.bar) );
 }
//-------------------------------------------------------------------+


Fazit

In diesem Artikel haben wir die Beispiele des Aufbaus der dreifarbigen Charts und dreifarbigen Movings betrachtet, welche basierend auf den verfügbaren Code-Fragmente sind, die in mqh-Dateien gesetzt wurden. Mit Verwendung des oben beschriebenen Aufbauverfahrens der dreifarbigen Indikatoren kann man unter Verwendung der angegebenen Beispiele als Vorlagen ähnliche Indikatoren bauen, die basierend auf beliebiger Movings und Oszillatoren sein werden. Mit dieser Methode können Sie auch die Indikatoren bauen, welche die Daten aus einem anderen Timeframe zeigen werden, die können auch sehr praktisch sein, wenn sie auf einem Chart platziert sind, so dass man Prozesse beobachten kann, die in verschiedenen Zeitskalen gleichzeitig laufen.

Das Archiv NK_library.zip enthält mehr als hunderte Indikatoren, die mit verschiedenen Algorithmen der Glättung geschrieben wurden. Diese Indikatoren sind mehr als genug, um die erwähnten Beispiele aus dem Artikel zu verwenden, und dadurch ähnliche Indikatoren zu schreiben. Alle Indikatoren aus dem Archiv mit diesen Versionen der Glättungsfunktionen funktionieren mit Experten ohne Fehler. Die Indikatoren aus dem Archiv muss im Ordner des Client-Terminals: \MetaTrader\EXPERTS\indicators gespeichert werden. Die Glättungsfunktionen und die gesetzten Fragmenten des Prorammcodes werden im Archiv des Ordners INCLUDE sein. Den ganzen Inhalt dieses Ordners muss im Ordner des Client-Terminals: \MetaTrader\EXPERTS\INCLUDE gespeichert werden.