English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
preview
MQL5를 사용하여 사용자 지정 지표(헤이켄 아시)를 만드는 방법

MQL5를 사용하여 사용자 지정 지표(헤이켄 아시)를 만드는 방법

MetaTrader 5트레이딩 | 18 2월 2025, 12:58
319 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

소개

우리 모두는 차트를 읽어야 하며 이 작업에 도움이 될 수 있는 도구라면 우리는 어떤 것이든 환영할 것입니다. 차트를 읽는 데 도움이 될 수 있는 도구 중에는 가격, 거래량, 다른 기술 지표 또는 이들의 조합을 기반으로 계산되는 지표가 있습니다. 이 외에도 트레이딩 세계에는 많은 아이디어가 존재합니다. 트레이딩 터미널에는 내장 보조지표가 많이 있습니다. 만약 이들 지표에 우리의 거래 스타일에 맞게 일부 기능을 추가해야 하는 경우 변경이 불가능할 수 있습니다. 이외 우리가 필요로 하는 보조지표를 트레이딩 터미널에 내장된 보조지표에서는 찾지 못할 수도 있습니다.

이 글에서 저는 iCustom 함수를 활용해서 원하는 조건에 따라 사용자 지정 지표를 생성하여 이러한 문제를 극복하는 방법을 알려드리겠습니다. 우리는 사용자 지정 하이켄 아시 기술 지표를 만들고 거래 시스템 예제에서 이 사용자 지정 지표를 사용해 볼 것입니다. 다음과 같은 주제로 이에 대해 다뤄보겠습니다:

이전 주제에서 다루는 내용을 이해했다면 여러분은 차트를 읽는 데 도움이 되고 트레이딩 시스템에서 사용할 수 있는 사용자 지정 보조지표를 만드는 데에 도움이 될 것입니다. 우리는 MetaTrader 5 거래 플랫폼에 내장된 MQL5(MetaQuotes 언어)를 사용하여 생성할 보조지표와 EA 코드를 작성할 것입니다. 다운로드 및 사용 방법을 모르는 경우 이전 글에서 MetaEditor서 MQL5 코드 작성하기를 읽어보면 도움이 될 수 있습니다.

면책 조항: 여기의 모든 정보는 정보 제공의 목적으로만 '있는 그대로' 제공되며 거래의 목적이나 조언을 위해 준비된 것이 아닙니다. 여기의 정보는 어떤 종류의 결과도 보장하지 않습니다. 거래 계좌에서 이러한 자료를 사용하기로 선택한 경우 이에 대한 책임은 전적으로 귀하에게 있으며 이에 대한 책임은 전적으로 귀하에게 있습니다.

사용자 지정 지표 및 하이켄 아시 정의

이 부분에서는 사용자 지정 지표와 하이켄 아시 지표에 대해 자세히 알아보겠습니다. 이전 섹션의 소개에서 언급했듯이 사용자 지정 보조지표는 MQL5 프로그래밍 언어를 사용하여 사용자가 만들 수 있는 기술적 분석 도구이며 MetaTrader 5에서 시장 움직임을 분석하고 이해하는 데 사용할 수 있으며 정보에 입각한 투자 결정을 내리는 데 도움을 줄 수 있습니다. 유용한 기본 제공 보조지표가 많이 있지만 때로는 추가적이고 구체적인 수학적, 통계적 또는 기술적 개념을 기반으로 시장이 어떻게 움직이는지 분석하고 이해해야 하는데 이러한 개념이 기본 제공되는 보조지표에 없거나 해당 작업을 수행할 수 있는 보조지표가 없는 경우가 있습니다. 따라서 이러한 경우 우리는 지표를 직접 만들어야 하며 이는 특정 선호도와 목표를 충족하는 자체 분석 또는 거래 도구를 만드는 데 도움이 되는 MetaTrader 5 플랫폼의 중요 기능 중 하나입니다.

이제 사용자 지정 지표를 만드는 데 필요한 단계를 살펴보겠습니다:

MetaEditor IDE를 열고 네비게이터에서 '지표' 폴더를 선택합니다.

지표 폴더

아래 그림과 같이 '새로 만들기' 버튼을 클릭하여 새 프로그램을 만듭니다.

새 버튼

그 후 생성할 프로그램 유형을 선택해야 하는 다음과 같은 창이 열립니다. 여기서는 '사용자 지정 지표'를 선택합니다.

프로그램 선택

'다음'을 클릭하면 지표 세부 정보가 표시된 다음과 같은 창이 열립니다. 여기에서 사용자 지정 지표의 이름을 지정한 후 '다음'을 클릭합니다.

지표 세부 정보

다음 창에서 더 많은 지표 세부 정보를 결정합니다.

지표 세부 정보2

지표 세부 정보3

환경 설정 설정을 완료하고 '다음'을 클릭한 다음 '마침'을 클릭하면 에디터 창이 열리고 여기서 사용자 지정 지표의 코드를 작성할 수 있습니다.

하이켄 아시를 예로 들어 사용자 지정 지표를 개발하는 방법을 살펴보겠습니다. 그전에 하이켄 아시 기술 지표에 대해 자세히 알아볼 필요가 있습니다. 이 지표는 캔들형 차트는 시장 움직임을 표시하고 분석하는 데 사용할 수 있는 캔들형 차트의 방법으로 다른 도구와 함께 사용하면 효과적이고 더 나은 통찰력을 얻을 수 있으며 우리는 이를 바탕으로 좋은 잠재적 거래 아이디어와 기회를 찾은 후 정보에 입각한 거래 결정을 내릴 수 있습니다.

하이켄 아시 차트는 일반적인 캔들 차트와 비슷하지만 이 캔들을 그리는 계산은 다릅니다. 두 가지 방법이 있습니다. 아시다시피 일반 캔들 차트는 특정 기간의 실제 시가, 고가, 저가, 종가를 기준으로 가격을 계산하지만 하이켄 아시는 캔들 계산 시 이전 유사 가격(시가, 고가, 저가, 종가)의 가격을 고려합니다.

헤이켄 아시의 관련 값을 계산하는 방법은 다음과 같습니다:

  • 시가 = (이전 캔들 시가 + 이전 캔들 종가) / 2
  • 종가 = (현재 캔들의 시가 + 종가 + 고가 + 저가) / 4
  • 높음 = 현재 기간의 고가, 시가 또는 종가 중 가장 높은 값입니다.
  • 낮음 = 현재 기간의 저점, 시가 또는 종가 중 가장 낮은 값입니다.

이러한 계산을 기반으로 지표는 상승 및 하락 캔들을 구성하며 이 캔들의 색상은 시장의 관련 방향(강세 또는 약세)을 나타냅니다. 아래는 일본 전통 캔들과 헤이켄 아시를 보여주는 예시입니다. 시각적인 관점에서 차이점을 확인해 보세요.

 ha 지표

이전 차트 스크린샷에서 상단에는 전통적인 캔들이 표시되어 있고 하단에는 시장 방향을 정의하는 파란색과 빨간색 캔들로 표시되는 하이켄 아시 지표가 있습니다. 계산에 따르면 이 지표의 목적은 잘못된 신호를 피하기 위해 데이터를 평활화하여 시장 움직임의 일부 노이즈를 필터링하고 제거하는 것입니다.


간단한 하이켄 아시 지표

이 파트에서는 MetaTrader 5에서 사용할 간단한 하이켄 아시 지표를 만들어 보겠습니다. 지표는 가격(시가, 고가, 저가, 종가)을 지속적으로 확인하고 수학적 계산을 수행하여 haOpen, haHigh, haLow, haClose 값을 생성해야 합니다. 계산에 따라 지표는 차트에 캔들 방향이 캔들인 경우 파란색, 약세인 경우 빨간색 등 다양한 색상의 캔들 스틱으로 값을 표시해야 합니다. 캔들 스틱은 기존 차트 아래 별도의 창에 하위 창으로 표시되어야 합니다.

이 사용자 지정 지표를 만들기 위해 완료해야 하는 모든 단계를 살펴보겠습니다.

속성 및 식별자 값을 통해 다음과 같이 추가 매개변수를 지정하여 지표의 설정을 결정할 수 있습니다:

  • (indicator_separate_window)를 사용하여 별도의 창에 지표를 표시할 수도 있습니다.
  • (indicator_buffers)를 사용하여 지표 계산을 위한 버퍼 수를 결정합니다.
  • (indicator_plots)를 사용하여 지표의 그래픽 시리즈의 수를 결정합니다. 그래픽 시리즈는 사용자 지정 지표를 만들 때 사용할 수 있는 그리기 스타일입니다.
  • (indicator_typeN)의 값에서 그래픽 플롯의 유형을 결정하기 위해 (ENUM_DRAW_TYPE)을 사용하며 N은 마지막 매개변수에서 결정한 그래픽 계열의 수이며 1부터 시작합니다.
  • (indicator_colorN)을 사용하여 N의 색상을 결정하며 N은 앞서 결정한 그래픽 계열의 수이며 1부터 시작됩니다.
  • (indicator_widthN)을 사용하여 N 또는 그래픽 계열의 두께도 결정할 수 있습니다.
  • (indicator_labelN)을 사용하여 결정된 그래픽 계열의 N에 대한 레이블을 설정합니다.
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   1
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_color1  clrBlue, clrRed
#property indicator_width1  2
#property indicator_label1  "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close"

지표의 5개 버퍼(haOpen, haHigh, haLow, haClose, haColor)에 대해 더블 유형으로 5개의 배열을 생성합니다.

double haOpen[];
double haHigh[];
double haLow[];
double haClose[];
double haColor[];

OnInit() 내에서 이 함수는 실행 중인 지표를 초기화하는 데 사용됩니다.

int OnInit()

(SetIndexBuffer) 함수를 사용하여 더블 타입의 1차원 동적 배열로 지표 버퍼를 정렬합니다. 매개변수는 다음과 같습니다:

  • index: 0부터 시작하는 지표 버퍼의 숫자이며 이 숫자는 (indicator_buffers)의 결정된 매개변수에 선언된 값보다 작아야 합니다.
  • buffer[]: 커스텀 지표에 선언된 배열입니다.
  • data_type: 지표 배열에 저장해야 하는 데이터 유형입니다.
   SetIndexBuffer(0,haOpen,INDICATOR_DATA);
   SetIndexBuffer(1,haHigh,INDICATOR_DATA);
   SetIndexBuffer(2,haLow,INDICATOR_DATA);
   SetIndexBuffer(3,haClose,INDICATOR_DATA);
   SetIndexBuffer(4,haColor,INDICATOR_COLOR_INDEX);

속성 식별자를 지정하는 호출 변형과 함께 (IndicatorSetInteger) 함수를 사용하여 해당 지표 속성의 값을 설정합니다. 매개변수는 다음과 같습니다:

  • prop_id: 속성의 식별자 (ENUM_CUSTOMIND_PROPERTY_INTEGER) 중 하나가 될 수 있으며 (INDICATOR_DIGITS)를 지정합니다.
  • prop_value: 속성의 값으로 (_Digits)를 지정합니다.
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);

속성 식별자를 지정하는 호출의 변형으로 해당 문자열 유형 속성의 값을 설정합니다. 매개변수는 다음과 같습니다:

  • prop_id: 속성의 식별자로 (ENUM_CUSTOMIND_PROPERTY_STRING) 중 하나가 될 수 있으며 지표의 짧은 이름을 사용하려면 (INDICATOR_SHORTNAME)을 지정합니다.
  • prop_value: 속성의 값으로 우리는 ("Simple Heiken Ashi")로 할 것입니다.
   IndicatorSetString(INDICATOR_SHORTNAME,"Simple Heiken Ashi");

(PlotIndexSetDouble) 함수를 사용하여 해당 지표의 해당 더블 유형 속성 값을 설정합니다. 매개변수는 다음과 같습니다:

  • plot_index: 그래픽 플로팅의 인덱스, 0을 지정합니다.
  • prop_id: (ENUM_PLOT_PROPERTY_DOUBLE) 값 중 하나이며 그림이 없는 경우 (PLOT_EMPTY_VALUE)가 됩니다.
  • prop_value: 속성의 값입니다.
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);

그런 다음 초기화 성공 여부를 반환하여 함수를 종료하려면 OnInit() 함수의 일부로 (INIT_SUCCEED)를 반환합니다.

   return(INIT_SUCCEEDED);

가격 데이터를 처리하기 위해 지표에서 호출되는 OnCalculate 함수 내에서 현재 시간대 시계열을 기준으로 계산 유형이 변경됩니다.

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[])

정수 'start' 변수를 생성. 우리는 나중에 해당 값을 할당합니다:

int start;

'if' 문을 사용하여 인덱스 값(낮음, 높음, 열기, 닫기)과 start value=1을 반환하려면 prev_c계산된 값이 0이거나 (prev_c계산된-1)에 할당된 시작 값을 반환합니다:

   if(prev_calculated==0)
     {
      haLow[0]=low[0];
      haHigh[0]=high[0];
      haOpen[0]=open[0];
      haClose[0]=close[0];
      start=1;
     }
   else
      start=prev_calculated-1;

계산을 위한 메인 루프에 'for' 함수를 사용합니다. 'for' 연산자는 세 가지 표현식과 실행 연산자로 구성됩니다.

세 가지 표현식이 있습니다:

  • i=start: 시작 위치입니다.
  • i<rates_total && !IsStopped(): 조건이 루프를 완료하도록 합니다. IsStopped()는 지표의 강제 종료를 확인합니다.
  • i++: 1을 더하면 새로운 i가 됩니다.

루프 중에 매번 실행해야 하는 작업입니다:

이중 네 가지 변수에 대한 계산

  • haOpenVal: 하이켄 아시 오픈 값입니다.
  • haCloseVal: 하이켄 아시 종가 값입니다.
  • haHighVal: 하이켄 아시의 고가 입니다.
  • haLowVal: 하이켄 아시의 저가 입니다.

이전 단계에서 계산된 값을 할당하는 방법은 다음과 같습니다.

  • haLow[i]=haLowVal
  • haHigh[i]=haHighVal
  • haOpen[i]=haOpenVal
  • haClose[i]=haCloseVal

하이켄 아시의 시가가 종가보다 낮은지 확인하면 지표는 파란색 캔들을 그리고 그렇지 않은 경우 빨간색 캔들을 그립니다.

   for(int i=start; i<rates_total && !IsStopped(); i++)
     {
      double haOpenVal =(haOpen[i-1]+haClose[i-1])/2;
      double haCloseVal=(open[i]+high[i]+low[i]+close[i])/4;
      double haHighVal =MathMax(high[i],MathMax(haOpenVal,haCloseVal));
      double haLowVal  =MathMin(low[i],MathMin(haOpenVal,haCloseVal));

      haLow[i]=haLowVal;
      haHigh[i]=haHighVal;
      haOpen[i]=haOpenVal;
      haClose[i]=haCloseVal;

      //--- set candle color
      if(haOpenVal<haCloseVal)
         haColor[i]=0.0;
      else
         haColor[i]=1.0;
     }

다음 호출을 위해 (rates_total)을 prev_calculated로 반환하여 함수를 종료합니다.

return(rates_total);

그런 다음 코드를 컴파일하여 오류가 없는지 확인합니다. 다음은 한 블록의 전체 코드입니다:

//+------------------------------------------------------------------+
//|                                             simpleHeikenAshi.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   1
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_color1  clrBlue, clrRed
#property indicator_width1  2
#property indicator_label1  "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close"
double haOpen[];
double haHigh[];
double haLow[];
double haClose[];
double haColor[];
int OnInit()
  {
   SetIndexBuffer(0,haOpen,INDICATOR_DATA);
   SetIndexBuffer(1,haHigh,INDICATOR_DATA);
   SetIndexBuffer(2,haLow,INDICATOR_DATA);
   SetIndexBuffer(3,haClose,INDICATOR_DATA);
   SetIndexBuffer(4,haColor,INDICATOR_COLOR_INDEX);
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
   IndicatorSetString(INDICATOR_SHORTNAME,"Simple Heiken Ashi");
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   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[])
  {
   int start;
   if(prev_calculated==0)
     {
      haLow[0]=low[0];
      haHigh[0]=high[0];
      haOpen[0]=open[0];
      haClose[0]=close[0];
      start=1;
     }
   else
      start=prev_calculated-1;
   for(int i=start; i<rates_total && !IsStopped(); i++)
     {
      double haOpenVal =(haOpen[i-1]+haClose[i-1])/2;
      double haCloseVal=(open[i]+high[i]+low[i]+close[i])/4;
      double haHighVal =MathMax(high[i],MathMax(haOpenVal,haCloseVal));
      double haLowVal  =MathMin(low[i],MathMin(haOpenVal,haCloseVal));

      haLow[i]=haLowVal;
      haHigh[i]=haHighVal;
      haOpen[i]=haOpenVal;
      haClose[i]=haCloseVal;
      if(haOpenVal<haCloseVal)
         haColor[i]=0.0;
      else
         haColor[i]=1.0;
     }
   return(rates_total);
  }

오류 없이 컴파일이 완료되면 다음 그림과 같이 내비게이터 창의 '지표' 폴더에서 지표를 사용할 수 있게 됩니다.

간단한HA 탐색

그런 다음 더블 클릭하여 원하는 차트에서 실행하면 지표 정보의 공통 창이 나타납니다:

 간단한HA 윈

색상 탭에는 기본 설정으로 위로 이동 시 파란색 아래로 이동 시 빨간색이 표시됩니다. 필요한 경우 이 값을 편집하여 원하는 색상을 설정할 수 있습니다. 이 탭은 다음과 같이 표시됩니다:

 simpleHA win2

확인을 누르면 지표가 차트에 첨부되고 아래 그림과 같이 표시됩니다:

simpleHA 첨부

이전 차트에서 볼 수 있듯이 차트에 별도의 하위 창에 단순 하이켄 아시 지표가 삽입되어 있습니다. 캔들의 방향(황소와 곰)에 따라 파란색과 빨간색 캔들이 있습니다. 이제 우리에게는 MetaTrader 5에서 만든 사용자 지정 보조지표가 있으며 모든 트레이딩 시스템에서 이 사용자 지정 보조지표를 사용할 수 있습니다. 다음 주제에서 이를 쉽게 수행할 수 있는 방법을 살펴보겠습니다.


사용자 지정 하이켄 아시 지표 기반 EA

이 부분에서는 트레이딩 시스템 EA에서 사용자 지정 보조지표를 사용하는 방법을 알아보겠습니다. 우리는 지표의 가격(시가, 고가, 저가, 종가)을 표시할 수 있는 간단한 하이켄 아시 시스템을 만들겠습니다. 우리는 이들 지표의 가격이 지표의 계산에 따라 실제 가격과 다르다는 것을 이미 알고 있습니다.

이를 수행하는 방법은 새로운 Expert Advisor를 만드는 것입니다. 아래는 전체 코드입니다:

//+------------------------------------------------------------------+
//|                                             heikenAshiSystem.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
int heikenAshi;
int OnInit()
  {
   heikenAshi=iCustom(_Symbol,_Period,"My Files\\Heiken Ashi\\simpleHeikenAshi");
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("Heiken Ashi System Removed");
  }
void OnTick()
  {
   double heikenAshiOpen[], heikenAshiHigh[], heikenAshiLow[], heikenAshiClose[];
   CopyBuffer(heikenAshi,0,0,1,heikenAshiOpen);
   CopyBuffer(heikenAshi,1,0,1,heikenAshiHigh);
   CopyBuffer(heikenAshi,2,0,1,heikenAshiLow);
   CopyBuffer(heikenAshi,3,0,1,heikenAshiClose);
   Comment("heikenAshiOpen ",DoubleToString(heikenAshiOpen[0],_Digits),
           "\n heikenAshiHigh ",DoubleToString(heikenAshiHigh[0],_Digits),
           "\n heikenAshiLow ",DoubleToString(heikenAshiLow[0],_Digits),
           "\n heikenAshiClose ",DoubleToString(heikenAshiClose[0],_Digits));
  }

이 코드에서의 차이점:

프로그램 유형은 Expert Advisor입니다. 따라서 이 프로그램의 구성은 다음과 같이 세가지 부분으로 나뉘어져 있습니다:

  • int OnInit(): 정수를 반환하는 권장 유형으로 EA 실행을 초기화하는 데 사용됩니다.
  • void OnDeinit: 값을 반환하지 않는 EA의 실행을 초기화하는 데 사용됩니다.
  • void OnTick(): 매 틱마다 새로운 쿼트를 처리하는 데 사용되며 값을 반환하지 않습니다.

이전 함수의 범위를 벗어나 우리는 그 앞에 정수 변수(heikenAshi)를 만들었습니다.

int heikenAshi;

OnInit()의 범위 내에서 iCustom 함수의 값을 'heikenAshi' 변수에 할당했습니다. iCustom 함수는 사용자 지정 지표의 핸들을 반환하는데 여기서는 심플 하이켄 아시가 되겠지만 지표 폴더에 있는 모든 사용자 지정 지표를 사용할 수도 있습니다. 매개변수는 다음과 같습니다:

  • symbol: 심볼 이름, 우리는 현재 심볼 (_Symbol)을 사용했습니다.
  • period: 차트 주기, 우리는 현재 차트 주기 (_Period)를 사용했습니다.
  • name: 사용자 지정 보조지표의 이름과 MetaTrader 5의 지표 폴더 경로이며 여기서는 "My Files\\Heiken Ashi\\simpleHeikenAshi"를 사용했습니다.

그런 다음 초기화에 성공하면 (INIT_SUCCEED)를 반환하여 함수를 종료했습니다.

int OnInit()
  {
   heikenAshi=iCustom(_Symbol,_Period,"My Files\\Heiken Ashi\\simpleHeikenAshi");
   return(INIT_SUCCEEDED);
  }

OnDeinit() 함수의 범위 내에서 프린트 함수를 사용하여 EA가 제거되었음을 알렸습니다.

void OnDeinit(const int reason)
  {
   Print("Heiken Ashi System Removed");
  }

OnTick() 함수 범위 내에서 다음을 사용하여 코드를 완성했습니다:

하이켄 아시 가격에 대한 네 가지 더블 유형 변수 만들기(시가, 고가, 저가, 종가)

   double heikenAshiOpen[], heikenAshiHigh[], heikenAshiLow[], heikenAshiClose[];

복사 버퍼 함수를 사용하여 사용자 지정 지표의 버퍼 데이터를 가져옵니다. 매개변수는 다음과 같습니다:

  • indicator_handle: 지표 핸들, (heikenAshi)를 사용했습니다.
  • buffer_num: 지표 버퍼 번호(0은 시가, 1은 고가, 2는 저가, 3은 종가)를 사용했습니다.
  • start_pos: 복사할 첫 번째 요소 위치로 현재 요소에는 0을 사용했습니다.
  • count: 복사할 데이터의 양. 여기서는 1을 사용했으며 그 이상은 필요하지 않습니다.
  • buffer[]: 복사할 배열(시가는 heikenAshiOpen, 고가는 heikenAshiHigh, 저가는 heikenAshiLow, 종가는 heikenAshiClose)을 사용했습니다.

코멘트함수를 사용하여 현재 헤이켄 아시 가격(시가, 고가, 저가, 종가)이 표시된 차트에 코멘트를 달 수 있습니다:

   Comment("heikenAshiOpen ",DoubleToString(heikenAshiOpen[0],_Digits),
           "\n heikenAshiHigh ",DoubleToString(heikenAshiHigh[0],_Digits),
           "\n heikenAshiLow ",DoubleToString(heikenAshiLow[0],_Digits),
           "\n heikenAshiClose ",DoubleToString(heikenAshiClose[0],_Digits));

이 코드를 오류 없이 컴파일하고 실행하면 차트에 첨부된 EA를 찾을 수 있습니다. 다음 테스트 예제와 같은 신호를 수신할 수 있습니다:

 haSystem

이전 차트에서 볼 수 있듯이 지표 가격이 차트 왼쪽 상단에 코멘트로 표시되어 있습니다.


하이켄 아시 - EMA 시스템

이 주제에서는 다른 기술 도구를 결합하여 결과가 더 나은지 여부를 확인합니다. 우리의 아이디어는 가격과 함께 지수 이동 평균을 사용하여 사용자 지정 지표의 신호를 필터링하는 것입니다. EMA에 더 많은 기능을 추가하려면 또 다른 사용자 지정 지표인 EMA를 만든 다음 iCustom으로 사용할 수 있습니다. 또한 지표의 값을 평활화한 다음 신호를 가져와서 평활화된 지표를 만들 수도 있습니다. EA에 내장된 iMA 기능을 사용하여 신호를 가져올 수 있으며 여기서는 단순함을 위해 이 방법을 사용하겠습니다.

우리가 해야 할 일은 EA가 현재 2개의 EMA(패스트 및 슬로우)와 이전 패스트 EMA 및 하이켄 아시의 값을 지속적으로 확인하여 모든 값의 위치를 결정하도록 하는 것입니다. 이전 heikenAshiClose가 이전 fastEMAarray보다 크고 현재 fastEMA가 현재 slowEMA 값보다 크면 EA는 매수 신호와 이 값을 차트에 코멘트로 반환해야 합니다. 이전 heikenAshiClose가 이전 fastEMAarray보다 낮고 현재 fastEMA가 현재 slowEMA 값보다 낮으면 EA는 매도 신호와 이 값을 차트에 코멘트로 반환해야 합니다.

다음은 이 EA를 생성하는 전체 코드입니다:

//+------------------------------------------------------------------+
//|                                          heikenAsh-EMASystem.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
input int fastEMASmoothing=9; // Fast EMA Period
input int slowEMASmoothing=18; // Slow EMA Period
int heikenAshi;
double fastEMAarray[], slowEMAarray[];
int OnInit()
  {
   heikenAshi=iCustom(_Symbol,_Period,"My Files\\Heiken Ashi\\simpleHeikenAshi");
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("Heiken Ashi-EMA System Removed");
  }
void OnTick()
  {
   double heikenAshiOpen[], heikenAshiHigh[], heikenAshiLow[], heikenAshiClose[];
   CopyBuffer(heikenAshi,0,0,3,heikenAshiOpen);
   CopyBuffer(heikenAshi,1,0,3,heikenAshiHigh);
   CopyBuffer(heikenAshi,2,0,3,heikenAshiLow);
   CopyBuffer(heikenAshi,3,0,3,heikenAshiClose);
   int fastEMA = iMA(_Symbol,_Period,fastEMASmoothing,0,MODE_SMA,PRICE_CLOSE);
   int slowEMA = iMA(_Symbol,_Period,slowEMASmoothing,0,MODE_SMA,PRICE_CLOSE);
   ArraySetAsSeries(fastEMAarray,true);
   ArraySetAsSeries(slowEMAarray,true);
   CopyBuffer(fastEMA,0,0,3,fastEMAarray);
   CopyBuffer(slowEMA,0,0,3,slowEMAarray);
   if(heikenAshiClose[1]>fastEMAarray[1])
     {
      if(fastEMAarray[0]>slowEMAarray[0])
        {
         Comment("Buy Signal",
                 "\nfastEMA ",DoubleToString(fastEMAarray[0],_Digits),
                 "\nslowEMA ",DoubleToString(slowEMAarray[0],_Digits),
                 "\nprevFastEMA ",DoubleToString(fastEMAarray[1],_Digits),
                 "\nprevHeikenAshiClose ",DoubleToString(heikenAshiClose[0],_Digits));
        }
     }
   if(heikenAshiClose[1]<fastEMAarray[1])
     {
      if(fastEMAarray[0]<slowEMAarray[0])
        {
         Comment("Sell Signal",
                 "\nfastEMA ",DoubleToString(fastEMAarray[0],_Digits),
                 "\nslowEMA ",DoubleToString(slowEMAarray[0],_Digits),
                 "\nprevFastEMA ",DoubleToString(fastEMAarray[1],_Digits),
                 "\nheikenAshiClose ",DoubleToString(heikenAshiClose[0],_Digits));
        }
     }
  }

이 코드의 차이점은 다음과 같습니다:

사용자 기본 설정에 따라 빠른 EMA 기간과 느린 EMA 기간을 설정하는 사용자 입력을 생성합니다.

input int fastEMASmoothing=9; // Fast EMA Period
input int slowEMASmoothing=18; // Slow EMA Period

fastEMA와 slowEMA를 위한 두 개의 배열을 생성합니다.

double fastEMAarray[], slowEMAarray[];

복사할 데이터의 양을 CopyBuffer에서 3으로 설정하여 하이켄 아시 지표의 이전 종가 값을 가져옵니다.

   CopyBuffer(heikenAshi,0,0,3,heikenAshiOpen);
   CopyBuffer(heikenAshi,1,0,3,heikenAshiHigh);
   CopyBuffer(heikenAshi,2,0,3,heikenAshiLow);
   CopyBuffer(heikenAshi,3,0,3,heikenAshiClose);

이동평균 지표의 핸들을 반환하는 iMA의 내장 함수를 사용하여 빠르고 느린 EMA를 정의합니다. 매개변수는 다음과 같습니다:

  • symbol: 심볼 이름, 현재 심볼인 (_Symbol)을 사용했습니다.
  • period: 차트 주기. 현재 차트 주기인 (_Period)를 사용했습니다.
  • ma_period: 평균을 평활화하는 데 필요한 기간으로 (fastEMASmoothing 및 slowEMASmoothing) 입력을 사용했습니다.
  • ma_shift: 지표의 시프트, 0을 사용했습니다.
  • ma_method: 이동평균의 유형으로, 단순 이동평균에는 MODE_SMA를 사용했습니다.
  • applied_price: 계산에 필요한 가격 유형으로 여기서는 PRICE_CLOSE를 사용했습니다.
   int fastEMA = iMA(_Symbol,_Period,fastEMASmoothing,0,MODE_SMA,PRICE_CLOSE);
   int slowEMA = iMA(_Symbol,_Period,slowEMASmoothing,0,MODE_SMA,PRICE_CLOSE);

ArraySetAsSeries 함수를 사용하여 AS_SERIES 플래그를 설정합니다. 매개변수는 다음과 같습니다:

  • array[]: 배열, 우리는 (fastEMAarray와 slowEMA를 사용했습니다.)
  • flag: 배열 인덱싱 방향입니다. 우리는 참을 사용했습니다.
   ArraySetAsSeries(fastEMAarray,true);
   ArraySetAsSeries(slowEMAarray,true);

CopyBuffer 함수를 사용하여 EMA 지표의 버퍼 데이터를 가져옵니다.

   CopyBuffer(fastEMA,0,0,3,fastEMAarray);
   CopyBuffer(slowEMA,0,0,3,slowEMAarray);

'if' 문을 사용하여 신호를 반환하는 조건입니다:

매수 신호의 경우

이전 heikenAshiClose > 이전 fastEMAarray, 현재 fastEMAarray > 현재 slowEMAarray인 경우 EA는 매수 신호와 다음 값들을 반환해야 합니다:

  • fastEMA
  • slowEMA
  • prevFastEMA
  • prevHeikenAshiClose
   if(heikenAshiClose[1]>fastEMAarray[1])
     {
      if(fastEMAarray[0]>slowEMAarray[0])
        {
         Comment("Buy Signal",
                 "\nfastEMA ",DoubleToString(fastEMAarray[0],_Digits),
                 "\nslowEMA ",DoubleToString(slowEMAarray[0],_Digits),
                 "\nprevFastEMA ",DoubleToString(fastEMAarray[1],_Digits),
                 "\nprevHeikenAshiClose ",DoubleToString(heikenAshiClose[0],_Digits));
        }

매도 신호의 경우

이전 heikenAshiClose < 이전 fastEMAarray, 현재 fastEMAarray < 현재 slowEMAarray인 경우 EA는 매도 신호와 가격 값들을 반환해야 합니다:

  • fastEMA
  • slowEMA
  • prevFastEMA
  • prevHeikenAshiClose
   if(heikenAshiClose[1]<fastEMAarray[1])
     {
      if(fastEMAarray[0]<slowEMAarray[0])
        {
         Comment("Sell Signal",
                 "\nfastEMA ",DoubleToString(fastEMAarray[0],_Digits),
                 "\nslowEMA ",DoubleToString(slowEMAarray[0],_Digits),
                 "\nprevFastEMA ",DoubleToString(fastEMAarray[1],_Digits),
                 "\nheikenAshiClose ",DoubleToString(heikenAshiClose[0],_Digits));
        }
     }

이 코드를 컴파일하고 실행하면 다음 테스트 예제와 같은 신호를 얻을 수 있습니다.

매수 신호의 경우:

HA, 2EMA - 매수 신호

이전 차트와 마찬가지로 왼쪽 상단 모서리에 다음과 같은 신호가 코멘트로 표시됩니다:

  • 매수 신호.
  • fastEMA
  • prevFastEMA
  • prevHeikenAshiClose

매도 신호의 경우:

2EMA를 사용한 HA- 매도

차트에는 다음과 같은 값이 신호로 표시됩니다:

  • 매도 신호
  • fastEMA
  • prevFastEMA
  • prevHeikenAshiClose

결론

이 기사에서 설명한 모든 내용을 이해하셨다면 이제 여러분 자신만의 사용자 지정 Heiken Ashi 지표를 만들거나 기본 설정에 따라 더 많은 기능을 추가할 수 있습니다. 이는 차트를 읽고 이해를 바탕으로 효과적인 의사 결정을 내리는 데 매우 유용합니다. 또한 두 개의 트레이딩 시스템에서 예시로 살펴보았습니다. 이 생성된 사용자 지정 지표를 트레이딩 시스템에서 사용할 수 있습니다.

  • 하이켄 아시 시스템
  • 하이켄 아시-EMA 시스템

이 글이 도움이 되셨기를 바라며 해당 주제 또는 관련 주제에 대한 좋은 인사이트를 얻으셨기를 바랍니다. 실습은 효과적인 교육 과정에서 매우 중요한 요소이므로 프로그래밍의 학습 여정에 매우 유용합니다. 이 글에서 배운 내용을 적용해 보시기 바랍니다. 이 글이나 다른 리소스에서 배운 내용은 본인에게 적합하지 않을 경우 좋은 결과가 아닐 수 있습니다. 실제 계정에서 사용하기 전에 반드시 테스트해 보시기 바랍니다. 이 글의 주된 목적은 교육용입니다.

이 글이 유용했고 더 많은 글을 읽고 싶다면 제가 작성한 다른글을 통해 더 많은 주제를 읽어 보실 수 있습니다. 여러분도 유용하게 사용하시길 바랍니다.

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

모집단 최적화 알고리즘: 하모니 검색(HS) 모집단 최적화 알고리즘: 하모니 검색(HS)
이번 기사에서는 완벽한 하모니를 찾는 과정에서 영감을 얻은 가장 강력한 최적화 알고리즘인 하모닉 서치(HS)에 대해 알아보고 테스트해 보겠습니다. 현재 평가에서 선두를 달리고 있는 알고리즘은 무엇일까요?
MQL5를 사용하여 트렌드 및 차트 패턴을 감지하는 방법 MQL5를 사용하여 트렌드 및 차트 패턴을 감지하는 방법
이 글에서는 추세(상승추세, 하락추세, 횡보), 차트 패턴(더블 탑, 더블 바텀)과 같은 가격 움직임의 패턴을 MQL5로 자동 감지하는 방법을 알아보겠습니다.
모집단 최적화 알고리즘: 원숭이 알고리즘(MA) 모집단 최적화 알고리즘: 원숭이 알고리즘(MA)
이 글에서는 원숭이 알고리즘(MA) 최적화 알고리즘에 대해 알아보겠습니다. 원숭이들이 어려운 장애물을 극복하고 가장 접근하기 어려운 나무 꼭대기에 도달하는 능력은 MA 알고리즘의 아이디어의 기초가 되었습니다.
재구매 알고리즘: 다중 통화 거래 시뮬레이션 재구매 알고리즘: 다중 통화 거래 시뮬레이션
이 기사에서 우리는 다중 통화 가격 시뮬레이션을 위한 수학적 모델을 만들고 이전 기사에서 이론적인 계산으로 시작한 거래 효율성을 높이기 위한 메커니즘 탐색의 일환으로 다각화 원칙에 대한 연구를 완료할 것입니다.