English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
그래픽 컨트롤 옵션이 있는 인디케이터 만들기

그래픽 컨트롤 옵션이 있는 인디케이터 만들기

MetaTrader 5 | 5 7월 2021, 13:08
84 0
Vasily
Vasily

개요

시장 분위기가 무엇인지 안다면 MACD 인디케이터(이동 평균 수렴 확산 지수)도 아실 겁니다. 컴퓨터 분석이 가능해지면서 투자자들이 사용하기 시작한 가격 변동을 파악할 수 있는 아주 뛰어난 분석 도구죠.

저는 오랫동안 MACD 인디케이터에 대해 연구했는데요. 적용 가능한 알고리즘과 옵션들이 굉장히 다양하더라고요. 그래서 제가 배운 것들을 하나의 인디케이터에 다 담아 보기로 했습니다.

MACD 인디케이터의 종류

인디케이터에는 기본 MACD 지표 선과 oSMA 히스토그램이 나타날 겁니다. 변형 MACD 지표에는 어떤 것들이 있는지 알아보죠.
  1. 임펄스 시스템으로도 알려진 엘더의 MACD
  2. 이동선을 체크하지 않는 엘더의 MACD
  3. 가격 상승 및 하락을 각각 다른 색으로 나타내는 osMA 히스토그램
  4. osMA 히스토그램 단독 사용
  5. MACD 선 단독 사용

인디케이터 초기 설정

계산에는 다음의 매개 변수가 필요합니다:

  1. MACD 빠른 선의 값
  2. MACD 느린 선의 값
  3. MACD 신호선의 값
  4. 엘더의 추세 확인 선의 값

인디케이터를 그리려면 다음이 필요합니다.

  1. 이동평균선
  2. 신호선
  3. 3색 OsMA 히스토그램

메뉴에서 MQL5 마법사를 클릭하세요.

그림 1. MQL5 마법사를 이용한 인디케이터 생성


그림 2. MQL5 마법사로 공통 인디케이터 변수 설정하기


그림 3. MQL5 마법사로 인디케이터 드로잉 속성 설정하기

인디케이터 만들기

인디케이터 기초 템플릿은 완성되었네요. 이제 우리가 만들 인디케이터의 MACD 선을 계산해야 합니다.

선 계산식에 대해서는 자세히 다루지 않겠습니다. iMACD 함수를 이용할 거예요. 

int iMACD (
   string symbol,           // symbol name
   ENUM_TIMEFRAMES period,   // time period
   int fast_ema_period,    // fast averaging period
   int slow_ema_period,    // slow averaging period
   int signal_period,      // averaging period of a signal line
   ENUM_APPLIED_PRICE applied_price // type of price or a handle
   )

해당 함수는 특정 인디케이터 사본의 핸들을 반환합니다. 이 핸들을 이용하면 인디케이터가 연산한 데이터를 얻을 수 있죠. 인디케이터 버퍼의 데이터(기술적 인디케이터는 자체 내장 버퍼에 계산된 데이터를 포함하며 인디케이터에 따라 최대 5개까지 포함 가능) CopyBuffer() 함수를 이용하여 복사할 수 있습니다.

다음은 iMACD 함수를 이용하여 MACD 데이터를 요청할 차례입니다.

int MACDhadling =  iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);

인디케이터 사본의 핸들을 반환해 줄 겁니다.

CopyBuffer 함수를 이용해 데이터를 필요한 버퍼로 복사합니다.

int  CopyBuffer(
   int       indicator_handle,     // indicator's handle
   int       buffer_num,           // buffer number of the indicator
   int       start_pos,            // start position 
   int       count,                // number of data to copy
   double    buffer[]              // target array for the data to copy
   );

그 다음 MACD 선을 요청하고요.

CopyBuffer(MACDhadling,0,0,NewData,MACDlineBuffer);

인디케이터 신호선을 얻습니다.

CopyBuffer(MACDhadling,1,0,NewData,SignallineBuffer);

모두 합쳐 어떤 결과가 나오는지 보죠.

int MACDhadling=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);
CopyBuffer(MACDhadling,0,0,rates_total,MACDlineBuffer);
CopyBuffer(MACDhadling,1,0,rates_total,SignallineBuffer);

이제 계산된 MACD 선과 신호선이 준비되었습니다.

계속할까요?

의 데이터는

MACDlineBuffer

따라서

SignallineBuffer

버퍼가 복사되었으며 인덱싱은 차트 끝에서 시작합니다.

전통적으로 가격 배열 데이터에 대한 액세스는 가장 마지막 데이터에서부터 실행되는데요. 실질적으로는 새로운 데이터가 배열 끝에 입력되지만 현재 바(미완성)의 인덱스는 늘 0값을 갖습니다. 시계열에서 0값을 갖는 인덱스는 현재 바의 데이터가 타임프레임의 미완료된 인터벌에 해당함을 의미합니다.

따라서 모든 버퍼의 인덱싱 방향을 동일하게 만들려면 나머지 버퍼를 시계열로 설정해야 합니다.

ArraySetAsSeries(HistogramBuffer,false);
ArraySetAsSeries(HistogramColors,false);

히스토그램의 데이터도 필요합니다. 이는 MACD 선에서 신호선을 빼는 방식으로 계산됩니다.

for(int i=0;i<rates_total;i++)
  {
   HistogramBuffer[i]=MACDlineBuffer[i]-SignallineBuffer[i];
  }

이제 모두 합쳐 보죠.

ArraySetAsSeries(HistogramBuffer,false);
ArraySetAsSeries(HistogramColors,false);

int MACDhadling=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);
CopyBuffer(MACDhadling,0,0,rates_total,MACDlineBuffer);
CopyBuffer(MACDhadling,1,0,rates_total,SignallineBuffer);

for(int i=0;i<rates_total;i++)
  {
   HistogramBuffer[i]=MACDlineBuffer[i]-SignallineBuffer[i];
   HistogramColors[i]=1; 
  }


인디케이터 컨트롤 그래픽 시스템 만들기

이제 5가지 변형 인디케이터를 갖게 되었습니다.

우선 3번과 4번을 구현합니다.

    3. osMA 히스토그램 단독 사용
4. MACD 선 단독 사용

이제 버튼을 만들어 봅시다.

4번의 경우,

ObjectCreate(0,"ShowMACD",OBJ_BUTTON,ChartWindowFind(),100,100);   //creating the button
ObjectSetInteger(0,"ShowMACD",OBJPROP_XDISTANCE,75);              //assign the coordinates
ObjectSetInteger(0,"ShowMACD",OBJPROP_YDISTANCE,5);
ObjectSetInteger(0,"ShowMACD",OBJPROP_CORNER,CORNER_RIGHT_UPPER);  // and an anchor point
ObjectSetString(0,"ShowMACD",OBJPROP_TEXT,"ShowMACD");            // button label 
ObjectSetInteger(0,"ShowMACD",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"ShowMACD",OBJPROP_XSIZE,70);                 // size of buttons 
ObjectSetInteger(0,"ShowMACD",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"ShowMACD",OBJPROP_SELECTABLE,false);         // to make it selectable

실수로 버튼을 삭제하거나 다음 틱으로 버튼이 보내질 경우 버튼이 원래 자리로 돌아옵니다.

3번의 경우에는

ObjectCreate(0,"ShowOsMA",OBJ_BUTTON,ChartWindowFind(),100,100);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_XDISTANCE,75);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_YDISTANCE,30);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
ObjectSetString (0,"ShowOsMA",OBJPROP_TEXT,"Show OsMA");
ObjectSetInteger(0,"ShowOsMA",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_SELECTABLE,false);

4번의 버튼이 눌렸을 때와 눌리지 않았을 때의 경우를 구현해 보겠습니다.

그러려면 버퍼 인덱스를 확인해야 합니다.

SetIndexBuffer(0,MACDlineBuffer,INDICATOR_DATA);
SetIndexBuffer(1,SignallineBuffer,INDICATOR_DATA);
SetIndexBuffer(2,HistogramBuffer,INDICATOR_DATA);
SetIndexBuffer(3,HistogramColors,INDICATOR_COLOR_INDEX);
if(ObjectGetInteger(0,"ShowMACD",OBJPROP_STATE)!=1)
  {
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_NONE); // the buffer with index 0 isn't plotted
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_NONE); // the buffer with index 1 isn't plotted
  }
else
  {
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE); // the buffer with index 0 is plotted as line
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE); // the buffer with index 1 is plotted as line
  }

버튼이 눌러지먼 MACD 선이 그려지고, 버튼이 눌리지 않으면 MACD 선은 그려지지 않습니다.

3번의 버튼이 눌렸을 때와 눌리지 않았을 때의 경우도 구현해 봅시다.

if(ObjectGetInteger(0,"ShowOsMA",OBJPROP_STATE)!=1)
  {
   //the buffer with index 2 isn't plotted
   PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_NONE);
  }
else
  {
   //the buffer with index 2 is plotted as a color histogram
   PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_COLOR_HISTOGRAM);
  }

'2컬러'와 '임펄스' 두 가지 버튼을 차트의 오른쪽 하단 코너에 만들어 볼게요.

ObjectCreate(0,"2color",OBJ_BUTTON,ChartWindowFind(),100,100);
ObjectSetInteger(0,"2color",OBJPROP_XDISTANCE,75);
ObjectSetInteger(0,"2color",OBJPROP_YDISTANCE,50);
ObjectSetInteger(0,"2color",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
ObjectSetInteger(0,"2color",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"2color",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"2color",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"2color",OBJPROP_SELECTABLE,false);
ObjectSetString (0,"2color",OBJPROP_TEXT,"MultiColor");

ObjectCreate(0,"Impulse",OBJ_BUTTON,ChartWindowFind(),100,100);
ObjectSetInteger(0,"Impulse",OBJPROP_XDISTANCE,75);
ObjectSetInteger(0,"Impulse",OBJPROP_YDISTANCE,25);
ObjectSetInteger(0,"Impulse",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
ObjectSetInteger(0,"Impulse",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"Impulse",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"Impulse",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"Impulse",OBJPROP_SELECTABLE,false);

엘더의 임펄스 체킹은 EldersMA 값이 저장되는 새로운 배열을 필요로 합니다.

그러려면 우선 버퍼 전체 개수에 1을 더합니다.

#property indicator_buffers 4

다음과 같은 결과가 나올 거예요.

#property indicator_buffers 5

이제 새로운 버퍼를 선언합니다.

double EldersiEMA[];

이 버퍼는 내부 연산을 위한 버퍼로 설정합니다.

SetIndexBuffer(4,EldersiEMA,INDICATOR_CALCULATIONS);

이제 버퍼에 지수 이동 평균을 복사하겠습니다.

// you can do all in single line
CopyBuffer(iMA(NULL,0,EldersEMA,0,MODE_EMA,PRICE_CLOSE),0,0,rates_total,EldersiEMA); 

복사 함수로 버퍼가 얻어졌기 때문에 해당 버퍼의 인덱싱 또한 나머지 버퍼와 마찬가지로 차트 끝에서 시작합니다.

이제 2컬러 OsMA에 필요한 조건을 생각해 봅시다.

if (ObjectGetInteger(0,"2color",OBJPROP_STATE))
  {
   for(int i=1;i<rates_total;i++)
     {
      // if the histogram rises, the color is set to 0
      if(HistogramBuffer[i] > HistogramBuffer[i-1]) HistogramColors[i]=0;
      // if the histogram falls, the color is set to 1
      if(HistogramBuffer[i] < HistogramBuffer[i-1]) HistogramColors[i]=1;
     }
  }
else
  {
   ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
   // Here are the conditions for multi-color OSMA
  }

라인에 컬러 인덱스 설정

#property indicator_label3  "Histogram"
#property indicator_type3   DRAW_COLOR_HISTOGRAM
#property indicator_color3  DeepSkyBlue,Red,Green

첫 번째 컬러 인덱스 값이 0에서 시작

임펄스 시스템 변형에 필요한 조건을 작성해 보죠.

if (ObjectGetInteger(0,"Impulse",OBJPROP_STATE)) // // "Impulse" button is checked
  {
   ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");  // checking for a trend using the MACD-Line
   for(int i=1;i<rates_total;i++)
     {
      // the histogram rises and MACD-line rises
      if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (MACDlineBuffer[i]>MACDlineBuffer[i-1])) HistogramColors[i]=0;
      else
        {
         // the histogram falls and MACD-line falls 
         if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (MACDlineBuffer[i]<MACDlineBuffer[i-1])) HistogramColors[i]=1;
         else HistogramColors[i]=2; // if there isn't any conditions satisfied
        }
     }
  }
else 
  {
   ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's");  // checking for a trend using the EMA-line
   for(int i=1;i<rates_total;i++)
     {
      // the histogram rises and EMA-line rises
      if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (EldersiEMA[i]>EldersiEMA[i-1])) HistogramColors[i]=0;
      else
        {
         // the histogram falls and EMA-line falls
         if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (EldersiEMA[i]<EldersiEMA[i-1])) HistogramColors[i]=1;
         else HistogramColors[i]=2;// if there isn't any conditions satisfied
        }
     }
  }

이제 임펄스 시스템 조건을 OsMA 플로팅 조건과 합칩니다.

if (ObjectGetInteger(0,"2color",OBJPROP_STATE))
  {
   for(int i=1;i<rates_total;i++)
     {
      if(HistogramBuffer[i] > HistogramBuffer[i-1]) HistogramColors[i]=0;
      if(HistogramBuffer[i] < HistogramBuffer[i-1]) HistogramColors[i]=1;
     }
  }
else
  {
   ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
   if(ObjectGetInteger(0,"Impulse",OBJPROP_STATE))
     {
      ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");
      for(int i=1;i<rates_total;i++)
        {
         if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (MACDlineBuffer[i]>MACDlineBuffer[i-1])) HistogramColors[i]=0;
         else
           {
            if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (MACDlineBuffer[i]<MACDlineBuffer[i-1])) HistogramColors[i]=1;
            else HistogramColors[i]=2;
           }
        }
     }
   else 
     {
      ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's");
      for(int i=1;i<rates_total;i++)
        {
         if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (EldersiEMA[i]>EldersiEMA[i-1])) HistogramColors[i]=0;
         else
           {
            if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (EldersiEMA[i]<EldersiEMA[i-1])) HistogramColors[i]=1;
            else HistogramColors[i]=2;
           }
        }
     }
  }

이제 불필요한 버튼 신호를 방지하기 위한 조건을 작성합니다.

if (ObjectGetInteger(0,"2color",OBJPROP_STATE)) ObjectSetString (0,"2color",OBJPROP_TEXT,"2ColorMACD");
else ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
if (ObjectGetInteger(0,"Impulse",OBJPROP_STATE)) ObjectSetString (0,"Impulse",OBJPROP_TEXT,"Impulse");
else ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's")

버튼의 텍스트를 변경하는 코드를 삭제합니다.

이제 모두 합쳐 보죠.

//+------------------------------------------------------------------+
//|                                            MACD_By_CoreWinTT.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   3
//---- plot MACDline
#property indicator_label1  "MACDline"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Green
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//---- plot Signalline
#property indicator_label2  "Signalline"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//---- plot Histogram
#property indicator_label3  "Histogram"
#property indicator_type3   DRAW_COLOR_HISTOGRAM
#property indicator_color3  DeepSkyBlue,Red,Green
#property indicator_style3  STYLE_SOLID
#property indicator_width3  2

//--- input parameters
input int      Fast=12;
input int      Slow=26;
input int      Signal=9;
input int      EldersEMA=13;
//--- indicator buffers
double         MACDlineBuffer[];
double         SignallineBuffer[];
double         HistogramBuffer[];
double         HistogramColors[];
double         EldersiEMA[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MACDlineBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SignallineBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,HistogramBuffer,INDICATOR_DATA);
   SetIndexBuffer(3,HistogramColors,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(4,EldersiEMA,INDICATOR_CALCULATIONS);
//---
   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[])
  {
   ArraySetAsSeries(HistogramBuffer,false);
   ArraySetAsSeries(HistogramColors,false);

   int MACDhadling=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);
   CopyBuffer(MACDhadling,0,0,rates_total,MACDlineBuffer);
   CopyBuffer(MACDhadling,1,0,rates_total,SignallineBuffer);

   for(int i=0;i<rates_total;i++) { HistogramBuffer[i]=MACDlineBuffer[i]-SignallineBuffer[i];HistogramColors[i]=1; }

   ObjectCreate(0,"ShowMACD",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_YDISTANCE,5);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
   ObjectSetString(0,"ShowMACD",OBJPROP_TEXT,"ShowMACD");
   ObjectSetInteger(0,"ShowMACD",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_SELECTABLE,false);

   ObjectCreate(0,"ShowOsMA",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_YDISTANCE,30);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
   ObjectSetString(0,"ShowOsMA",OBJPROP_TEXT,"Show OsMA");
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_SELECTABLE,false);

   if(ObjectGetInteger(0,"ShowMACD",OBJPROP_STATE)!=1) 
     {
      PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_NONE);
      PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_NONE);
     }
   else 
     {
      PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);
      PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE);
     }

   if(ObjectGetInteger(0,"ShowOsMA",OBJPROP_STATE)!=1) 
     {
      PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_NONE);
     }
   else 
     {
      PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_COLOR_HISTOGRAM);
     }

   ObjectCreate(0,"2color",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"2color",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"2color",OBJPROP_YDISTANCE,50);
   ObjectSetInteger(0,"2color",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
   ObjectSetInteger(0,"2color",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"2color",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"2color",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"2color",OBJPROP_SELECTABLE,false);
   ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");

   ObjectCreate(0,"Impulse",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"Impulse",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"Impulse",OBJPROP_YDISTANCE,25);
   ObjectSetInteger(0,"Impulse",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
   ObjectSetInteger(0,"Impulse",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"Impulse",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"Impulse",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"Impulse",OBJPROP_SELECTABLE,false);
   ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");

   if(ObjectGetInteger(0,"2color",OBJPROP_STATE)) ObjectSetString(0,"2color",OBJPROP_TEXT,"2ColorMACD");
   else ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
   if(ObjectGetInteger(0,"Impulse",OBJPROP_STATE)) ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");
   else ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's");

   CopyBuffer(iMA(NULL,0,EldersEMA,0,MODE_EMA,PRICE_CLOSE),0,0,rates_total,EldersiEMA);

   if(ObjectGetInteger(0,"2color",OBJPROP_STATE))
     {
      for(int i=1;i<rates_total;i++)
        {
         if(HistogramBuffer[i] > HistogramBuffer[i-1]) HistogramColors[i]=0;
         if(HistogramBuffer[i] < HistogramBuffer[i-1]) HistogramColors[i]=1;
        }
     }
   else
     {
      if(ObjectGetInteger(0,"Impulse",OBJPROP_STATE))
        {
         for(int i=1;i<rates_total;i++)
           {
            if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (MACDlineBuffer[i]>MACDlineBuffer[i-1])) HistogramColors[i]=0;
            else
              {
               if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (MACDlineBuffer[i]<MACDlineBuffer[i-1])) HistogramColors[i]=1;
               else HistogramColors[i]=2;
              }
           }
        }
      else 
        {
         for(int i=1;i<rates_total;i++)
           {
            if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (EldersiEMA[i]>EldersiEMA[i-1])) HistogramColors[i]=0;
            else
              {
               if((HistogramBuffer[i]<HistogramBuffer[i-1]) && (EldersiEMA[i]<EldersiEMA[i-1])) HistogramColors[i]=1;
               else HistogramColors[i]=2;
              }
           }

        }
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

알고리즘 블록 다이어그램은 그림 4에서 확인 가능합니다.



그림 4. 인디케이터 알고리즘 블록 다이어그램

결과는 그림 5~7에 나타나 있습니다.

그림5

그림6

그림7

결론

이 글은 이제 막 기술적 분석을 시작하는 초보자들이 간단한 방법으로 인디케이터 그래픽 컨트롤을 구현할 수 있도록 돕기 위한 가이드입니다.

여러분에게 도움이 되었으면 좋겠고 궁극적으로 여러분이 자신만의 '시장 비전'을 키울 수 있었으면 합니다.

MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/42

파일 첨부됨 |
MetaTrader5와 MATLAB의 상호 작용 MetaTrader5와 MATLAB의 상호 작용
이 글은 MetaTrader5와 MATLAB 패키지 사이의 상호 작용에 대한 설명입니다. 데이터 변환 메커니즘과 MATLAB 데스크톱과 상호 작용이 가능한 범용 라이브러리 개발 과정에 대해 살펴볼 겁니다. MATLAB 환경에서 생성된 DLL의 사용법도 알아보겠습니다. 이 글은 C++와 MQL5를 이미 알고 있는 숙련된 프로그래머들을 위해 작성되었습니다.
MQL5 이벤트 핸들링: 빠르게 MA 피리어드 바꾸기 MQL5 이벤트 핸들링: 빠르게 MA 피리어드 바꾸기
피리어드가 13인 단일 MA 인디케이터가 차트에 적용되었다고 상상해 봅시다. 피리어드를 20으로 바꾸고 싶은데, 인디케이터 속성 대화 상자에서 13을 20으로 바꾸고 싶지는 않네요. 맨날 쓰는 방법이니까 너무 지루하잖아요. 특히 인디케이터 코드를 열어서 수정하고 싶지가 않습니다. 버튼 하나만 눌러서 해결하고 싶은데요. 키보드의 위쪽 화살표가 딱이겠네요. 이 글에서는 그 방법을 찾아볼게요.
뉴비들을 위한 복합 인디케이터 버퍼 만들기 뉴비들을 위한 복합 인디케이터 버퍼 만들기
복잡한 코드는 여러 개의 간단한 코드로 이루어집니다. 익숙한 코드들이라면 별로 복잡해 보이지 않죠. 이 글에서는 복수 개의 인디케이터 버퍼를 이요한 인디케이터 작성법을 알아보겠습니다. 아룬 인디케이터를 예시로 분석했으며, 두 가지 코드가 포함되어 있습니다.
MQL5: MetaTrader5로 상품선물거래위원회(CFTC) 보고서 분석하기 MQL5: MetaTrader5로 상품선물거래위원회(CFTC) 보고서 분석하기
이 글에서는 CTFC 보고서 분석에 필요한 도구를 개발해 보겠습니다. 우리가 해결할 문제는 다음과 같습니다. 중간 계산이나 변환을 거치지 않고 CFTC 보고서 내 데이터를 곧바로 활용할 수 있도록 해주는 인디케이터를 개발하는 것이죠. 그 외에도 여러 가지로 활용할 수 있습니다. 데이터 플로팅이라든지, 다른 인디케이터의 데이터로 활용하거나, 자동 분석 스크립트에서도 사용될 수 있고, 액스퍼트 어드바이저 매매 전략에서 사용될 수도 있죠.