
그래픽 컨트롤 옵션이 있는 인디케이터 만들기
개요
시장 분위기가 무엇인지 안다면 MACD 인디케이터(이동 평균 수렴 확산 지수)도 아실 겁니다. 컴퓨터 분석이 가능해지면서 투자자들이 사용하기 시작한 가격 변동을 파악할 수 있는 아주 뛰어난 분석 도구죠.
저는 오랫동안 MACD 인디케이터에 대해 연구했는데요. 적용 가능한 알고리즘과 옵션들이 굉장히 다양하더라고요. 그래서 제가 배운 것들을 하나의 인디케이터에 다 담아 보기로 했습니다.
MACD 인디케이터의 종류
인디케이터에는 기본 MACD 지표 선과 oSMA 히스토그램이 나타날 겁니다. 변형 MACD 지표에는 어떤 것들이 있는지 알아보죠.- 임펄스 시스템으로도 알려진 엘더의 MACD
- 이동선을 체크하지 않는 엘더의 MACD
- 가격 상승 및 하락을 각각 다른 색으로 나타내는 osMA 히스토그램
- osMA 히스토그램 단독 사용
- MACD 선 단독 사용
인디케이터 초기 설정
계산에는 다음의 매개 변수가 필요합니다:
- MACD 빠른 선의 값
- MACD 느린 선의 값
- MACD 신호선의 값
- 엘더의 추세 확인 선의 값
인디케이터를 그리려면 다음이 필요합니다.
- 이동평균선
- 신호선
- 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



