English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
MQL5의 드로잉 스타일

MQL5의 드로잉 스타일

MetaTrader 5지표 | 5 7월 2021, 10:08
73 0
Loong
Loong

개요

MQL4는 6가지 드로잉 스타일을 지원합니다. MQL5는 18가지 드로잉 스타일을 지원하지요. 그러니까 MQL5의 드로잉 스타일을 알아 보면 되겠죠?

이번 글에서는 MQL5가 지원하는 드로잉 스타일에 대해 상세히 알아 보겠습니다. 그리고 인디케이터를 생성해서 드로잉 스타일도 설명하고 플롯도 개선해 보도록 할게요.

드로잉 스타일

MQL4에는 플롯 개념이 없지만 SetIndexStyle() 함수의 첫 번째 변수인 라인 인덱스가 플롯 인덱스와 같은 역할을 한다고 생각하시면 됩니다.

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

MQL4는 6가지 드로잉 스타일만을 지원하는데요. DRAW_ZIGZAG는 2개의 버퍼를, 나머지 5가지 드로잉 스타일은 1개의 버퍼를 사용합니다.

따라서, MQL4의 경우, SetIndexStyle() 함수의 첫 번째 파라미터를 간단히 버퍼 인덱스로 이해할 수 있습니다. DRAW_ZIGZAG를 사용하지 않아도 아무런 문제가 없죠. 그나저나, MQL4에서 DRAW_ZIGZAG가 구현된 인디케이터를 보신 적이 있나요? 전 없거든요. (ZigZag.mq4는 DRAW_SECTION으로 구현됩니다).

MQL4와 MQL5의 드로잉 스타일을 비교해 봅시다. 

표 1. MQL4와 MQL5의 드로잉 스타일 목록

표 1. MQL4와 MQL5의 드로잉 스타일 목록

뭐가 눈에 띄나요? MQL5는 12가지 드로잉 스타일을 지원하며 이 중 8가지는 컬러 버퍼를 가지고 있습니다. 다만 라인 인덱스의 개념을 혼동하기가 매우 쉽기 때문에 전처럼 모호하게 사용할 수는 없습니다.

그렇기 때문에 MQL5는 MQL4의 라인과 동일한 역할을 하는 플롯을 제공하여 인디케이터 창에서 그림을 그릴 수 있게 해줍니다.

MQL5에서는 선만 그릴 수 있는 것이 아니므로 플롯이라는 이름이 더 정확하죠.

버퍼 패턴

이번에는 버퍼 패턴에 대해 알아 보겠습니다. 드로잉 스타일의 버퍼 패턴에는 버퍼 넘버, 타입 및 어레인지먼트가 들어갑니다.

버퍼 패턴은 DataBuffer를 의미하는 D 또는 ColorBuffer를 의미하는 C의 문자열로 표현할 수 있으며 왼쪽에서 오른쪽으로 갈수록 상응하는 인덱스 넘버가 커집니다.

MQL5의 각 드로잉 스타일에 해당하는 버퍼 패턴은 다음 표에서 확인할 수 있습니다.

표 2. MQL5 드로잉 스타일별 버퍼 패턴

표 2 MQL5 드로잉 스타일별 버퍼 패턴

인디케이터에 복수의 플롯이 존재할 경우, 인디케이터의 버퍼 패턴은 플롯 버퍼 패턴의 순서를 따르며 SetIndexBuffer() 호출 시 버퍼 인덱스는 오름차순이어야 합니다.

연산에 필요한 데이터를 보조 버퍼에 임시로 저장한 경우 모든 보조 버퍼는 SetIndexBuffer()로 바인딩되어야 하며 디스플레이 가능한 버퍼 다음에 위치해야 합니다.

그것도 아니면...

직접 보여 드리고자 DemoBufferPattern 인디케이터를 생성했습니다. 한번 따라해 보세요.

DemoDrawType 인디케이터

DemoDrawType 인디케이터를 자세히 볼게요.


그림 3. 인디케이터 입력 변수

그림 1. 인디케이터 입력 변수

그림 4. 인디케이터 입력 변수(계속)

Figure 2. 인디케이터 입력 변수(계속)

'인풋' 탭에서 원하는 드로잉 스타일을 선택하고 플롯의 프로퍼티를 설정할 수 있습니다.

그림 5. 드로잉 스타일 목록

그림 3. 드로잉 스타일 목록

따라서, 각 속성별 입력 변수를 정의하고 각 변수의 합리성을 확인하는 함수를 구현해야 합니다.

또한 프로그램 상에서는 입력 변수를 수정할 수 없으므로 전역 변수 세트를 설정하여 확인된 입력 변수 값을 유지해야 합니다.

//--- 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);
  }

그림 4-21. 18가지 드로잉 스타일의 예시

=

그림 4. DRAW_NONE의 예시

=

그림 5. DRAW_LINE의 예시

=

그림 6. DRAW_HISTOGRAM의 예시

=

그림 7. DRAW_ARROW의 예시

=

그림 8. DRAW_SECTION의 예시

=

그림 9. DRAW_HISTOGRAM2의 예시

=

그림 10. DRAW_FILLING의 예시

=

그림 11. DRAW_ZIGZAG의 예시

=

그림 12. Example of drawing style DRAW_BARS

=

그림 13. DRAW_CANDLES의 예시

=

그림 14. DRAW_COLOR_LINE의 예시

=

그림 15. DRAW_COLOR_HISTOGRAM의 예시

=

그림 16. DRAW_COLOR_ARROW의 예시

=

그림 17. DRAW_COLOR_SECTION의 예시

=

그림 18. DRAW_COLOR_HISTOGRAM2의 예시

=

그림 19. DRAW_COLOR_ZIGZAG의 예시

=

그림 20. DRAW_COLOR_BARS의 예시

=

그림 21. DRAW_COLOR_CANDLES의 예시


빈 값 다루기

드로잉 스타일별로 차트가 다르므로 버퍼 패턴 또한 상이하죠.

버퍼 패턴을 제외하면 드로잉 스타일 사이의 가장 큰 차이점은 바로 빈 값을 다루는 방식이 됩니다.

그래서 빈 값을 삽입할 수 있게 해주는 입력 변수를 추가해 보았습니다. DrawType에 대한 설명이 본 인디케이터의 목적인 만큼 이번에는 빈 값을 설정해 보겠습니다.

빈 값 처리 방식을 기준으로 하면 전체 드로잉 스타일을 세 가지 카테고리로 분류할 수 있습니다.

표 3. 카테고리별 드로잉 스타일

표 3. 카테고리별 드로잉 스타일

그림 22-29는 빈 값을 포함하는 드로잉 스타일의 예시입니다.

그림 22. DRAW_LINE의 예시(빈 값 포함 시)

그림23. DRAW_SECTION의 예시(빈값 포함 시)

그림24. DRAW_HISTOGRAM2의 예시(빈값 포함 시)

그림 25. DRAW_BARS의 예시(빈값 포함 시)

그림 26. DRAW_FILLING의 예시(빈값 포함 시)

그림 27. DRAW_ZIGZAG의 예시(빈값 포함 시)

그림 28. DRAW_COLOR_ARROW의 예시(빈값 포함 시)

그림 29. DRAW_COLOR_CANDLES(빈 값 포함 시)

 

인디케이터 전체 소스 코드:

//+------------------------------------------------------------------+
//|                                                 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);
  }
//+------------------------------------------------------------------+

그럴 줄 알고 미리 준비한 Q&A

Q: 아무 것도 안 나오는데요.
A: 이 인디케이터의 목적은 코드를 작성하지 않고 드로잉 스타일을 테스트하는 것이므로 잘못된 매개 변수 값을 입력하면 당연히 아무 것도 안 나와요. 진정하세요.

Q: caDrawType[]은 아무짝에도 쓸모없어 보이는데요. 문자열 이름이나 쓰라고 만든 겁니까?
A: 아이고. 사실 제가 귀찮아서 예전에 썼던 글 복사한거라... 물론 caDrawType[]이 굉장히 유용하게 쓰일 수도 있는데, 다음에 설명할게요.

결론

그리고 싶은 건 다 그릴 수 있다.

코드가 함께하길.

MetaQuotes 소프트웨어 사를 통해 영어가 번역됨
원본 기고글: https://www.mql5.com/en/articles/45

파일 첨부됨 |
demodrawtype.mq5 (17.28 KB)
MQL5로 틱 인디케이터 만들기 MQL5로 틱 인디케이터 만들기
이 글에서는 가격을 틱 차트로 나타내는 틱 인디케이터와 특정 개수의 틱을 이용해 캔들을 그리는 캔들 인디케이터 두 가지의 작성 방법을 다룰 겁니다. 두 인디케이터 모두 가격 정보를 파일로 만들어 인디케이터 재가동 시 저장된 데이터(다른 프로그램에서도 이용 가능)를 이용합니다.
MQL5에서 인디케이터를 호출하는 방법 MQL5에서 인디케이터를 호출하는 방법
새로운 버전의 MQL 프로그래밍 언어를 사용할 수 있게 됨에 따라 지표 처리 방식이 변경되었을 뿐만 아니라 지표를 만드는 새로운 방법도 있습니다. 또한 인디케이터 버퍼로 작업 할 수 있는 추가적인 유연성이 있습니다. 이제 원하는 인덱싱 방향을 지정하고 원하는 만큼의 인디케이터 값을 얻을 수 있습니다. 이 문서에서는 인디케이터를 호출하고 인디케이터의 버퍼에서 데이터를 검색하는 기본 방법을 설명합니다.
MetaTrader5가 주는 새로운 기회 MetaTrader5가 주는 새로운 기회
전 세계 투자자들에게 사랑 받은 MetaTrader4는 그 자체로 정말 완벽해 보였죠. 빠른 처리 속도, 안정성, 다양한 인디케이터 작성 방법, 엑스퍼트 어드바이저, 거래 시스템, 그리고 선택 가능한 브로커의 수까지, 다른 터미널과는 비교가 불가능할 정도였으니까요. 하지만 시간이 흘러 이제 우리는 MetaTrader4와 MetaTrader5 사이의 선택의 길에 놓여 있는데요. 이 글에서는 MetaTrader5의 주요 차별점에 대해 이야기하도록 하겠습니다.
Expert Advisor에서 OnTrade() 함수를 이용한 거래 이벤트 처리 Expert Advisor에서 OnTrade() 함수를 이용한 거래 이벤트 처리
MQL5는 다양한 유형의 이벤트 (타이머 이벤트, 거래 이벤트, 맞춤 이벤트 등) 작업을 포함하여 많은 혁신을 제공했습니다. 이벤트 처리 기능을 통해 자동 및 반자동 거래를 위한 완전히 새로운 유형의 프로그램을 만들 수 있습니다. 이 기사에서는 거래 이벤트를 고려하고 거래 이벤트를 처리할 OnTrade() 함수에 대한 코드를 작성합니다.