English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
Haiken-Ashi(평균족) 인디케이터에 기반한 매매 시스템 예시

Haiken-Ashi(평균족) 인디케이터에 기반한 매매 시스템 예시

MetaTrader 5 | 5 7월 2021, 15:17
108 0
Dmitry Voronkov
Dmitry Voronkov

들어가며

20여 년 전 미국에서 캔들스틱 차트가 등장하면서 서양 시장에서 강세와 약세가 어떻게 작용하는지에 대한 이해에 혁명이 일어났습니다. 캔들스틱은 인기 있는 트레이딩 도구가 되었고, 트레이더들은 차트 독해를 더 쉽게 하기 위해서 캔들스틱을 활용하기 시작했습니다. 하지만 캔들스틱의 해석에는 여러 방법이 있습니다.

전통적인 캔들스틱 차트를 변형시키고 더 쉽게 이해하게해주는 방법들 중 하나가 Heiken-Ashi 기술이라고 불립니다.

1. «나니데스까?»*

이 주제에 대한 첫 출판은 Dan Valcu가 2004년 2월호 «주식 & 상품의 기술적 분석» 저널에 «Heikin Ashi 기술의 사용» (원문 링크)을 기고하면서 이루어졌습니다.

그의 홈페이지에서 저자는 2003년 여름 동안 이치모쿠의 기술을 연구했으며, 종종 우연히 몇 개의 도표를 발견했는데, 그 도표를 통해 시장의 흐름을 분명히 볼 수 있었다고 주장합니다. 그것이 Heikin-Ashi 도표로, 좀 더 정확하게 말하자면 변형된 캔들스틱으로 밝혀졌습니다.

이 분석 방법은 매우 성공적이었던 일본인 트레이더에 의해 개발되었으며 오늘날까지도 쓰이고 있습니다. 놀랍게도 저자는 이에 대한 내용을 어떠한 책이나 인터넷에서도 찾을 수가 없었기 때문에 저널에 기고하는 것으로 모든 트레이더들에게 공유하고자 했습니다

Haikin-Ashi법 ( heikin 는 일본어로 "중간" 혹은 "균형"을 의미하며 ashi 는 "발" 혹은 "바"를 의미), 이는 트렌드, 방향 및 강도를 분석하는 시각적 툴입니다. 이는 트레이딩의 "치트키"는 아니지만 트렌드를 시각화하는데에 쓰기 쉽고 좋은 도구입니다.

OHLC 캔들스틱 값이 어떻게 계산되는가 한 번 보도록 합시다.

현재 바의 청산: haClose = (Open + High + Low + Close) / 4
현재 바의 개방: haOpen = (haOpen [before.] + HaClose [before]) / 2
현재 바의 최대값: haHigh = Max (High, haOpen, haClose)
현재 바의 최소값: haLow = Min (Low, haOpen, haClose)

"Open," "High," "Low" 및 "Close" 값들은 현재 바를 의미합니다. 접두사 "ha"는 heikin-ashi 변형값을 의미합니다.

시장 정보에 대한 인식을 용이하게 하기 위해 Heikin-Ashi 법은 일반 차트에서 불규칙성을 제거하여 추세와 통합에 대한 더 나은 그림을 제공하는 이른바 합성 캔들스틱를 만들어 기존의 캔들스틱 차트를 수정합니다. 이 방법을 사용하여 작성된 캔들스틱 차트를 보기만 해도 시장 및 시장 스타일에 대한 좋은 요약본을 얻을 수 있습니다.

1번 그림. 왼쪽에 있는 것이 일반 캔들스틱 차트(a), 오른쪽이 Heikin-Ashi 차트(b) 입니다.

1번 그림이 종래의 일본 캔들스틱과 Heikin Ashi 캔들스틱의 차이를 보여줍니다. 이 그래프들의 특징은 상향추세의 경우 대부분의 흰색 양초에는 그림자가 없다는 것입니다. 하향추세의 경우에는 대부분의 검은 양초에 위쪽 그림자가 없습니다. Heiken Ashi 차트는 브레이크를 보여주지 않아 새 초가 기존 초의 중간레벨에서 개방됩니다.

Heiken-Ashi 차트의 캔들스틱들은 기존의 캔들스틱들보다 훨씬 강한 트렌드 강조경향이 있습니다. 만약 트렌드가 약해진다면 캔들스틱의 몸체가 작아지고 그림자가 커집니다. 캔들스틱의 색 변화는 매수 / 매도 신호입니다. 이러한 차트를 기반으로 교정 이동의 끝을 확인하는 것이 가장 편리합니다.

이 인디케이터는 MetaTrader 5의 일부로 «Indicators \\ Examples \\ Heiken_Ashi.mq5» 폴더에서 찾을 수 있습니다. 인디케이터를 차트에 설치하기 전에, 먼저 그래프를 선형으로 바꾸는 것을 추천합니다. 또한 그래프 속성의 "General" 탭에서 "from the top graph" 옵션을 해제하십시오.

다시 한 번 말하지만 Heiken-Ashi 법은 "치트키"가 아니라는 점을 강조하고 싶습니다. 이것을 증명하기 위해 Heiken-Ashi 법만을 이용해 간단한 매매 시스템(TS)을 만들어 보겠습니다.

이를 위해서는 MQL5 프로그래밍 언어와 표준 라이브러리 클래스를 사용하는 간단한 Expert Advisor를 만든 다음 MetaTrader 5 터미널의 전략 테스터를 사용하여 기간별 데이터에 대해 테스트해야 합니다.

2. 매매 시스템 알고리즘

너무 복잡하지 않게 다음 사이트에서 Dan Valcu가 제안한 Heiken-Ashi 절차의 6가지 기본 규칙을 사용하여 알고리즘을 생성합니다: http://www.educofin.com/

  1. 증가하는 트렌드 - 파란 캔들스틱 haClose> haOpen
  2. 감소하는 트렌드 - 빨간 캔들스틱 haClose <haOpen
  3. 강하게 증가하는 트렌드 - 파란 캔들스틱, 단 하나도 Low haOpen == haLow 가 아님
  4. 강하게 감소하는 트렌드 - 빨간 캔들스틱, 단 하나도 High haOpen == haHigh 가 아님
  5. 합병 - 작은 본체와 (아무 색이나)과 긴 그림자로 이루어진 캔들스틱들의 시퀀스
  6. 트렌드 변화 - 작은 본체와 긴 그림자로 이루어진 반대 색의 캔들스틱. 이건 언제나 믿을법한 신호는 아니고 그냥 합병 (5)의 일부인 경우도 있습니다.

(1,2)의 경향은 이해하기 쉽습니다. 거래 중이라면 이전 캔들스틱보다 1-2 포인트 아래/위로 스톱을 이동시키면서 위치를 유지하기만 하면 됩니다.

강한 경향 (3,4)의 경우 같은 방식으로 행동합니다. 스탑을 끌어올리는걸로.

합병(5)과 트렌드 변화(6)은 포지션을 닫지만(스탑 시 닫히지 않았을 경우), 반대 포지션를 열 것인지 여부를 결정해야 합니다. 결정을 내리려면 합병이 이루어지는지 역전이 이루어지는지 판단해야 합니다. 인디케이터, 캔들스틱 분석, 혹은 그래픽 분석을 기반으로 만든 필터가 필요합니다.

이 문서의 목표에는 딱히 수익성 있는 전략의 수립이 포함되어 있지 않지만, 결과적으로 우리가 무엇을 달성할지는 누가 알겠습니까? 따라서 반대색 캔들스틱이 나타나면 포지션을 닫고 반대 방향으로 새 캔들스틱을 열 것이라고 생각합시다.

알고리즘은 다음과 같습니다::

  1. 반대 색의 캔들스틱이 형성되면 이전 포지션을 닫고, 새 캔들스틱이 열릴 때 이전 캔들스틱의 최소/최대치보다 2포인트 아래/위로 정지선을 설정합니다.
  2. 트렌드 - 이전 캔들스틱의 최소/최대보다 2포인트 아래/위로 정지선을 이동합니다.
  3. 강한 트렌드의 경우 트렌드 때에 했던 것과 같게 대응합니다. 예) 스탑 이동

전반적으로 모든 것이 간단한데, 독자분들께도 설명이 명료했으면 좋겠습니다. 이제 MQL5 언어로 구현해볼 것입니다.

3. MQL5으로 Expert Advisor 프로그래밍하기

Expert Advisor를 만들려면 입력 패러미터 하나만 필요합니다. 랏의 크기, 두 이벤트 핸들러 함수 OnInit(), OnTick() 및 자체 함수 CheckForOpenClose().

MQL5에서 입력 패러미터를 설정하는데에는 Input 변수를 씁니다.

//--- input parameters
input double Lot=0.1;    // Port size

OnInit () 함수가 Init 이벤트 핸들러입니다. Init 이벤트는 Expert Advisor를 로딩하는 즉시 생성됩니다.

이 함수의 코드에서 우리는 인디케이터와 해당 Expert Advisor를 연결합니다. 위에서 말했다시피 표준 MetaTrader 5에는 Heiken_Ashi.mq5 인디케이터가 포함되어있습니다.

인디케이터 계산을 위한 공식이 있고 Expert Advisor의 코드에서 값을 계산할 수 있다면, 왜 그렇게 복잡한지 궁금할 것입니다. 인정하겠습니다, 가능하기는 한데요, 신중하게 들여다 보아야할 때의 이야기입니다:

haOpen=(haOpen[prev.]+haClose[prev])/2

보시다시피 이전 값을 쓰는 것을 보실 수 있을겁니다. 저거 때문에 독립적 계산에 지장이 생기고 삶을 참 복잡하게 하죠. 따라서 독립적인 계산 대신 MQL5의 기능을 활용하여 커스텀 인디케이터, 특히 iCustom함수를 연결할 예정입니다.

이걸 하기 위해 OnInit () 함수의 본문에 다음 줄들을 넣습니다:

   hHeiken_Ashi=iCustom(NULL,PERIOD_CURRENT,"Examples\\Heiken_Ashi");

우리가 미래에 쓰게될 Heiken_Ashi.mq5 인디케이터의 핸들인 글로벌 변수 hHeiken_Ashi를 얻었습니다.

OnTick () 함수는 NewTick () 이벤트의 핸들러로, 새 틱이생길 때마다 생성됩니다.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- check the ability of trading and the calculated number of bars
   if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
      if(BarsCalculated(hHeiken_Ashi)>100)
        {
         CheckForOpenClose();
        }
//---
  }

TerminalInfoInteger (TERMINAL_TRADE_ALLOWED) 함수는 트레이딩이 허가되었는지 아닌지 확인합니다. BarsCalculated (HHeiken_Ashi) 함수를 사용하여 Heiken_Ashi.mq5 인디케이터 용으로 계산된 데이터의 양을 확인합니다.

만약 두가지 조건이 다 맞아떨어졌다면 주요 작업이 이루어지는 CheckForOpenClose () 함수가 달성되었는지 확인합니다. 더 자세히 들여다 봅시다

TS 기준에 따르면 주문 실행은 새 캔들스틱 개방 시 수행되므로 새 캔들스틱이 개방되었는지의 여부를 확인해야 합니다. 이걸 하는 방법은 아주 많지만 가장 단순한 방법은 틱의 볼륨을 확인하는 것입니다. 따라서 만약 틱의 볼륨이 1이라면 이는 새 바가 열렸다는 의미이므로 TS 기준을 체크하고 주문을 실행해야합니다.

이 방식으로 구현합니다:

//--- process the orders only after receiving the first tick of the new candlestick 
   MqlRates rt[1];
   if(CopyRates(_Symbol,_Period,0,1,rt)!=1)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
   if(rt[0].tick_volume>1) return;

요소 한 개 사이즈 만큼의 MqlRates 타입 어레이를 생성합니다. CopyRates () 함수를 사용하여 가장 최근 바의 값을 어레이로 받아옵니다 그 다음 틱 볼륨을 확인하여 만약 그게 1보다 크다면 함수를 터뜨리고 아니라면 계산을 계속 수행합니다.

다음으로 다이렉티브 #define을 써서 니모닉 상수를 몇 개 선언합니다:

//--- to check the conditions we need the last three bars
#define  BAR_COUNT   3
//--- the number of indicator buffer for storage Open
#define  HA_OPEN     0
//--- the number of the indicator buffer for storage High
#define  HA_HIGH     1
//--- the number of indicator buffer for storage Low
#define  HA_LOW      2
//--- the number of indicator buffer for storage Close
#define  HA_CLOSE    3

그 다음 어레이를 선언합니다:

double   haOpen[BAR_COUNT],haHigh[BAR_COUNT],haLow[BAR_COUNT],haClose[BAR_COUNT];

이후 CopyBuffer () 함수를 써서 적절한 어레이 안에 있는 인디케이터의 값들을 받아옵니다.

   if(CopyBuffer(hHeiken_Ashi,HA_OPEN,0,BAR_COUNT,haOpen)!=BAR_COUNT
      || CopyBuffer(hHeiken_Ashi,HA_HIGH,0,BAR_COUNT,haHigh)!=BAR_COUNT
      || CopyBuffer(hHeiken_Ashi,HA_LOW,0,BAR_COUNT,haLow)!=BAR_COUNT
      || CopyBuffer(hHeiken_Ashi,HA_CLOSE,0,BAR_COUNT,haClose)!=BAR_COUNT)
     {
      Print("CopyBuffer from Heiken_Ashi failed, no data");
      return;
     }

어레이의 변수들에 어떻게 데이터가 저장되었는지 주목해주셨으면 하는 바램입니다.

"가장 오래된" (기록상) 바는 어레이의 첫 요소 (0)에 저장됩니다.

"가장 새로운" (현재) 바는 BAR_COUNT-1 (2번 그림)에 저장됩니다.

2번 그림. 어레이 인덱스 값과 캔들스틱 주문

2번 그림. 어레이 인덱스 값과 캔들스틱 주문

그래서 우리는 OHLC Heiken-Ashi 값을 얻었고, 그 값의 개방 또는 유지에 대한 조건을 확인하는 것이 남았습니다.

판매 신호 처리를 진지하게 고려해보세요.

아까 지적했듯이, 이미 우리는 3개의 Heiken-Ashi 캔들스틱 값을 얻었습니다. [BAR_COUNT-1 = 2]에 위치한 셀의 현재 값은 딱히 필요하지않습니다. 이전 값들은 셀 [BAR_COUNT-2 = 1]에, 그리고 더 앞쪽 바들은 [BAR_COUNT-3 = 0] (2번 그림 참조)에 있고, 이 두 바들을 기준으로 우리는 매매 성립의 기준과 조건을 확인합니다.

다음 기구의 개방 포지션을 확인해야합니다. 이걸 하기 위해 우리는 표준 라이브러리 내 매매 클래스의 CPositionInfo 클래스를 사용할 것입니다. 이 클래스는 우리가 개방된 포지션에 대한 정보를 받아올 수 있게 도와줍니다. Select (_Symbol) 메소드를 사용하여 도구 내 개방된 포지션의 유무를 확인하고, 만약 개방된 포지션이 존재한다면 Type () 메소드를 사용하여 해당 개방 포지션의 타입을 확인합니다.

현 시점에 매수용 개방 포지션이 있다면 우선 청산해야합니다.

이를 위해서는 매매 작업을 처리하게 디자인된 표준 클래스 라이브러리 CTrade 메소드를 사용합니다..

PositionClose (const string symbol, ulong deviation)메소드를 이용하여 구매를 닫습니다. symbol은 도구의 이름이고, 두번째 패러미터 deviation은 종가의 허용 편차입니다.

그런 다음 TS에 따라 캔들스틱의 조합을 확인합니다. 새로 만들어진 캔들스틱(인덱스 [BAR_COUNT-2])의 방향을 이미 확인했으므로, 그 앞의 캔들스틱(인덱스 [BAR_COUNT-3])만 확인하고 포지션을 여는 데 필요한 과정을 수행하면 됩니다.

     //--- check if there is an open position, and if there is, close it
      if(posinf.Select(_Symbol))
        {
         if(posinf.Type()==POSITION_TYPE_BUY)
           {
            //            lot=lot*2;
            trade.PositionClose(_Symbol,3);
           }
        }
      //--- check and set Stop Loss level
      double stop_loss=NormalizeDouble(haHigh[BAR_COUNT-2],_Digits)+_Point*2;
      double stop_level=SymbolInfoDouble(_Symbol,SYMBOL_ASK)+SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point;
      if(stop_loss<stop_level) stop_loss=stop_level;
      //--- check the combination: the candle with the opposite color has formed
      if(haOpen[BAR_COUNT-3]<haClose[BAR_COUNT-3])
        {
         if(!trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,lot,SymbolInfoDouble(_Symbol,SYMBOL_BID),stop_loss,0))
            Print(trade.ResultRetcodeDescription());
        }
      else
      if(posinf.Select(_Symbol))
        {
         if(!trade.PositionModify(_Symbol,stop_loss,0))
            Print(trade.ResultRetcodeDescription());
        }

CTrade 클래스의 3개 메소드 활용에 주목할 필요가 있습니다:

  • PositionOpen (symbol, order_type, volume, price, sl, tp, comment) 메소드는 포지션을 개방하는데 쓰이며 symbol은 도구의 이름, order_type은 주문 타입, volume은 랏의 크기, price는 매수가, sl는 스탑, tp는 이득, comment는 코멘트를 의미합니다.
  • PositionModify (symbol, sl, tp) 메소드는 스탑과 이득의 값을 저장하기 위해 쓰였으며 symbol은 도구의 이름, sl은 스탑, tp은 이득 입니다. 이 메소드를 사용하기 전에 개방된 포지션이 있는지 확인해야 한다는 사실에 주목해 주시기 바랍니다.
  • ResultRetcodeDescription () 메소드는 코드 에러 설명을 글으로 받아오는데에 쓰입니다.

만약 제대로 쓰려면 stop_loss 변수를 계산할 때에, haHigh [BAR_COUNT-2]의 값은 인디케이터 계산에서 받아오며 다 NormalizeDouble (haHigh [BAR_COUNT-2], _Digits) 함수를 통한 정규화가 필요합니다.

이걸로 매도용 신호의 처리를 완료했습니다.

매수에도 같은 이론을 쓸 것입니다.

이것이 그 Expert Advisor의 전체 코드입니다:

//+------------------------------------------------------------------+
//|                                           Heiken_Ashi_Expert.mq5 |
//|                                               Copyright VDV Soft |
//|                                                 vdv_2001@mail.ru |
//+------------------------------------------------------------------+
#property copyright "VDV Soft"
#property link      "vdv_2001@mail.ru"
#property version   "1.00"

#include <Trade\AccountInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>

//--- the list of global variables
//--- input parameters
input double Lot=0.1;    // Lot size
//--- indicator handles
int      hHeiken_Ashi;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   hHeiken_Ashi=iCustom(NULL,PERIOD_CURRENT,"Examples\\Heiken_Ashi");
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- trading should be allowed and number of bars calculated>100
   if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
      if(BarsCalculated(hHeiken_Ashi)>100)
        {
         CheckForOpenClose();
        }
//---
  }
//+------------------------------------------------------------------+
//| Checking of the position opening conditions                      |
//+------------------------------------------------------------------+
void CheckForOpenClose()
  {
//--- process orders only when new bar is formed
   MqlRates rt[1];
   if(CopyRates(_Symbol,_Period,0,1,rt)!=1)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
   if(rt[0].tick_volume>1) return;

//--- to check the conditions we need the last three bars
#define  BAR_COUNT   3
//--- number of the indicator buffer for storage Open
#define  HA_OPEN     0
//--- number of the indicator buffer for storage High
#define  HA_HIGH     1
//--- number of the indicator buffer for storage Low
#define  HA_LOW      2
//--- number of the indicator buffer for storage Close
#define  HA_CLOSE    3

   double   haOpen[BAR_COUNT],haHigh[BAR_COUNT],haLow[BAR_COUNT],haClose[BAR_COUNT];

   if(CopyBuffer(hHeiken_Ashi,HA_OPEN,0,BAR_COUNT,haOpen)!=BAR_COUNT
      || CopyBuffer(hHeiken_Ashi,HA_HIGH,0,BAR_COUNT,haHigh)!=BAR_COUNT
      || CopyBuffer(hHeiken_Ashi,HA_LOW,0,BAR_COUNT,haLow)!=BAR_COUNT
      || CopyBuffer(hHeiken_Ashi,HA_CLOSE,0,BAR_COUNT,haClose)!=BAR_COUNT)
     {
      Print("CopyBuffer from Heiken_Ashi failed, no data");
      return;
     }
//---- check sell signals
   if(haOpen[BAR_COUNT-2]>haClose[BAR_COUNT-2])// bear candlestick 
     {
      CPositionInfo posinf;
      CTrade trade;
      double lot=Lot;
     //--- check if there is an open position, and if there is, close it
      if(posinf.Select(_Symbol))
        {
         if(posinf.Type()==POSITION_TYPE_BUY)
           {
            //            lot=lot*2;
            trade.PositionClose(_Symbol,3);
           }
        }
      //--- check and set Stop Loss level
      double stop_loss=NormalizeDouble(haHigh[BAR_COUNT-2],_Digits)+_Point*2;
      double stop_level=SymbolInfoDouble(_Symbol,SYMBOL_ASK)+SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point;
      if(stop_loss<stop_level) stop_loss=stop_level;
      //--- check the combination: the candle with the opposite color has formed
      if(haOpen[BAR_COUNT-3]<haClose[BAR_COUNT-3])
        {
         if(!trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,lot,SymbolInfoDouble(_Symbol,SYMBOL_BID),stop_loss,0))
            Print(trade.ResultRetcodeDescription());
        }
      else
      if(posinf.Select(_Symbol))
        {
         if(!trade.PositionModify(_Symbol,stop_loss,0))
            Print(trade.ResultRetcodeDescription());
        }
     }
//---- check buy signals
   if(haOpen[BAR_COUNT-2]<haClose[BAR_COUNT-2]) // bull candle
     {
      CPositionInfo posinf;
      CTrade trade;
      double lot=Lot;
     //--- check if there is an open position, and if there is, close it
      if(posinf.Select(_Symbol))
        {
         if(posinf.Type()==POSITION_TYPE_SELL)
           {
            //            lot=lot*2;
            trade.PositionClose(_Symbol,3);
           }
        }
      //--- check and set Stop Loss level
      double stop_loss=NormalizeDouble(haLow[BAR_COUNT-2],_Digits)-_Point*2;
      double stop_level=SymbolInfoDouble(_Symbol,SYMBOL_BID)-SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point;
      if(stop_loss>stop_level) stop_loss=stop_level;
      //--- check the combination: the candle with the opposite color has formed
      if(haOpen[BAR_COUNT-3]>haClose[BAR_COUNT-3])
        {
         if(!trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,lot,SymbolInfoDouble(_Symbol,SYMBOL_ASK),stop_loss,0))
            Print(trade.ResultRetcodeDescription());
        }
      else
      if(posinf.Select(_Symbol))
        {
         if(!trade.PositionModify(_Symbol,stop_loss,0))
            Print(trade.ResultRetcodeDescription());
        }

     }
  }
//+------------------------------------------------------------------+

Expert Advisor 전문은 첨부파일 Heiken_Ashi_Expert.mq5 에서 확인할 수 있습니다. \\ MQL5 \\ Experts, 카탈로그에 복사하시고 .. "Tools -&gt; Editor MetaQuotes Language», 혹은 «F4» 키를 눌러 MetaEditor를 실행시킵니다. "Navigator" 창에서 «Experts» 탭을 열고, Heiken_Ashi_Expert.mq5 을 더블클릭해 에딧 창에 다운로드한 후 «F7»을 눌러 컴파일하세요..

만약 모든걸 제대로 수행했다면 "Expert Advisors" 탭 "Navigator" 윈도우에 Heiken_Ashi_Expert 이 생성될 것입니다. Heiken_Ashi.mq5 인디케이터도 같은 식으로 컴파일 되어야 하고 catalog \\ MQL5 \\ Indicators \\ Examples \\ 에서찾을 수 있습니다.

4. 과거 기록으로 매매 시스템 테스트하기

거래시스템의 타당성을 확인하기 위해 거래 플랫폼의 일부인 MetaTrader 5 전략 테스터를 사용할 예정입니다. 테스터는 터미널 메뉴 "View -&gt; Strategy Tester " 혹은 « Ctrl + R » 키 조합을 누르는걸로 실행할 수 있습니다. 실행되었다면 "세팅" 탭 (3번 그림)을 찾아봅니다. 

 3번 그림.  전략 테스터 설정

3번 그림.  전략 테스터 설정

Expert Advisor 구성 - Expert Advisor 목록 중에서 선택하여 테스트 간격을 2000년 초부터 2009년 말까지로 표시합니다. 초기 보증금은 USD 10,000이므로 최적화를 사용하지 않도록 설정합니다(입력 패러미터가 하나뿐이고 TS의 실행 가능성을 확인하려고 함).

테스트는 두개의 화폐쌍을 이용하여 이루어집니다. EURUSD 그리고 GBPUSD 화폐쌍을 쓰기로 했습니다.

테스트용으로 이하의 시간 인터벌을 쓰기로 했습니다: H3, H6 그리고 H12. 왜 그렇게 했냐고요? 정답은 MetaTrader4 터미널에 없는 TS를 시간 간격으로 테스트하고 싶었기 때문입니다.

그래서 이렇게 했습니다. 테스트용 화폐로 EURUSD, 기간으로 H3을 설정했고, "Start"를 누르십시오. 테스팅이 완료되면 테스터 창에 2개의 새로운 탭이 생긴걸 볼 수 있습니다: "Results" (4번 그림) 그리고 "Graph" (5번 그림).

4번 그림. 전략 테스팅 결과 EURUSD H3

4번 그림. 전략 테스팅 결과 EURUSD H3

테스트 결과(그림 4) 2000년 초부터 2009년 말까지 주어진 패러미터에서 TS의 손실액은 -2560,60달러였습니다.

그래프(그림 5)는 시간 경과에 따른 손익의 분포를 보여주며, 이로 인해 전체 TS의 성능을 검토하고 시스템 오류를 분석할 수 있습니다.

 5번 그림. 전략 테스터의 "그래프" 탭 (  EURUSD H3)

5번 그림.. 전략 테스터의 "Graph" 탭 (EURUSD H3)

Results" 탭에 대해서 말하는 것을 거의 잊었는데, 기본적으로 단순한 리포트를 만듭니다 거기에 추가적으로 결제, 주문, 그리고 파일 리포트를 볼 수 있습니다.

이렇게 하려면 커서를 탭 위에 놓고 마우스 오른쪽 버튼을 클릭한 다음 적절한 메뉴 항목을 선택하면 됩니다:

6번 그림. 전략 테스터 "결과" 탭의 본문 메뉴

6번 그림. 전략 테스터 본문 메뉴 결과 탭

6시간 (H6) 동안 테스팅한 결과입니다:

 7번 그림. 전략 테스터 "결과" 탭 (  EURUSD H6)

7번 그림. 전략 테스터 결과 탭 (EURUSD H6)

12시간을 넘도록 (H12).

 8번 그림.  전략 테스터 그래프 탭 (EURUSD H12)

8번 그림  전략 테스터 결과 탭 (EURUSD H12)

EURUSD 같은 통화 쌍에서는 이 전략이 효과적이지 않은 것 같습니다. 그러나 작업 기간의 변화가 결과에 상당한 영향을 미친다는 것을 알 수 있습니다.

화폐쌍 GBPUSD에도 테스트를 확대시켜서 TS의 효용성에 대한 최종 결론을 내릴 수 있게 시도해봅니다.

 9번 그림.  전략 테스터 그래프 탭 (GBPUSD H3)

9번 그림 전략 테스터 결과 탭(GBPUSD H3)

 10번 그림.  전략 테스터 그래프 탭 (GBPUSD H6)

10번 탭 전략 테스터 결과 탭 (GBPUSD H6)


 11번 그림.  전략 테스터 그래프 탭 (GBPUSD H12)

11번 그림 전략 테스터 결과 탭 (GBPUSD H12)

 12번 그림  전략 테스터 그래프 탭 (GBPUSD H12)

12번 그림  전략 테스터 그래프 (GBPUSD H12)

테스트 결과를 분석한 결과, GBUSD와 같은 통화 쌍을 사용했을 때, 우리 시스템은 두 개의 개별 사례에서 긍정적인 결과를 보였습니다. 우리는 12시간 동안 8903,23달러의 상당한 이익을 얻었지만 그걸 9년에 걸쳐서야 얻었습니다.

관심있는 사람들은 다른 통화쌍으로도 해보면 될 것 같습니다. 내 가정은 해당 화폐쌍의 가치 변화가 심할수록 더 좋은 결과를 얻고, 기간으로는 긴 기간을 사용해야 좀 쓸만할거란 점입니다.

마치며

결론으로, 이것이 "만능치트키"가 아니며 이것만으론 사용할 수 없다는 점을 강조하겠습니다.

그러나 추가 신호(캔들스틱 분석, 웨이브 분석, 인디케이터, 트렌드를 통해 통합 신호에서 역전 신호를 분리하면 일부 변동성 있는 거래 상품에서는 "미친" 이익까지는 아니더라도 나름 건질 수도 있겠습니다.

__________________________________ 
* "나니데스까?" - 이건 뭡니까?  (일본어)

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

Delphi로 MQL5용 DLL 짜는 법 Delphi로 MQL5용 DLL 짜는 법
이 문서는 Delphi 환경에서 인기좋은 언어 ObjectPascal을 이용해 DLL 모듈을 짜는 법에 대해서 알아볼 것입니다. 본 문서에서 제공하는 자료는 주로 외부 DLL 모듈을 연결하여 MQL5의 내장 프로그래밍 언어의 경계를 허문 초보자 프로그래머를 대상으로 합니다.
포지션 중심적 MetaTrader5 환경에서 주문 추적을 위해 가상 주문 매니저 활용하기 포지션 중심적 MetaTrader5 환경에서 주문 추적을 위해 가상 주문 매니저 활용하기
이 클래스 라이브러리를 MetaTrader 5 Expert Advisor에 추가하면 MetaTrader 5의 포지션 기반 접근 방식이 아닌, MetaTrader 4와 거의 유사한 주문 중심의 접근 방식으로 작성할 수 있습니다. 이를 위해 MetaTrader 5 클라이언트 터미널의 가상 주문을 추적하는 동시에 재앙 보호를 위한 각 위치에 대한 보호 브로커 스톱을 유지합니다.
캔들스틱 패턴 분석 캔들스틱 패턴 분석
일본 캔들스틱 차트의 구성과 캔들스틱 패턴 분석은 놀라운 기술적 분석 영역을 구성합니다. 캔들스틱의 장점은 데이터 내부의 역학을 추적 할 수 있는 방식으로 데이터를 표현한다는 것입니다. 이 글에서는 캔들스틱 유형, 캔들스틱 패턴 분류를 분석하고 캔들스틱 패턴을 결정할 수 있는 인디케이터를 제시합니다.
여러 중간 인디케이터 버퍼들을 통해 다중 화폐 인디케이터 만들기 여러 중간 인디케이터 버퍼들을 통해 다중 화폐 인디케이터 만들기
최근 FOREX 시장의 클러스터 분석에 대한 관심이 높아지고 있습니다. MQL5는 통화 쌍의 이동 동향을 조사할 수 있는 새로운 가능성을 열어줍니다. MQL4와 차별화되는 MQL5의 주요 기능은 인디케이터 버퍼를 무제한으로 사용할 수 있다는 것입니다. 이 문서에서 그러한 다중 화폐 인디케이터를 만드는 예시에 대해 다뤄보겠습니다.