English Русский 中文 Español 日本語 Português 한국어 Français Italiano Türkçe
Unterschiedliche Zeichnungsstile in MQL5

Unterschiedliche Zeichnungsstile in MQL5

MetaTrader 5Indikatoren | 11 Januar 2016, 14:20
1 372 0
Loong
Loong

Einleitung

MQL4 umfasst 6 Zeichnungsstile. In MQL5 sind es bereits 18. Aus diesem Grund ist ein Beitrag zur Präsentation der Zeichnungsstile von MQL5 durchaus angebracht.

Im Folgenden werden daher die Zeichnungsstile in MQL5 im Einzelnen betrachtet. Darüber hinaus erzeugen wir einen Indikator zur Demonstration, wie man diese Zeichnungsstile nutzt und die graphische Darstellung (Plot) verfeinert.

Zeichnungsstile

In MQL4 gibt es kein Plot-Konzept. Der erste Parameter der SetIndexStyle() Funktion, der Zeilen-Index, entspricht hier jedoch dem Plot-Index.

void SetIndexStyle( int index, int type, int style=EMPTY, int width=EMPTY, color clr=CLR_NONE)
// The index is Line index.

MQL4 umfasst nur 6 Zeichnungsstile: DRAW_ZIGZAG benötigt zwei Buffer, die anderen 5 Zeichnungsstile nur je einen.

Daher kann der erste Parameter der SetIndexStyle() Funktion in MQL4, leicht als Buffer-Index verstanden werden. Wenn man DRAW_ZIGZAG nicht verwendet, macht das auch nichts. Ach, haben Sie übrigens die in DRAW_ZIGZAG implementierten MQL4-Indikatoren entdeckt? Ich habe sie nicht gefunden. (ZigZag.mq4 ist in DRAW_SECTION implementiert).

Vergleichen wir nun die Zeichnungsstile von MQL4 und MQL5: 

Tabelle 1 Liste der Zeichnungsstile in MQL4 und MQL5

Tabelle 1 Liste der Zeichnungsstile in MQL4 und MQL5

Was erkennt man hier? In MQL5 sind 12 Zeichnungsstile hinzugekommen, und es gibt 8 neue Zeichnungsstile mit einem Farb-Buffer. Er kann nicht so vage wie zuvor verwendet werden, da das Konzept der Zeilen-Indizierung zu leicht verwirrt.

Daher bietet Ihnen MQL5 einen Plot, der der Zeile in MQL4 entspricht, die Sie im Indikatorfenster zeichnen können.

Man kann in MQL5 nicht nur die Zeile zeichnen, daher ist der Name bei dem Plot exakter.

Buffer-Muster

Hier wird das Konzept des Buffer-Musters definiert. Das Buffer-Muster eines Zeichnungsstil erfordert die Buffer-Nummer, seine Art und Anordnung.

Das Buffer-Muster eines Zeichnungsstils lässt sich mit einem String darstellen: Buchstabe D für DataBuffer, Buchstabe C für ColorBuffer, von links nach rechts als Entsprechung der Indexnummer von klein und groß.

Das Buffer-Muster der MQL5 Zeichnungsstile wird in der folgenden Tabelle dargestellt:

Tabelle 2 Buffer-Muster der Zeichnungsstile in MQL5

Tabelle 2 Buffer-Muster der Zeichnungsstile in MQL5

Wenn Ihre Indikatoren mehrere Plots enthalten, folgt die Anordnung der Buffer-Muster dieser Indikatoren der Anordnung der Buffer-Muster dieser Plots. Wenn SetIndexBuffer() aufgerufen wird, sollte Buffer-Index also in aufsteigender Reihenfolge sein.

Wenn Sie zur Speicherung der für die Berechnung notwendigen, temporären Daten zusätzliche Buffer verwenden, sollten diese Hilfs-Buffer an SetIndexBuffer() gebunden und erst nach allen Buffern, die angezeigt werden können, platziert sein.

Sonst ...

Zur Demonstration des Buffer-Musters habe ich einen Indikator veröffentlicht: DemoBufferPattern. Probieren Sie es selbst aus.

Der Indikator vom Typ DemoDraw

Sehen wir uns nun den DemoDrawTyp Indikator an.


Abb. 3 Indikator Eingabe-Parameter

Abb. 1 Indikator Eingabe-Parameter

Abb. 4 Indikator Eingabe-Parameter (fortgesetzt)

Abb. 2 Indikator Eingabe-Parameter (fortgesetzt)

Damit können Sie jeden Zeichnungsstil aus dem "Eingabe"-Tab auswählen und die verschiedenen Eigenschaften des Plots einstellen.

Abb. 5 Liste der Zeichnungsstile

Abb. 3 Liste der Zeichnungsstile

Dazu müssen wir für jedes Merkmal eine Eingabe-Variable festlegen und eine Funktion implementieren, die die Angemessenheit dieser Variablen prüft.

Da die Eingabe-Variablen im Programm nicht modifiziert werden können, muss zudem auch ein Set an globalen Variablen definiert werden, das den geprüften Eingabe-Variablenwert besitzt.

//--- input parameters
input ENUM_DRAW_TYPE InpDrawType    = DRAW_LINE;
input ENUM_LINE_STYLE InpLineStyle  = STYLE_SOLID;
input bool InpShowData        = true;
input uchar InpArrow          = 159;
input int InpArrowShift       = -10;
input int InpDrawBegin        = 10;
input int InpShift            = 10;
input int InpLineWidth        = 1;
input int InpColorNum         = 60;
input color InpPlotColor      = RoyalBlue;
input double InpEmptyValue    = 0.0;
input string InpLabel         = "Value";
input bool InpTestEmptyValue  = false;

//Note: Variables declared at global level must not be mixed up with the client terminal 
//global variables that can be accessed using the GlobalVariable...() functions.
//--- you can not change input parameters in code, so you need Global Variables
ENUM_DRAW_TYPE iDrawType      = DRAW_LINE;
ENUM_LINE_STYLE iLineStyle    = STYLE_SOLID;
bool bShowData       = true;
uchar uArrow         = 181;
int iArrowShift      = -10;
int iDrawBegin       = 10;
int iShift           = 10;
int iLineWidth       = 1;
int iColorNum        = 60;
color iPlotColor     = RoyalBlue;
string sLabel        = "";
bool bTestEmptyValue = false;
double dEmptyValue   = EMPTY_VALUE;

//+------------------------------------------------------------------+
//| check input parameters.                                          |
//+------------------------------------------------------------------+
bool checkInput()
  {
   if(InpDrawType<DRAW_NONE || InpDrawType>DRAW_COLOR_CANDLES) return(false);
   else iDrawType = InpDrawType;
   if(InpLineStyle<STYLE_SOLID || InpLineStyle>STYLE_DASHDOTDOT) return(false);
   else iLineStyle = InpLineStyle;
   bShowData   = InpShowData;
   uArrow      = InpArrow;    //if uArrow>255, MQL5 will set Arrow as uArrow%256
   iArrowShift = InpArrowShift;
   iDrawBegin  = InpDrawBegin;
   iShift      = InpShift;
   iLineWidth  = InpLineWidth;
   iColorNum   = InpColorNum;
   iPlotColor  = InpPlotColor;
   //if(InpEmptyValue<=0.0) dEmptyValue=0.0;
   //else dEmptyValue=EMPTY_VALUE;
   dEmptyValue = InpEmptyValue;  // It may be not 0.0 or EMPTY_VALUE
   sLabel      = InpLabel;
   bTestEmptyValue = InpTestEmptyValue;
   return(true);
  }

Abb. 4-21 zeigen die Beispiele aller 18 Zeichnungsstile:

=""

Abb. 4 Beispiel für Zeichnungsstil DRAW_NONE

=""

Abb. 5 Beispiel für Zeichnungsstil DRAW_LINE

=""

Abb. 6 Beispiel für Zeichnungsstil DRAW_HISTOGRAM

=""

Abb. 7 Beispiel für Zeichnungsstil DRAW_ARROW

=""

Abb. 8 Beispiel für Zeichnungsstil DRAW_SECTION

=""

Abb. 9 Beispiel für Zeichnungsstil DRAW_HISTOGRAM2

=""

Abb. 10 Beispiel für Zeichnungsstil DRAW_FILLING

=""

Abb. 11 Beispiel für Zeichnungsstil DRAW_ZIGZAG

=""

Abb. 12 Beispiel für Zeichnungsstil DRAW_BARS

=""

Abb. 13 Beispiel für Zeichnungsstil DRAW_CANDLES

=""

Abb. 14 Beispiel für Zeichnungsstil DRAW_COLOR_LINE

=""

Abb. 15 Beispiel für Zeichnungsstil DRAW_COLOR_HISTOGRAM

=""

Abb. 16 Beispiel für Zeichnungsstil DRAW_COLOR_ARROW

=""

Abb. 17 Beispiel für Zeichnungsstil DRAW_COLOR_SECTION

=""

Abb. 18 Beispiel für Zeichnungsstil DRAW_COLOR_HISTOGRAM2

=""

Abb. 19 Beispiel für Zeichnungsstil DRAW_COLOR_ZIGZAG

=""

Abb. 20 Beispiel für Zeichnungsstil DRAW_COLOR_BARS

=""

Abb. 21 Beispiel für Zeichnungsstil DRAW_COLOR_CANDLES


Wie man mit leeren Werten umgeht

Die verschiedenen Zeichnungsstile zeigen die unterschiedlichen Charts, also brauchen sie die verschiedenen Buffer-Muster.

Der größte Unterschied bei all diesen Zeichnungsstilen besteht, neben den verschiedenen Buffer-Mustern, im Umgang mit leeren Werten.

Also habe ich einen Eingabe-Parameter hinzugefügt, mit dem man einen leeren Wert einfügen kann. Da dieser Indikator den DrawType demonstrieren soll, ist dies die Gelegenheit, einen Teil des Null-Werts einzurichten.

Basierend auf dem Unterschied im Umgang mit leeren Werten, lassen sich alle Zeichnungsstile in drei Kategorien unterteilen:

Tabelle 3 Zeichnungsstile, in Kategorien unterteilt

Tabelle 3. Zeichnungsstile, in Kategorien unterteilt

Abb. 22-29 zeigen die entsprechenden Beispiele.

Abb. 22 Beispiel für Zeichnungsstil DRAW_LINE (mit leeren Werten)

Abb. 23 Beispiel für Zeichnungsstil DRAW_SECTION (mit leeren Werten)

Abb. 24 Beispiel für Zeichnungsstil DRAW_HISTOGRAM2 (mit leeren Werten)

Abb. 25 Beispiel für Zeichnungsstil DRAW_BARS (mit leeren Werten)

Abb. 26 Beispiel für Zeichnungsstil DRAW_FILLING (mit leeren Werten)

Abb. 27 Beispiel für Zeichnungsstil DRAW_ZIGZAG (mit leeren Werten)

Abb. 28 Beispiel für Zeichnungsstil DRAW_COLOR_ARROW (mit leeren Werten)

Abb. 29 Beispiel für Zeichnungsstil DRAW_COLOR_CANDLES (mit leeren Werten)

 

Der komplette Quellcode des Indikators:

//+------------------------------------------------------------------+
//|                                                 DemoDrawType.mq5 |
//|                             Copyright 2010, Loong@forum.mql4.com |
//|                             http://login.mql5.com/en/users/Loong |
//+------------------------------------------------------------------+
#property copyright "2010, Loong@forum.mql4.com"
#property link      "http://login.mql5.com/en/users/Loong"
#property version   "1.00"

//#property indicator_chart_window
#property indicator_separate_window // in order to more clearly show
#property indicator_plots   1 //must set, can be bigger than necessary, can not be bigger than indicator_buffers
#property indicator_buffers 5 //must set, can be bigger than necessary
//+------------------------------------------------------------------+
//| DrawType struct, record info about DrawType and Buffer-Pattern   |
//+------------------------------------------------------------------+
struct SLoongDrawType                       // Draw Type
  {
   ENUM_DRAW_TYPE    eDrawType;             // enum of Draw Type
   int               iDrawType;             // value of Draw Type, only used to look
   int               iNumBufferData;        // number of Data Buffer
   int               iNumBufferColor;       // number of Color Buffer
   string            sDrawType;             // string of Draw Type
   string            sDrawTypeDescription;  // string of Draw Type Description, copy from document
  };
//+------------------------------------------------------------------+
//| const array, record info about DrawType and Buffer-Pattern       |
//+------------------------------------------------------------------+
const SLoongDrawType caDrawType[]=
  {
     { DRAW_NONE,              0,    1,    0,    "DRAW_NONE",             "Not drawn" },
     { DRAW_LINE,              1,    1,    0,    "DRAW_LINE",             "Line" },
     { DRAW_HISTOGRAM,         2,    1,    0,    "DRAW_HISTOGRAM",        "Histogram from the zero line" },
     { DRAW_ARROW,             3,    1,    0,    "DRAW_ARROW",            "Drawing arrows" },
     { DRAW_SECTION,           4,    1,    0,    "DRAW_SECTION",          "Section" },
     { DRAW_HISTOGRAM2,        5,    2,    0,    "DRAW_HISTOGRAM2",       "Histogram of the two indicator buffers" },
     { DRAW_ZIGZAG,            6,    2,    0,    "DRAW_ZIGZAG",           "Style Zigzag allows vertical section on the bar" },
     { DRAW_FILLING,           7,    2,    0,    "DRAW_FILLING",          "Color fill between the two levels" },
     { DRAW_BARS,              8,    4,    0,    "DRAW_BARS",             "Display as a sequence of bars" },
     { DRAW_CANDLES,           9,    4,    0,    "DRAW_CANDLES",          "Display as a sequence of candlesticks" },
     { DRAW_COLOR_LINE,       10,    1,    1,    "DRAW_COLOR_LINE",       "Multicolored line" },
     { DRAW_COLOR_HISTOGRAM,  11,    1,    1,    "DRAW_COLOR_HISTOGRAM",  "Multicolored histogram from the zero line" },
     { DRAW_COLOR_ARROW,      12,    1,    1,    "DRAW_COLOR_ARROW",      "Drawing multicolored arrows" },
     { DRAW_COLOR_SECTION,    13,    1,    1,    "DRAW_COLOR_SECTION",    "Multicolored section" },
     { DRAW_COLOR_HISTOGRAM2, 14,    2,    1,    "DRAW_COLOR_HISTOGRAM2", "Multicolored histogram of the two indicator buffers" },
     { DRAW_COLOR_ZIGZAG,     15,    2,    1,    "DRAW_COLOR_ZIGZAG",     "Multicolored ZigZag" },
     { DRAW_COLOR_BARS,       16,    4,    1,    "DRAW_COLOR_BARS",       "Multicolored bars" },
     { DRAW_COLOR_CANDLES,    17,    4,    1,    "DRAW_COLOR_CANDLES",    "Multicolored candlesticks" }
  };

//--- input parameters
input ENUM_DRAW_TYPE InpDrawType    = DRAW_LINE;
input ENUM_LINE_STYLE InpLineStyle  = STYLE_SOLID;
input bool InpShowData        = true;
input uchar InpArrow          = 159;
input int InpArrowShift       = -10;
input int InpDrawBegin        = 10;
input int InpShift            = 10;
input int InpLineWidth        = 1;
input int InpColorNum         = 60;
input color InpPlotColor      = RoyalBlue;
input double InpEmptyValue    = 0.0;
input string InpLabel         = "Value";
input bool InpTestEmptyValue  = false;

//Note: Variables declared at global level must not be mixed up with the client terminal
// global variables that can be accessed using the GlobalVariable...() functions.
//--- you can not change input parameters in code, so you need Global Variables
ENUM_DRAW_TYPE iDrawType      = DRAW_LINE;
ENUM_LINE_STYLE iLineStyle    = STYLE_SOLID;
bool bShowData       = true;
uchar uArrow         = 181;
int iArrowShift      = -10;
int iDrawBegin       = 10;
int iShift           = 10;
int iLineWidth       = 1;
int iColorNum        = 60;
color iPlotColor     = RoyalBlue;
string sLabel        = "";
bool bTestEmptyValue = false;
double dEmptyValue   = EMPTY_VALUE;

//--- indicator buffers
double DC[];   // color buffer
double D1[];   //  data buffer
double D2[];
double D3[];
double D4[];
//+------------------------------------------------------------------+
//| check input parameters.                                          |
//+------------------------------------------------------------------+
bool checkInput()
  {
   if(InpDrawType<DRAW_NONE || InpDrawType>DRAW_COLOR_CANDLES) return(false);
   else iDrawType=InpDrawType;
   if(InpLineStyle<STYLE_SOLID || InpLineStyle>STYLE_DASHDOTDOT) return(false);
   else iLineStyle=InpLineStyle;
   bShowData   =InpShowData;
   uArrow=InpArrow;    //if uArrow>255, MQL5 will set Arrow as uArrow%256
   iArrowShift = InpArrowShift;
   iDrawBegin  = InpDrawBegin;
   iShift      = InpShift;
   iLineWidth  = InpLineWidth;
   iColorNum   = InpColorNum;
   iPlotColor  = InpPlotColor;
//if(InpEmptyValue<=0.0) dEmptyValue=0.0;
//else dEmptyValue=EMPTY_VALUE;
   dEmptyValue=InpEmptyValue;  // It may be not 0.0 or EMPTY_VALUE
   sLabel=InpLabel;
   bTestEmptyValue=InpTestEmptyValue;
   return(true);
  }
//+------------------------------------------------------------------+
//| color well-distributed                                           |
//+------------------------------------------------------------------+
int ColorInc6section(int i,int iBase=63,int iI=0xFF)
  {
   int id  = (int)MathFloor((double)iBase/6.0);
   int ip  = (int)MathFloor((double)iI/id);
   int MA_Rinc=0;
   int MA_Ginc=0;
   int MA_Binc=0;
   color iColor=0;
   if(i<=0)        {iColor =       iI; MA_Rinc=0; MA_Ginc=0; MA_Binc=0;}
   else if(i<1*id) {iColor =       iI; MA_Rinc=  0; MA_Ginc= ip; MA_Binc=  0;}
   else if(i<2*id) {iColor =   257*iI; MA_Rinc=-ip; MA_Ginc=  0; MA_Binc=  0;}
   else if(i<3*id) {iColor =   256*iI; MA_Rinc=  0; MA_Ginc=  0; MA_Binc= ip;}
   else if(i<4*id) {iColor = 65792*iI; MA_Rinc=  0; MA_Ginc=-ip; MA_Binc=  0;}
   else if(i<5*id) {iColor = 65536*iI; MA_Rinc= ip; MA_Ginc=  0; MA_Binc=  0;}
   else if(i<6*id) {iColor = 65537*iI; MA_Rinc=  0; MA_Ginc=  0; MA_Binc=-ip;}
   else            {iColor =       iI; MA_Rinc=  0; MA_Ginc=  0; MA_Binc=  0;}
   int iColorInc=(MA_Rinc+256*MA_Ginc+65536*MA_Binc);
   return iColor+iColorInc*(i%id);
  }
//+------------------------------------------------------------------+
//| Set Plot Color Indexes                                           |
//+------------------------------------------------------------------+
void SetPlotColorIndexes(int plot_index)
  {
   int iIllumination=0xFF;
//color cBack=(color)ChartGetInteger(0,CHART_COLOR_BACKGROUND);
//Print("BACKGROUND is ",cBack);
//if(White==cBack) iIllumination=0x9F; //want to obtain a better visual effect
   PlotIndexSetInteger(plot_index,PLOT_COLOR_INDEXES,iColorNum);
   for(int i=0;i<iColorNum;i++)
      PlotIndexSetInteger(plot_index,PLOT_LINE_COLOR,i,ColorInc6section(i,iColorNum,iIllumination));
  }
//+------------------------------------------------------------------+
//| Set Plot Draw Type and other Properties                          |
//+------------------------------------------------------------------+
bool SetPlotProperties()
  {
//Print("iDrawType="+iDrawType);
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,iDrawType);
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,iLineStyle);
   PlotIndexSetInteger(0,PLOT_SHIFT,iShift);
   PlotIndexSetInteger(0,PLOT_SHOW_DATA,bShowData);//--- if show indicator data in DataWindow
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,iDrawBegin);
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,iLineWidth);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,dEmptyValue);
   PlotIndexSetString(0,PLOT_LABEL,sLabel);
   switch(iDrawType) //            Data  Color
     {
      case DRAW_COLOR_ARROW:       //1,    1,
         SetIndexBuffer(0,D1,INDICATOR_DATA);
         SetIndexBuffer(1,DC,INDICATOR_COLOR_INDEX);
         PlotIndexSetInteger(0,PLOT_ARROW,uArrow);
         PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,iArrowShift);
         SetPlotColorIndexes(0);
         break;

      case DRAW_ARROW:             //1,    0,
         SetIndexBuffer(0,D1,INDICATOR_DATA);
         PlotIndexSetInteger(0,PLOT_ARROW,uArrow);
         PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,iArrowShift);
         PlotIndexSetInteger(0,PLOT_LINE_COLOR,iPlotColor);
         break;

      case DRAW_COLOR_LINE:        //1,    1,
      case DRAW_COLOR_HISTOGRAM:   //1,    1,
      case DRAW_COLOR_SECTION:     //1,    1,
         SetIndexBuffer(0,D1,INDICATOR_DATA);
         SetIndexBuffer(1,DC,INDICATOR_COLOR_INDEX);
         SetPlotColorIndexes(0);
         break;

      case DRAW_NONE:              //1,    0,
      case DRAW_LINE:              //1,    0,
      case DRAW_HISTOGRAM:         //1,    0,
      case DRAW_SECTION:           //1,    0,
         SetIndexBuffer(0,D1,INDICATOR_DATA);
         PlotIndexSetInteger(0,PLOT_LINE_COLOR,iPlotColor);
         break;

      case DRAW_COLOR_HISTOGRAM2:  //2,    1,
      case DRAW_COLOR_ZIGZAG:      //2,    1,
         SetIndexBuffer(0,D1,INDICATOR_DATA);
         SetIndexBuffer(1,D2,INDICATOR_DATA);
         SetIndexBuffer(2,DC,INDICATOR_COLOR_INDEX);
         SetPlotColorIndexes(0);
         break;

      case DRAW_HISTOGRAM2:        //2,    0,
      case DRAW_ZIGZAG:            //2,    0,
         SetIndexBuffer(0,D1,INDICATOR_DATA);
         SetIndexBuffer(1,D2,INDICATOR_DATA);
         PlotIndexSetInteger(0,PLOT_LINE_COLOR,iPlotColor);
         break;

      case DRAW_FILLING:           //2,    0,
         SetIndexBuffer(0,D1,INDICATOR_DATA);
         SetIndexBuffer(1,D2,INDICATOR_DATA);
         PlotIndexSetInteger(0,PLOT_LINE_COLOR,iPlotColor);
         break;

      case DRAW_COLOR_BARS:        //4,    1,
      case DRAW_COLOR_CANDLES:     //4,    1,
         SetIndexBuffer(0,D1,INDICATOR_DATA);
         SetIndexBuffer(1,D2,INDICATOR_DATA);
         SetIndexBuffer(2,D3,INDICATOR_DATA);
         SetIndexBuffer(3,D4,INDICATOR_DATA);
         SetIndexBuffer(4,DC,INDICATOR_COLOR_INDEX);
         SetPlotColorIndexes(0);
         break;
      case DRAW_BARS:              //4,    0,
      case DRAW_CANDLES:           //4,    0,
         SetIndexBuffer(0,D1,INDICATOR_DATA);
         SetIndexBuffer(1,D2,INDICATOR_DATA);
         SetIndexBuffer(2,D3,INDICATOR_DATA);
         SetIndexBuffer(3,D4,INDICATOR_DATA);
         PlotIndexSetInteger(0,PLOT_LINE_COLOR,iPlotColor);
         break;
     }
   return(true);
  }
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- ArrayInit
   bool bInitBuffer=true;
   if(bInitBuffer)
     {
      ArrayInitialize(D1,dEmptyValue);
      ArrayInitialize(D2,dEmptyValue);
      ArrayInitialize(D3,dEmptyValue);
      ArrayInitialize(D4,dEmptyValue);
      ArrayInitialize(DC,dEmptyValue);
     }
   checkInput();
   SetPlotProperties();
//--- set accuracy
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
   IndicatorSetString(INDICATOR_SHORTNAME,"DemoDrawType : "+caDrawType[iDrawType].sDrawType);
   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[])
  {
//--- auxiliary variables
   int i=0;
//--- set position for beginning
   if(i<prev_calculated) i=prev_calculated-1;
//--- start calculations
   while(i<rates_total)
     {
      switch(iDrawType) //            Data  Color   if(buffer contain dEmptyValue)
        {
         case DRAW_COLOR_LINE:        //1,    1,      all do not draw
            DC[i]=(double)(i%iColorNum);
         case DRAW_LINE:              //1,    0,      all do not draw
         case DRAW_NONE:              //1,    0,      draw nothing at first
            if(bTestEmptyValue)
              {
               if(i%5==1)D1[i]=high[i];
               else D1[i]=dEmptyValue;
              }
            else
               D1[i]=close[i];
            break;

         case DRAW_COLOR_SECTION:     //1,    1,      link between non-empty place
            DC[i]=(double)(i%iColorNum);
         case DRAW_SECTION:           //1,    0,      connecting adjacent non-empty value
            if(bTestEmptyValue)
              {
               if(i%5==1)D1[i]=close[i];
               else D1[i]=dEmptyValue;
              }
            else
               D1[i]=close[i];
            break;

         case DRAW_FILLING:           //2,    0,
            //DC[i]=(double)(i%iColorNum);
            if(bTestEmptyValue)
              {
               if(i%5==1)
                 {
                  D1[i]=high[i];
                  D2[i]=low[i];
                 }
               else
                 {
                  D1[i]=dEmptyValue;
                  D2[i]=dEmptyValue;
                 }
              }
            else
              {
               D1[i]=high[i];
               D2[i]=low[i];
              }
            break;

         case DRAW_COLOR_ZIGZAG:      //2,    1,
            DC[i]=(double)(i%iColorNum);
         case DRAW_ZIGZAG:            //2,    0,
            if(bTestEmptyValue)
              {
               if(i%5==1)D1[i]=high[i];
               else D1[i]=dEmptyValue;
               if(i%5==4)D2[i]=low[i];
               else D2[i]=dEmptyValue;
              }
            else
              {
               D1[i]=high[i];
               D2[i]=low[i];
              }
            break;

         case DRAW_COLOR_ARROW:       //1,    1,      draw arrow at non-empty value
         case DRAW_COLOR_HISTOGRAM:   //1,    1,      only draw at non-empty place
            DC[i]=(double)(i%iColorNum);
         case DRAW_ARROW:             //1,    0,      draw arrow at non-empty value
         case DRAW_HISTOGRAM:         //1,    0,      only draw at non-empty place
            if(bTestEmptyValue)
              {
               if(i%5==1)D1[i]=close[i];
               else D1[i]=dEmptyValue;
              }
            else
              {
               D1[i]=close[i];
              }
            break;

         case DRAW_COLOR_HISTOGRAM2:  //2,    1,      only draw at non-empty place
            DC[i]=(double)(i%iColorNum);
         case DRAW_HISTOGRAM2:        //2,    0,      only draw at non-empty place
            if(bTestEmptyValue)
              {
               if(i%5==1)
                 {
                  D1[i]=high[i];
                  D2[i]=low[i];
                 }
               else
                 {
                  D1[i]=dEmptyValue;
                  D2[i]=dEmptyValue;
                 }
              }
            else
              {
               D1[i]=high[i];
               D2[i]=low[i];
              }
            break;

         case DRAW_COLOR_BARS:        //4,    1,      only draw at non-empty place
         case DRAW_COLOR_CANDLES:     //4,    1,      only draw at non-empty place
            DC[i]=(double)(i%iColorNum);
         case DRAW_BARS:              //4,    0,      only draw at non-empty place
         case DRAW_CANDLES:           //4,    0,      only draw at non-empty place
            if(bTestEmptyValue)
              {
               if(i%5==1)
                 {
                  D1[i]=open[i];
                  D2[i]=high[i];
                  D3[i]=low[i];
                  D4[i]=close[i];
                 }
               else
                 {
                  D1[i]=dEmptyValue;
                  D2[i]=dEmptyValue;
                  D3[i]=dEmptyValue;
                  D4[i]=dEmptyValue;
                 }
              }
            else
              {
               D1[i]=open[i];
               D2[i]=high[i];
               D3[i]=low[i];
               D4[i]=close[i];
              }
            break;
        }
      //---
      i++;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

Vorbereitete Antworten auf Ihre Fragen

F: Ich erhalte keine Plots.
A: Der Zweck dieses Indikators ist, Ihnen das Testen aller Zeichnungsstile zu ermöglichen, ohne dafür einen Code schreiben zu müssen. Wenn Sie also falsche Parameter eingeben, erhalten Sie keinen Plot. Gar kein Problem.

F: Der caDrawType[] scheint nutzlos zu sein. Wird er nur dazu verwendet, den Namensstring DrawType zu enthalten?
A: Zugegeben, das hängt mit meiner Faulheit zusammen - ich habe ihn einfach von früher hierher kopiert. caDrawType[] ist in manchen Fällen extrem nützlich. Doch das besprechen wir im nächsten Beitrag.

Fazit

Jetzt können Sie alles, was Sie wollen, zeichnen.

Möge der Code stets mit Ihnen sein.

Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/45

Beigefügte Dateien |
demodrawtype.mq5 (17.28 KB)
Erzeugung von Kursschwankungs-Indikatoren in MQL5 Erzeugung von Kursschwankungs-Indikatoren in MQL5
In diesem Beitrag geht es um die Erzeugung von zwei Indikatoren: dem Kursschwankung-Indikator, der das Chart der Kursschwankungen des Kurses zeichnet und dem Kursschwankungs-"Kerzen" Indikator, der "Kerzen" mit der angegebenen Anzahl von Kursschwankungen zeichnet. Jeder dieser Indikatoren schreibt die eingehenden Kurse in eine Datei und verwendet die gespeicherten Daten dann nach einem Neustart des Indikators (diese Daten können auch von anderen Programmen verwendet werden).
Wie man in MQL5 Indikatoren aufruft Wie man in MQL5 Indikatoren aufruft
Mit der neuen, zur Verfügung stehenden Version der MQL Programmiersprache hat sich nicht nur der Ansatz im Umgang mit Indikatoren verändert, sondern es haben sich auch neue Möglichkeiten ihrer Erzeugung ergeben. Zudem hat man jetzt noch mehr Flexibilität bei der Arbeit mit den Indikator-Buffern - man kann jetzt die gewünschte Richtung der Indizierung angeben und genau so viele Indikatorwerte bekommen, wie man möchte. In diesem Beitrag werden die einfachen Methoden zum Aufruf von Indikatoren und Abruf von Daten aus dem Indikator-Buffer erklärt.
Neue Möglichkeiten mit MetaTrader5 Neue Möglichkeiten mit MetaTrader5
MetaTrader 4 erfreute sich bei Händlern auf der ganzen Welt großer Beliebtheit und es sah lange so aus, als wären alle nun wunschlos glücklich. Mit seiner hohen Arbeitsgeschwindigkeit, seiner robusten Zuverlässigkeit, einem Riesenfeld an Möglichkeiten zum Schreiben von Indikatoren, Expert Advisors und informierten Handelssystemen sowie seiner Fähigkeit, aus über 100 Maklern auswählen zu können, hat sich dieses Terminal deutlich vom Rest abgesetzt. Doch die Zeit steht nicht still und deshalb stehen wir jetzt vor der Wahl: MetaTrade 4 oder MetaTrade 5? In diesem Beitrag sollen die wichtigsten Unterschiede dieses Terminals der 5. Generation aus aktuellem Blickwinkel beschrieben werden.
Handels-Ereignisse im Expert Advisor mit Hilfe der OnTrade() Funktion bearbeiten Handels-Ereignisse im Expert Advisor mit Hilfe der OnTrade() Funktion bearbeiten
MQL5 brachte eine Menge an Innovationen, inkl. die Bearbeitung verschiedenartiger Ereignisse (Timer-Ereignisse, Handels-Ereignisse, benutzerdefinierte Ereignisse, usw). Mit diesen Ereignissen umgehen zu können, gestattet Ihnen die Erzeugung komplett neuer Arten an Programmen für den automatischen und halb-automatischen Handel. In diesem Beitrag betrachten wir uns Handels-Ereignisse und schreiben einen Code für die OnTrade() Funktion, die das Handels-Ereignis bearbeiten wird.