MQL5를 사용하여 사용자 지정 돈치안(Donchian) 채널 지표를 만드는 방법
소개
이 글에서는 트레이딩에서 매우 중요한 개념인 추세 식별에 도움이 되는 기술적 도구인 돈치안 채널 지표에 대해 알아보고자 합니다. 이 지표는 추세 추종 지표입니다.
다음과 같은 주제를 통해 이 지표에 대한 모든 것을 다뤄보겠습니다:
돈치안 채널 정의
이 부분에서는 돈치안 채널 지표에 대해 알아보고 그 뒤에 숨겨진 주요 개념을 이해하여 효과적으로 사용하도록 하겠습니다. 돈치안 채널은 리차드 돈치안 트레이더가 개발한 것으로 추세의 방향과 가격의 움직임을 따라가는 추세 추종이자 후행 지표로서 추세를 파악하는 것이 지표의 주요 목적입니다. 지표는 가격을 포함하는 채널을 형성하는 세 개의 선으로 구성되며 채널의 위쪽 선은 특정 시간 동안 기록된 최고 가격을, 채널의 아래쪽 선은 특정 기간의 최저 가격을, 중간 선은 위쪽 선과 아래쪽 선 사이의 절반 거리를 나타냅니다.
다음 차트는 Donchian 채널 차트의 예시입니다:

이전 차트에서 볼 수 있듯이 가격 위에 선이 있고 그 아래에 또 다른 선이 있으며 그 사이에 세 번째 선이 있습니다. 지표에는 상단 및 하단 라인과 함께 중간 라인이 존재합니다. 이러한 형태의 지표를 기반으로 다양한 전략 추세의 식별, 돌파, 지지 및 저항 수준의 식별 등 거래에 유용하게 사용할 수 있습니다.
이 지표의 주요 개념은 특정 시간에 걸쳐 가격의 고점과 저점을 관찰하여 추세 또는 우리가 선호하는 방향을 파악하는 것입니다. 가격이 특정 시점의 최고가보다 높으면 강세장이 있음을 나타내며 매수 신호일 수 있습니다. 가격이 특정 시점의 최저 저점보다 낮으면 약세장이 있음을 나타내며 매도 신호일 수 있습니다. 따라서 우리는 특정 기간을 지정하고 최고가와 최저가를 결정합니다. 그리고 가격이 위 또는 아래로 움직이다가 신호가 최고가 또는 최저가를 돌파할 때까지 관찰합니다.
이 지표는 손절 및 이익실현 레벨을 결정하기 위해 사용될 수 있습니다. 이 지표는 지표의 레벨이 매우 명확하고 특히 올바른 매개 변수를 사용하는 경우에는 잘못된 레벨이 설정되는 경우를 줄이며 중요한 레벨로 작동하므로 거래에서 매우 중요하고 유용합니다. 예를 들어 채널의 저점은 매수 포지션의 손절매 레벨 또는 매도 포지션의 이익실현 레벨로 사용될 수 있으며 채널의 고점은 숏 포지션의 손절매 또는 매수 포지션의 수익 목표로 사용될 수 있습니다.
앞서 살펴본 내용에 따라 이 지표를 계산하는 방법은 다음과 같은 간단한 단계와 같습니다:
- Channel High(CH)= 지난 N주기 중 가장 높은 고점
- Channel Low(CL)= 마지막 N주기 중 가장 낮은 저점
- Middle line(ML)= (Channel High+Channel Low)/2
따라서 원하는 기간을 정하고 그 기간 동안 방향을 감지하고 최고 가격과 최저 가격을 감지하고 그 옆에 선을 그려서 관찰하고 최고 레벨과 최저 레벨 사이의 절반 거리를 계산하여 중간 선을 얻어야 합니다. 돈치안 채널과 볼린저 밴드에는 차이가 있습니다. 돈치안 채널은 앞서 언급한 것처럼 특정 기간 동안 최고 고점과 최저 저점을 그리지만 볼린저 밴드는 두 표준 편차를 더하고 뺀 후 일정 기간의 평균을 그리는 차이가 있습니다. 자세한 정보가 필요하면 볼린저 밴드에 대한 글을 읽고 볼린저 밴드에 대해 자세히 알아보고 이를 기반으로 트레이딩 시스템을 만드는 방법을 알아보세요.
이 지표는 특히 추세 추종 트레이더에게 매우 중요합니다. 왜냐하면 이 지표는 추세와 방향을 명확하게 식별하는 데 도움이 되기 때문입니다. 이 지표를 기반으로 다양한 전략을 작업하고 테스트하는 것은 유용 할 수 있으므로 거래 시스템에서 매우 좋은 도구가 될 수 있습니다. 이 지표를 다른 의미 있는 기술적 지표와 함께 사용하면 더 나은 통찰력과 결과를 얻을 수 있다는 점을 잊지 마시기 바랍니다.
사용자 지정 돈치안 채널
이 주제에서는 MQL5로 사용자 지정 Donchian 채널 지표를 만드는 데 사용할 수 있는 방법을 공유하겠습니다. 다음 단계에서 볼 수 있듯이 우리는 위쪽 선, 아래쪽 선, 가운데 선의 형태로 지표를 만들 것입니다.
다음 값을 식별자로 사용하여 추가 매개변수를 생성합니다:
- indicator_chart_window: 차트 창에서 지표를 보이게 하기 위해서 입니다
- indicator_buffers: 지표 계산의 버퍼 수를 결정합니다. 숫자는 (3)이 됩니다.
- indicator_plots: 지표의 그래픽 시리즈 수를 결정합니다. 숫자는 (3)이 됩니다.
#property indicator_chart_window #property indicator_buffers 3 #property indicator_plots 3
기간에 대한 입력과 지표라인의 색상에 대한 입력 두 개를 다음과 같이 동일하게 만듭니다:
- 정수 변수(indPeriod)를 생성하고 20을 기본값으로 지정하지만 사용자의 입력에 따라 다르게 지정할 수 있습니다.
- 색상 유형 변수(indColor)를 생성하고 파란색을 기본값으로 지정하지만 사용자의 입력에 따라 다른 색상을 지정할 수도 있습니다.
input int indPeriod=20; //Period input color indColor=clrBlue; //Color
다음과 같이 전역 변수를 생성합니다:
- upperBuff, lowerBuff, middleBuff의 더블 유형 배열
- upperLine, lowerLine, middleLine의 더블 유형 변수
- 시작 및 바의 정수형 변수 유형
double upperBuff[]; double lowerBuff[]; double middleBuff[]; double upperLine,lowerLine,middleLine; int start, bar;
아무것도 반환하지 않는 void를 사용하여 지표의 사용자 지정 함수를 만들고 세 개의 매개 변수(인덱스, 동적 배열인 버퍼, 지표의 모든 라인에 대한 문자열인 레이블)로 indInit의 변수를 만듭니다. 함수 본문에서는 다음을 수행합니다:
- 지정된 지표를 1차원 동적 배열과 연결하는 SetIndexBuffer 함수를 사용합니다. 매개 변수는 다음과 같습니다:
- index: 지표 버퍼의 번호를 지정합니다. 우리는 인덱스 변수를 사용하겠습니다.
- buffer[]: 생성된 동적 배열인 buffer[]를 결정합니다.
- data_type: 기본값(indicator_data)이 될 저장해야 하는 데이터를 결정합니다.
- 코드에서 볼 수 있듯이 다른 prop-id 및 prop_value 매개 변수를 사용하여 PlotIndexSetInteger 함수를 다섯 번 사용하면 이 함수가 해당 지표 라인의 값을 설정합니다. 지표 속성은 정수여야 합니다. 모든 매개 변수는 다음과 같습니다:
- plot_index: 그래픽 플로팅의 인덱스를 결정합니다. 우리는 인덱스 변수를 사용하겠습니다.
- prop_id: ENUM_PLOT_PROPERT_INTEGER 중 하나가 될 수 있는 속성 식별자 값을 확인합니다.
- prop_value: prop_id에서 결정된 속성의 값을 확인합니다.
- 해당 문자열 속성 지표의 값을 설정하는 PlotIndexSetString 함수를 사용합니다. 이 함수의 매개 변수는 PlotIndexSetInteger 함수와 동일하지만 여기서 지표 속성은 문자열이어야 합니다.
- PlotIndexSetDouble 함수를 사용하여 해당 더블 속성 지표의 값을 설정합니다. 매개 변수도 동일하지만 지표 속성은 더블 유형이어야 합니다.
void indInit(int index, double &buffer[],string label) { SetIndexBuffer(index,buffer,INDICATOR_DATA); PlotIndexSetInteger(index,PLOT_DRAW_TYPE,DRAW_LINE); PlotIndexSetInteger(index,PLOT_LINE_WIDTH,2); PlotIndexSetInteger(index,PLOT_DRAW_BEGIN,indPeriod-1); PlotIndexSetInteger(index,PLOT_SHIFT,1); PlotIndexSetInteger(index,PLOT_LINE_COLOR,indColor); PlotIndexSetString(index,PLOT_LABEL,label); PlotIndexSetDouble(index,PLOT_EMPTY_VALUE,EMPTY_VALUE); }
그 후 OnInit() 본문에서 지표의 세개의 라인에 대해 지표의 사용자 정의 함수를 세 번 사용하며 다음과 같이 됩니다:
indInit(0,upperBuff,"Donchian Channel"); indInit(1,lowerBuff,"Donchian Channel"); indInit(2,middleBuff,"Middle Donchian");
여기에서 지표의 텍스트 레이블을 설정하려면 IndicatorSetString 함수를 사용합니다.
IndicatorSetString(INDICATOR_SHORTNAME,"Donchian ("+IntegerToString(indPeriod)+")");
OnCalculate 부분에서는 다음 단계를 수행하여 지표를 계산합니다:
rates_total이 사용자의 입력 period+1보다 작은지 확인하고 그렇다면 0을 반환하도록 프로그램을 작성해야 합니다.
if(rates_total<indPeriod+1) { return 0; }
삼항 연산자 ?: 를 사용하여 시작 변수에 값을 할당합니다. start=prev_calculated==0이 참이면 연산자는 indPeriod로 설정되고 거짓이면 연산자는 prev_calculated-1로 설정됩니다.
start=prev_calculated==0? indPeriod: prev_calculated-1;
for 함수를 사용하여 지표를 계산하는 루프를 만들면 표현식 1은 (bar=start), 표현식 2는 (bar < rate_total), 표현식 3은 (bar ++)가 되어 바가 하나씩 증가하게 됩니다. for 루프의 연산자는 다음과 같습니다:
- 배열에서 가장 높은 값을 검색하는 ArrayMaximum 함수를 사용하여 high의 최대값을 감지하여 upperLine을 계산합니다.
- 배열에서 가장 낮은 값을 찾는 ArrayMinimum 함수를 사용하여 low의 최소값을 감지하여 lowerLine을 계산합니다.
- 위쪽 라인과 아래쪽 라인의 결과에서 2로 나눠 중간 라인 계산하기
- upperBuff[bar], lowerBuff[bar], middleBuff[bar}의 값을 할당합니다.
for(bar=start;bar<rates_total;bar++) { upperLine=high[ArrayMaximum(high,bar-indPeriod+1,indPeriod)]; lowerLine=low[ArrayMinimum(low,bar-indPeriod+1,indPeriod)]; middleLine=(upperLine+lowerLine)/2; upperBuff[bar]=upperLine-(upperLine-lowerLine); lowerBuff[bar]=lowerLine+(upperLine-lowerLine); middleBuff[bar]=middleLine; }
다음은 하나의 블록에 포함된 전체 코드입니다:
#property indicator_chart_window #property indicator_buffers 3 #property indicator_plots 3 input int indPeriod=20; //Period input color indColor=clrBlue; //Color double upperBuff[]; double lowerBuff[]; double middleBuff[]; double upperLine,lowerLine,middleLine; int start, bar; void indInit(int index, double &buffer[],string label) { SetIndexBuffer(index,buffer,INDICATOR_DATA); PlotIndexSetInteger(index,PLOT_DRAW_TYPE,DRAW_LINE); PlotIndexSetInteger(index,PLOT_LINE_WIDTH,2); PlotIndexSetInteger(index,PLOT_DRAW_BEGIN,indPeriod-1); PlotIndexSetInteger(index,PLOT_SHIFT,1); PlotIndexSetInteger(index,PLOT_LINE_COLOR,indColor); PlotIndexSetString(index,PLOT_LABEL,label); PlotIndexSetDouble(index,PLOT_EMPTY_VALUE,EMPTY_VALUE); } int OnInit() { indInit(0,upperBuff,"Donchian Channel"); indInit(1,lowerBuff,"Donchian Channel"); indInit(2,middleBuff,"Middle Donchian"); IndicatorSetString(INDICATOR_SHORTNAME,"Donchian ("+IntegerToString(indPeriod)+")"); return(INIT_SUCCEEDED); } 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[]) { if(rates_total<indPeriod+1) { return 0; } start=prev_calculated==0? indPeriod: prev_calculated-1; for(bar=start;bar<rates_total;bar++) { upperLine=high[ArrayMaximum(high,bar-indPeriod+1,indPeriod)]; lowerLine=low[ArrayMinimum(low,bar-indPeriod+1,indPeriod)]; middleLine=(upperLine+lowerLine)/2; upperBuff[bar]=upperLine-(upperLine-lowerLine); lowerBuff[bar]=lowerLine+(upperLine-lowerLine); middleBuff[bar]=middleLine; } return(rates_total); }
이 코드를 컴파일한 후 오류나 경고 없이 컴파일이 완료되고 지표 폴더의 트레이딩 터미널 내 네비게이터 창에서 지표를 찾아 실행하면 아래와 같이 입력할 수 있습니다:

이전 그림에서 볼 수 있듯이 두 개의 입력이 있습니다:
- Period: 지표 계산에 사용할 시간 길이를 결정합니다. 기본값은 20으로 표시되지만 사용자가 업데이트할 수 있습니다.
- Color: 지표 라인의 색상을 결정합니다. 기본값은 파란색이지만 업데이트할 수 있습니다.
기본 설정에 따라 이 두 가지 입력을 결정하고 확인을 누르면 다음과 같이 차트에 첨부된 지표를 찾을 수 있습니다.

이전 차트에서 볼 수 있듯이 위와 아래에서 가격을 둘러싼 두 개의 선이 채널을 형성하고 가운데 선은 채널의 절반의 거리를 나타내는 세 개의 지표 선이 있습니다.
돈치안 채널 EA
이 부분에서는 지표의 움직임이나 동작을 기반으로 신호를 생성하는 데 사용하는 EA를 생성하여 거래 시스템에서 이 사용자 지정 돈치안 채널 지표를 사용합니다. 첫 번째 방법은 EA에 지표의 개념을 코드를 작성하는 것이고 두 번째 방법은 iCustom 함수를 사용하여 생성한 지표를 EA에 첨부하는 것입니다. 여기서는 두 번째 방법을 기반으로 간단한 시스템을 설계해 보겠습니다.
다음은 이러한 EA에 대한 설명입니다:
돈치안 채널 단순 EA
지표의 값(채널 높음, 채널 중간, 채널 낮음)과 함께 차트에 코멘트를 반환하는 데 사용할 수 있는 첫 번째 시스템을 만들겠습니다. 우리에게는 이러한 값을 지속적으로 확인하고 모니터링하여 차트에 주석으로 출력하는 프로그램이 필요합니다.
다음은 이러한 유형의 EA를 생성하는 단계입니다:
기본값(20)으로 지표 기간의 입력 변수를 생성하지만 사용자가 EA의 입력에서 업데이트할 수 있습니다.
input int indPeriod=20; //Period
정수형 글로벌 변수 donChianChannel을 생성합니다.
int donchianChannel; OnInit() 부분에서는 생성된 커스텀 Donchian 채널 지표의 핸들을 반환하는 iCustom 함수를 할당하여 donchianChannel을 업데이트합니다. 매개변수는 다음과 같습니다:
- symbol: 심볼 이름을 지정합니다. 우리는 현재 심볼에 적용할 _Symbol을 사용합니다.
- period: 기간을 지정합니다. 현재 기간에 적용될 PERIOD_CURRENT를 사용합니다.
- name: 지표의 문자열 이름과 경로를 지정합니다.
- 그런 다음 지표의 입력을 지정하고 여기에 지표의 기간을 지정합니다.
donchianChannel=iCustom(_Symbol,PERIOD_CURRENT,"My Files\\Donchian_Channel\\Donchian_Channel",indPeriod);
OnDeinit() 부분에서는 출력 함수를 사용하여 EA를 제거할 때 EA에서 "Donchian 채널 EA가 제거되었습니다"라는 메시지를 반환합니다.
Print("Donchian Channel EA Removed");
OnTick() 부분에서는 channelBuff, channelBuff1, middleBuff의 세 가지 배열을 생성합니다.
double channelBuff[],channelBuff1[], middleBuff[]; CopyBuffer 함수를 사용하여 사용자 지정 Donchian 채널 지표의 모든 버퍼 데이터를 가져옵니다. 매개변수:
- indicator_handle: 지표 핸들을 지정하기 위해 생성된 donchianChannel 핸들을 세 개의 버퍼 모두에 대해 사용합니다.
- buffer_num: 버퍼 번호를 지정하기 위해 channelBuff는 0, channelBuff1은 1, middleBuff는 2를 사용합니다.
- start_pos: 복사할 첫 번째 요소의 위치를 지정하기 위해 세 개의 버퍼 모두 0으로 설정합니다.
- count: 복사할 데이터 개수를 지정하기 위해 3개의 버퍼 모두에 3을 사용합니다.
- buffer[]: 복사할 대상 배열을 지정하기 위해 세 개의 버퍼(channelBuff, channelBuff1, middleBuff)를 지정합니다.
CopyBuffer(donchianChannel,0,0,3,channelBuff); CopyBuffer(donchianChannel,1,0,3,channelBuff1); CopyBuffer(donchianChannel,2,0,3,middleBuff);
모든 사용자에 대해 더블 변수를 만든 후 모든 라인의 현재 값을 정의합니다.
double channelHigh=channelBuff1[0]; double channelMiddle=middleBuff[0]; double channelLow=channelBuff[0];
코멘트 함수를 사용하여 차트에 세 개의 값과 각각의 값을 각각의 라인에 코멘트로 반환합니다.
Comment("Channel High: ",channelHigh,"\nChannel Middle: ",channelMiddle,"\nChannel Low: ",channelLow);
다음은 하나의 블록에 포함된 전체 코드입니다.
input int indPeriod=20; //Period int donchianChannel; int OnInit() { donchianChannel=iCustom(_Symbol,PERIOD_CURRENT,"My Files\\Donchian_Channel\\Donchian_Channel",indPeriod); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { Print("Donchian Channel EA Removed"); } void OnTick() { double channelBuff[],channelBuff1[], middleBuff[]; CopyBuffer(donchianChannel,0,0,3,channelBuff); CopyBuffer(donchianChannel,1,0,3,channelBuff1); CopyBuffer(donchianChannel,2,0,3,middleBuff); double channelHigh=channelBuff1[0]; double channelMiddle=middleBuff[0]; double channelLow=channelBuff[0]; Comment("Channel High: ",channelHigh,"\nChannel Middle: ",channelMiddle,"\nChannel Low: ",channelLow); }
이 코드를 오류나 경고 없이 컴파일한 후에는 내비게이터 창에서 Expert Advisor 폴더 아래에서 찾을 수 있습니다. 원하는 차트에 실행하면 다음과 같은 입력 창을 확인할 수 있습니다:

실행 후 돈치안 채널 지표의 레벨과 함께 EA가 차트에 다음과 같은 코멘트로 첨부된 것을 확인할 수 있습니다:

차트에 원하는 신호가 표시된 것을 볼 수 있습니다. 지표의 세 가지 값(Channel High, Channel Middle, Channel Low)의 각각의 값이 별도의 라인에 표시되어 있습니다.
확인을 위해 EA의 신호 값과 지표의 값을 비교해 보면 다음 그림과 같이 지표가 삽입되어 있고 데이터 창에 표시된 값이 EA의 신호 값과 동일하다는 것을 알 수 있습니다:

이 EA를 개선하여 지표의 움직임과 레벨에 따라 신호를 받으려면 지표의 개념에 맞는 조건을 설정하여 거래 시스템 (EA)을 통해 매수 및 매도 신호를 수신하도록 해야 합니다.
돈치안 채널 돌파 EA:
이 버전의 EA에서 우리는 프로그램이 지표의 세 가지 값을 모두 지속적으로 확인하고 가격(매도)이 채널 고점을 돌파하면 차트에 코멘트로 매수 신호를 수신해야 합니다. 다른 시나리오는 가격(bid)이 채널 저점을 돌파하면 차트에 코멘트로 매도 신호를 수신해야 하는 경우입니다. 다른 조건에 대해서는 우리는 아무것도 수신할 필요가 없습니다.
다음은 이러한 유형의 트레이딩 시스템(EA)을 만드는 전체 코드입니다:
input int indPeriod=20; //Period int donchianChannel; int OnInit() { donchianChannel=iCustom(_Symbol,PERIOD_CURRENT,"My Files\\Donchian_Channel\\Donchian_Channel",indPeriod); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { Print("Donchian Channel EA Removed"); } void OnTick() { double channelBuff[],channelBuff1[], middleBuff[]; CopyBuffer(donchianChannel,0,0,3,channelBuff); CopyBuffer(donchianChannel,1,0,3,channelBuff1); CopyBuffer(donchianChannel,2,0,3,middleBuff); double channelHigh=channelBuff1[0]; double channelMiddle=middleBuff[0]; double channelLow=channelBuff[0]; double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK); double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID); if(ask>channelHigh) { Comment("Buy Signal"); } else if(bid<channelLow) { Comment("Sell Signal"); } else Comment(" "); }
이 코드의 차이점은 다음과 같습니다:
ask와 bid에 대한 더블 변수를 생성한 후 속성(ask, bid) 값을 반환하는 SymbolInfoDouble 함수를 사용하여 ask와 bid를 정의합니다.
double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK); double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);
전략의 조건:
매수의 경우
ask와 채널 높이를 확인하여 이들의 위치를 결정하려면 프로그램이 필요합니다. 매도 호가가 채널 고점보다 크면 매수 조건이 되며 이 조건이 충족되면 EA가 차트에 코멘트로 매수 신호를 반환해야 합니다.
if(ask>channelHigh) { Comment("Buy Signal"); }
매도의 경우
bid와 채널 저점을 확인하여 포지션을 결정하려면 프로그램이 필요합니다. bid 가격이 채널 저점보다 낮으면 매도 조건이 되며 이 조건이 충족되면 EA가 차트에 코멘트로 매도 신호를 반환해야 합니다.
else if(bid<channelLow) { Comment("Sell Signal"); }
아무것도 없는 경우
아무것도 반환하지 않는 EA가 필요합니다.
else Comment(" ");
이 코드를 오류나 경고 없이 컴파일한 후 원하는 차트에 끌어다 놓아 실행하면 다음 예제와 같이 전략에 따른 신호를 얻을 수 있습니다:
매수 신호의 경우

이전 차트의 왼쪽 상단에서 볼 수 있듯이 채널 고점을 상승으로 돌파한 후 매수 신호가 있습니다.
매도 신호의 경우

이전 차트의 왼쪽 상단에서 볼 수 있듯이 채널 저점을 하방으로 돌파한 후 매도 신호가 있습니다.
아무것도 없는 경우

보시다시피 채널 내에서 가격이 움직일 때 신호가 없으므로 가격이 채널 고점의 아래에, 채널 저점의 위에 있음을 의미합니다.
돈치안 채널 및 MA 브레이크아웃:
이제 전략의 조건에 이동 평균을 추가하여 신호를 필터링하여 EA를 약간 개선해야 합니다. 이것이 이 거래 시스템에서 우리가 수행 할 작업입니다. 따라서 200일 EMA(지수이동평균)가 ask 밑에 있으면서 가격(ask)이 채널 고점을 돌파할 때 매수 신호를 받아야 합니다. 매도 신호의 경우 bid가 채널 저점을 하향 돌파하고 동시에 200일 이평선이 bid 위에 있는지 확인해야 합니다. 그 외에는 아무 신호도 받을 필요가 없습니다.
다음은 이러한 유형의 거래 시스템을 생성하는 전체 코드입니다:
input int indPeriod=20; //Period input int maPeriod=200; //Moving Average Period int donchianChannel; int EMA; double emaArray[]; int OnInit() { donchianChannel=iCustom(_Symbol,PERIOD_CURRENT,"My Files\\Donchian_Channel\\Donchian_Channel",indPeriod); EMA = iMA(_Symbol,_Period,maPeriod,0,MODE_EMA,PRICE_CLOSE); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { Print("Donchian Channel EA Removed"); } void OnTick() { double channelBuff[],channelBuff1[], middleBuff[]; CopyBuffer(donchianChannel,0,0,3,channelBuff); CopyBuffer(donchianChannel,1,0,3,channelBuff1); CopyBuffer(donchianChannel,2,0,3,middleBuff); ArraySetAsSeries(emaArray,true); CopyBuffer(EMA,0,0,3,emaArray); double channelHigh=channelBuff1[0]; double channelMiddle=middleBuff[0]; double channelLow=channelBuff[0]; double EMAValue=NormalizeDouble(emaArray[0],_Digits); double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK); double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID); if(ask>channelHigh&&ask>EMAValue) { Comment("Buy Signal","\nAsk above Channel High","\nAsk above (",maPeriod,") EMA"); } else if(bid<channelLow&&bid<EMAValue) { Comment("Sell Signal","\nBid below Channel Low","\nBid Below (",maPeriod,") EMA"); } else Comment(" "); }
이 코드의 차이점은 다음과 같습니다:
기본값(200)으로 maPeriod의 정수 변수 입력을 사용하지만 사용자가 기본 설정에 따라 업데이트할 수 있습니다.
input int maPeriod=200; //Moving Average Period
EMA의 전역 정수 변수를 만듭니다.
int EMA; emaArray[] 배열을 생성합니다.
double emaArray[]; 이동 평균 지표의 핸들을 반환하는 iMA 함수를 사용하여 EMA 변수를 업데이트합니다. 이때 해당 매개 변수는 다음과 같습니다:
- symbol: 심볼을 지정하면 현재 심볼에 적용될 (_Symbol)을 사용합니다.
- period: 현재 기간에 적용할 기간(_period)을 지정합니다.
- ma_period: 평균 기간을 지정하기 위해 사용자 입력(maPeriod)을 사용합니다.
- ma_shift: 쉬프트 이동 여부를 지정합니다. 우리는 쉬프트 이동이 필요하지 않으므로 (0)을 사용합니다.
- ma_method: 이동 평균 평활화 유형을 지정하기 위해 지수 이동 평균이 필요합니다. 그러므로 (MODE_EMA)를 사용합니다.
- applied_price: 가격 유형을 지정하려면 (PRICE_CLOSE)를 사용합니다.
EMA = iMA(_Symbol,_Period,maPeriod,0,MODE_EMA,PRICE_CLOSE);
ArraySetAsSeries 함수를 사용하여 AS_SERIES를 설정하는 매개 변수는 다음과 같습니다:
- array[]: 배열을 지정하기 위해 emaArray를 사용합니다.
- flag: 배열 인덱싱의 방향을 지정하려면 true를 사용합니다.
ArraySetAsSeries(emaArray,true);
CopyBuffer 함수를 사용하여 이동 평균 버퍼에서 데이터 가져오기
CopyBuffer(EMA,0,0,3,emaArray);
EMA 값 정의 및 정규화하기
double EMAValue=NormalizeDouble(emaArray[0],_Digits);
전략의 조건:
매수의 경우
가격 > 채널의 최고가인 경우 차트에 다음과 같은 코멘트가 필요합니다.
- 매수 신호
- 채널 하이 위에 ask
- (period)EMA 위에 ask
if(ask>channelHigh&&ask>EMAValue) { Comment("Buy Signal","\nAsk above Channel High","\nAsk above (",maPeriod,") EMA"); }
매도의 경우
채널의 가격 < 채널의 최저가인 경우 차트에 다음과 같은 코멘트가 필요합니다.
- 매도 신호
- 채널 최저가 아래에 bid
- (period) EMA 아래에 bid
else if(bid<channelLow&&bid<EMAValue) { Comment("Sell Signal","\nBid below Channel Low","\nBid Below (",maPeriod,") EMA"); }
신호가 없는 경우
else Comment(" ");
이 코드를 오류나 경고 없이 컴파일하면 다음과 같이 거래 시스템의 신호를 찾을 수 있습니다.
매수 신호의 경우

이전 예시에서 볼 수 있듯이 매수 신호와 이 신호의 조건인 가격이 채널 고점 이상이고 200 EMA를 충족하는 조건이 차트에 코멘트로 표시됩니다.
매도 신호의 경우

이전 예시에서 볼 수 있듯이 이 신호의 조건인 가격이 채널 저점 이하이고 200 EMA가 충족되는 조건이면 매도 신호가 차트에 코멘트로 표시되어 있습니다.
신호가 없는 경우

차트에서 볼 수 있듯이 가격이 200 EMA 아래에 있습니다. 이 경우 가격이 채널 저점 위나 채널 고점 아래에 있고 조건이 충족되지 않았으므로 나타내는 신호가 없습니다.
결론
이 글을 통해 우리는 지표가 가진 개념을 바탕으로 사용자 지정 지표로 직접 만들어 트레이딩 시스템을 만들어 보고 Donchian 채널 지표가 얼마나 유용하고 가치 있는 도구가 될 수 있는지 확인했습니다. 이는 여러분이 각자의 선호에 따라 사용자 정의 Donchian 채널 지표를 만들 수 있고 거래에 좋은 도구로 사용하는 것, 또한 iCustom 기능을 사용하여 거래 시스템을 만들어 거래하거나 지표의 해석을 기반으로 신호를 얻을 수 있을 뿐만 아니라 특정 조건을 추가하고 더 나은 통찰력을 얻기 위해 다른 기술 도구를 사용하여 결과를 향상시키 듯이 이 거래 시스템 (EA)을 향상시킬 수 있다는 것을 의미합니다.
이 기사가 여러분의 트레이딩 여정에서 더 나은 결과와 통찰력을 얻는 데 도움이 되고 다른 관련된 개념에 대한 좋은 통찰력을 얻는데 도움이 되었기를 바랍니다. 모든 사람에게 적합한 도구는 없습니다. 이 기사의 내용을 테스트하기 전에 실제 계정에서 바로 사용하지 마시고 다시 한 번 확인하는 것을 잊지 마시기 바랍니다.
이 기사가 유용했고 더 많은 기사를 읽고 싶다면 링크에서 다른 기사를 읽을 수 있습니다. 가장 인기있는 기술 지표를 기반으로 거래 시스템을 만드는 방법에 대한 일련의 기사를 찾을 수 있으며 다른 기사도 유용했으면 합니다.
MetaQuotes 소프트웨어 사를 통해 영어가 번역됨
원본 기고글: https://www.mql5.com/en/articles/12711
경고: 이 자료들에 대한 모든 권한은 MetaQuotes(MetaQuotes Ltd.)에 있습니다. 이 자료들의 전부 또는 일부에 대한 복제 및 재출력은 금지됩니다.
이 글은 사이트 사용자가 작성했으며 개인의 견해를 반영합니다. Metaquotes Ltd는 제시된 정보의 정확성 또는 설명 된 솔루션, 전략 또는 권장 사항의 사용으로 인한 결과에 대해 책임을 지지 않습니다.
HarmonyOS NEXT에 MetaTrader 5 및 기타 MetaQuotes 앱 설치
MQL5의 정량적 분석: 유망한 알고리즘 구현하기
MQL5를 사용하여 사용자 지정 Donchian 채널을 만드는 방법에 대한 새 문서가 게시되었습니다:
작성자: 모하메드 압델마부드
h ttps:// www.mql5.com/en/market/product/31082?source=Unknown