English Русский 中文 Español Deutsch 日本語 Português Français Italiano
preview
다양한 이동 평균 유형을 테스트하여 이들이 얼마나 통찰력이 있는지 확인합니다.

다양한 이동 평균 유형을 테스트하여 이들이 얼마나 통찰력이 있는지 확인합니다.

MetaTrader 5테스터 |
31 1
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

소개

이전 글에서 우리는 가장 인기 있는 이동 평균 유형(단순, 가중, 지수)들에 대해 살펴보았습니다: 다양한 이동 평균 시스템을 설계하는 방법 알아보기. 이 글에서는 이 주제를 계속 다루며 단순 유형을 사용하여 다른 유형의 이동 평균과 그 결과를 비교해 보겠습니다. 많은 트레이더가 선호에 따라 다양한 유형의 이동평균을 사용합니다. 이 기사에서는 다양한 유형에 대해 알아보고 성능을 테스트하고 결과를 비교하여 어떤 유형이 더 나은 성능을 발휘하는지 정의 할 것입니다.

우리는 내장된 MetaTrader 5 전략 테스터에서 평균 백테스트를 수행하기 위한 간단한 애플리케이션을 만들겠습니다. 테스트 결과를 활용할 때 집중해야 할 사항에 대해 이해하려면 저의 이전 글인 MQL5 전략 테스터의 효과적인 이해와 사용을 참조하세요. 유용한 정보를 많이 담고 있습니다.

이제 다양한 유형의 이동 평균들과 그 성능에 대해 알아보기 위해 다음 주제를 살펴보겠습니다:

저는 최상의 결과를 얻기 위해 모든 이동 평균의 설정을 최적화하려고 노력할 것입니다. 그러나 여기서는 교육을 대상으로 하는 것이므로 여러분이 직접 더 많은 확인과 테스트를 할 필요가 있습니다. 더 나은 결과를 얻을 수 있는 더 나은 설정을 테스트하고 최적화하여 찾아야 합니다. 이러한 유형 중 하나 또는 전체 다 트레이딩 스타일에 적합하지 않을 수도 있습니다. 하지만 트레이딩을 개선하는 데 도움이 될 수 있는 인사이트를 찾으시길 바랍니다. 일반적으로 어떤 트레이딩 전략이든 실제 계좌에서 사용하기 전에 성과를 측정하는 것이 중요합니다.

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

단순 이동 평균(SMA) 시스템 테스트

저는 이 부분에서는 단순한 하나의 이동평균 전략만을 기반으로 하는 간단한 시스템의 결과를 공유하겠습니다. 가격과 단순이동평균선 사이의 크로스오버를 찾아 매수 및 매도 신호를 생성합니다. 우리는 이러한 신호를 자동으로 실행할 수 있는 시스템을 만들 것입니다.

다음 신호를 사용하여 거래 작업을 수행합니다:


매수 신호:

종가가 단순 이동 평균값 이상입니다.

그리고 이전 종가가 이전 단순 이동 평균값보다 낮았습니다.

매도 신호:

종가가 단순 이동 평균값 미만인 경우

그리고 이전 종가가 이전 단순 이동 평균값보다 높습니다.

단순 이동 평균 및 기타 인기있는 이동 평균 유형에 대해 알아보고 싶으시면 이전 기사에서 다룬 다양한 이동 평균 시스템을 설계하는 방법을 읽어보시기 바랍니다. 그러면 이 기사를 이해하는 데 도움이 될 것입니다.

다음은 앞서 살펴본 신호에 따라 자동으로 매수 및 매도 주문을 체결할 수 있는 트레이딩 시스템을 만드는 단계입니다.

글로벌에서 전처리기 #include를 사용하여 시그널을 기반으로 주문을 체결할 수 있도록 소프트웨어에 Trade 인클루드 파일을 포함할 것입니다. 전처리기에 대해 자세히 알아보려면 MQL5 프로그램 구조에 대해 알아야 할 모든 것 문서에서 자세한 내용을 확인할 수 있습니다.

#include <Trade\Trade.mqh>

사용자가 원하는 대로 변경할 lotSize의 더블 변수, timeFrame의 ENUM_TIMEFRAMES 변수, MAPeriod의 정수 변수에 대한 세 가지 사용자 입력을 생성하고 기본값을 초기화합니다:

input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;

할당 없이 simpleMA와 barsTotal의 두 정수 변수를 만듭니다. 이는 나중에 OnInit() 부분에서 정의할 것입니다.

int simpleMA;
int barsTotal;

거래 함수에 쉽게 액세스할 수 있도록 CTrade 클래스에서 거래를 객체로 생성합니다.

CTrade trade;

OnInit() 부분에서는 이동평균 지표의 핸들을 반환하는 iMA 함수를 사용하여 simpleMA를 정의할 것입니다. 그 매개변수는 다음과 같습니다:

  • symbol: 심볼을 지정합니다. 현재 심볼을 지정하기 위해 _Symbol을 사용합니다.
  • period: 차트 주기를 지정하기 위해 사용자 입력으로 기본값 1시간을 사용하지만 사용자가 조정할 수 있습니다.
  • ma_period: 단순 이동 평균 기간을 지정합니다. 사용자 입력으로 기본값 50을 사용하지만 사용자가 조정할 수도 있습니다.
  • ma_shift: 수평 이동을 지정하려면 0을 사용합니다. 
  • applied_price: 가격 유형을 지정합니다. 단순 이동 평균 계산을 위해 종가를 사용합니다.
simpleMA = iMA(_Symbol, timeFrame, MAPeriod, 0, MODE_SMA, PRICE_CLOSE);

barsTotal은 iBars 함수를 사용하여 바의 개수를 반환합니다. 매개 변수는 다음과 같습니다:

  • symbol: 심볼을 지정합니다. 현재 심볼에 적용되는 (_Symbol)을 사용합니다.
  • timeframe: 차트 주기를 지정하기 위해 기본값 1시간인 생성된 사용자 입력 시간 프레임을 사용합니다. 사용자는 이를 조정할 수 있습니다.
   barsTotal=iBars(_Symbol,timeFrame);

OnTick() 부분에서는 가격, 거래량, 스프레드에 대한 정보를 저장하기 위해 MqlRates를 사용하여 가격용 배열과 단순 이동 평균용 배열 두 개를 생성합니다:

   MqlRates priceArray[];
   double mySMAArray[];

ArraySetAsSeries 함수를 사용하여 생성된 두 배열에 AS_SERIES 플래그를 설정하면 해당 매개변수는 다음과 같습니다:

  • array[]: 참조로 배열을 지정합니다.
  • flag: 배열 인덱싱 방향을 지정합니다.
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);

매도 호가와 매수 호가를 두 개의 더블 변수로 만든 후 정의하기

   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

CopyRates 함수를 사용하여 MqlRates의 과거 데이터를 가져오면 해당 매개 변수는 다음과 같습니다:

  • symbol_name: 심볼 이름을 결정합니다.
  • timeframe: 차트 주기를 결정합니다.
  • start_pos: 시작 위치를 지정합니다.
  • count: 복사할 데이터의 개수를 지정합니다.
  • rates_array[]: 복사할 대상 배열을 지정합니다.
int Data=CopyRates(_Symbol,_Period,0,3,priceArray);

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

  • indicator_handle: 여기에 simpleMA인 지표 핸들을 지정합니다.
  • buffer_num: 지표의 버퍼 번호를 0으로 지정합니다.
  • start_pos: 현재 캔들이 0인 시작 위치를 결정합니다.
  • count: 복사해야 하는 양을 3으로 지정합니다.
  • buffer[]: 복사해야 할 대상 배열을 지정합니다(mySMAArray).
CopyBuffer(simpleMA,0,0,3,mySMAArray);

이 두 값의 더블 변수를 만든 후 동일한 캔들의 마지막 종가와 단순 이동 평균값을 정의합니다.

   double lastClose=(priceArray[1].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);

이 두 값의 다른 두 개의 더블 변수를 만든 후 이전 종가와 동일한 캔들의 단순 이동 평균값을 정의합니다.

   double prevClose=(priceArray[2].close);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);

barsTotal와 비교되는 정수 바 변수 생성하기

int bars=iBars(_Symbol,timeFrame);

바 합계가 바와 같지 않은 경우 바 합계를 확인하여 새로운 바가 생성되었는지 확인합니다.

if(barsTotal != bars)

barsTotal이 바와 같지 않은 경우 바 값으로 barsTotal을 업데이트해야 합니다.

barsTotal=bars;

barsTotal 합계가 바와 같지 않은 경우 마지막 종가 중 이전 종가가 같은 캔들의 단순이동평균 값보다 낮고 동시에 마지막 종가가 같은 캔들의 단순이동평균 값보다 높은 경우에도 전략의 조건을 확인해야 합니다. 프로그램이 현재 진입 포지션을 청산하고 매수 포지션에 진입하도록 해야 합니다.

      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }

마지막 종가 중 이전 종가가 같은 바의 단순이동평균 값보다 높고 동시에 마지막 종가가 같은 바의 단순이동평균 값보다 낮은 경우. 프로그램이 현재 진입한 포지션을 청산하고 매도 포지션에 진입하도록 해야 합니다.

      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }

그런 다음 코드를 컴파일하면 오류나 경고 없이 컴파일 된 것을 확인할 수 있습니다.

다음은 하나의 코드 블록에 포함된 전체 코드입니다:

//+------------------------------------------------------------------+
//|                                                   SMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
int simpleMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   simpleMA = iMA(_Symbol, timeFrame, MAPeriod, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double mySMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);
   int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
   CopyBuffer(simpleMA,0,0,3,mySMAArray);
   double lastClose=(priceArray[1].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

EA를 컴파일하고 EURUSD 데이터에서 EA를 실행하여 전략을 백테스트 합니다. 테스트 기간은 앞서 이동평균 유형과 동일하게 2022년 1월 1일부터 6월 30일까지입니다. SMA에 대한 설정은 다음과 같습니다:

  • 랏 크기: 1
  • 차트 주기: 1시간
  • MA 기간: 50

테스트 결과:

SMA 결과

SMA 지표를 테스트하면 다음 그림에서 볼 수 있듯이 좀 더 알아보아야 할 사항이 있습니다:

  • 순이익: 2700.30 (27%)
  • 상대적 DD 밸런스: 37.07%
  • 상대 예탁자산 평가 총액 DD: 41.76%
  • 수익 요소: 1.10
  • 예상되는 보상: 12.68
  • 복구 계수: 0.45
  • 샤프 비율: 0.57

적응 이동 평균(Adaptive Moving Average; iAMA)

이번 파트에서는 또 다른 유형의 이동 평균인 적응 이동 평균(AMA)에 대해 알아보겠습니다. 페리 카우프만(Perry J. Kaufman)이 개발한 것으로 (KAMA)라고도 불리며 주요 개념은 가격 움직임의 노이즈를 줄이는 것입니다. 가격 움직임의 변동성에 상관없이 가격 변동에 적응하면서 가격 움직임을 따라갑니다. 이 지표는 추세를 따르는 지표이므로 추세와 전환점을 식별하는 데 사용할 수 있습니다.

지표는 몇 단계로 계산됩니다.

1단계: AMA 또는 KAMA 계산하기

1단계

2단계: 평활화 상수(SC) 계산하기

step2

3단계: 효율 비율(ER) 계산하기

 step3

AMA 지표를 수동으로 계산하는 방법에 대해 알아보았지만 이러한 계산 방법까지 알 필요는 없습니다. 우리는 내장 지표에서 선택하여 MetaTrader 5에 삽입하면 됩니다. 이제 종가와 AMA 지표의 교차를 기반으로 매매 주문을 체결할 수 있는 트레이딩 시스템을 만들어야 합니다. 다음 신호를 전략에 사용할 것입니다.

매수 신호:

종가가 적응 이동 평균값보다 높습니다.

그리고 이전 종가가 이전 적응 이동 평균값보다 낮았습니다.

매도 신호:

종가가 적응 이동 평균값보다 낮습니다.

그리고 이전 종가가 이전 적응 이동 평균값보다 높았습니다.

다음은 이러한 거래 시스템을 만들기 위한 전체 코드입니다:

//+------------------------------------------------------------------+
//|                                                  iAMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
input int fastMAPeriod= 5;
input int slowMAPeriod= 100;
int adaptiveMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   adaptiveMA = iAMA(_Symbol, timeFrame, MAPeriod,fastMAPeriod,slowMAPeriod, 0, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double myAMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(myAMAArray,true);
   int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray);
   CopyBuffer(adaptiveMA,0,0,3,myAMAArray);
   double lastClose=(priceArray[1].close);
   double AMAVal = NormalizeDouble(myAMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevAMAVal = NormalizeDouble(myAMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(lastClose>AMAVal && prevClose<prevAMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(lastClose<AMAVal && prevClose>prevAMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

이 코드의 차이점은 적응형 이동 평균 지표의 핸들을 반환하는 iAMA 함수를 사용한다는 점 입니다. 그 매개 변수는 다음과 같습니다:

  • symbol: 심볼을 지정합니다. 현재 심볼을 지정하기 위해 _Symbol을 사용합니다.
  • period: 사용자 입력을 사용하여 기본값이 1시간인 시간 프레임을 지정합니다.
  • ama_period: 적응 이동 평균의 주기를 지정합니다.
  • fast_ma_period: 빠른 MA의 기간을 지정합니다.
  • slow_ma_period: 느린 MA의 기간을 지정합니다.
  • ama_shift: 수평 이동을 지정합니다. 우리는 0을 사용합니다.
  • applied_price: 가격 유형을 지정합니다. 우리는 종가를 사용합니다.

결과를 확인하려면 같은 기간 동안 AMA 지표를 백테스트해야 합니다:

  • Lot size =1
  • Time frame = 1 hour
  • MAperiod = 50
  • Fast MA = 5
  • Slow MA = 100

결과:

AMA 결과

AMA 지표를 테스트하면 다음과 같은 수치를 확인할 수 있습니다:

  • 순이익: 3638.20 (36.39%)
  • 상대적 DD 밸런스: 22.48%
  • 상대 예탁자산 평가 총액 DD: 35.53%
  • 수익 요소: 1.31
  • 예상되는 보상: 35.67
  • 복구 계수: 0.65
  • 샤프 비율: 0.86

이중 지수 이동 평균(iDEMA)

이번 파트에서는 또 다른 이동평균 유형인 이중 지수 이동평균(Double Exponential Moving Average; DEMA) 기술 지표에 대해 알아보겠습니다. 이 지표는 패트릭 멀로이가 개발한 트렌드 추종 지표로 주요 목적은 EMA의 지연을 줄이되 이 지표의 계산에서 볼 수 있듯이 시장 움직임에 더 민감하게 반응하도록 하는 것입니다.

이 지표는 이 이동 평균을 기준으로 가격의 위치를 감지하여 추세 또는 추세의 전환점을 식별하는 데 사용할 수 있습니다. 지표 계산 단계는 다음과 같습니다:

1. 첫 번째 지수 이동 평균(EMA) 계산하기

EMA 1 = n 기간의 가격의 EMA

2. EMA 1의 EMA 계산하기

EMA 2 = EMA 1의 EMA

3. DEMA 계산하기

DEMA = (2 * EMA 1) - EMA 2

이러한 수동 계산은 지표를 잘 이해하기 위한 것입니다. MetaTrader 5의 많은 다른 기술 지표와 같이 이미 내장되어 있습니다. 이제 이전에 만든 것과 동일한 거래 시스템을 만들어야 하지만 이번에는 DEMA를 사용하여 다른 유형과 비교하고 그 결과를 테스트할 것입니다. 이 거래 시스템은 교차를 기준으로 매수 및 매도를 합니다. 앞서 살펴본 시스템과 동일하게 실행되지만 이번에는 교차의 기준이 가격과 DEMA 지표 사이의 크로스오버가 될 것입니다. 신호는 다음과 같습니다:

매수 신호:

종가가 이중 지수 이동 평균(DEMA) 값보다 높습니다.

그리고 이전 종가가 이전 DEMA 값보다 낮았습니다.

매도 신호:

종가가 DEMA 값보다 낮습니다.

그리고 이전 종가가 이전 DEMA 값보다 높았습니다.

다음은 이중 지수 이동 평균 지표의 핸들을 반환하기 위해 iDEMA 함수를 사용하는 이전과는 약간의 차이점이 있는 이 거래 시스템의 전체 코드이며 매개 변수는 다음과 같습니다:

  • symbol: 심볼 이름을 지정합니다. 현재 심볼로 (_Symbol)을 사용합니다.
  • period: 차트 주기를 지정합니다. 차트 주기가 기본 1시간인 사용자 입력을 사용합니다.
  • ma_period: 이동 평균 기간을 지정합니다. 기본값 50인 사용자 입력을 사용합니다.
  • ma_shift: 수평 이동을 지정합니다. 차트에 이동이 필요하지 않으므로 0을 사용합니다.
  • applied_price: 가격 유형을 지정합니다. 우리는 종가를 사용하여 이동 평균을 계산합니다.

이는 아래 한 블록의 코드와 같습니다:

//+------------------------------------------------------------------+
//|                                                 iDEMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
int DEMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   DEMA = iDEMA(_Symbol, timeFrame, MAPeriod,0, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double myDEMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(myDEMAArray,true);
   int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray);
   CopyBuffer(DEMA,0,0,3,myDEMAArray);
   double lastClose=(priceArray[1].close);
   double DEMAVal = NormalizeDouble(myDEMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevDEMAVal = NormalizeDouble(myDEMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(lastClose>DEMAVal && prevClose<prevDEMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(lastClose<DEMAVal && prevClose>prevDEMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

이 코드를 컴파일한 후 이전의 다른 유형에 사용한 것과 동일한 기간으로 백테스트할 수 있으며 이 지표의 설정 또는 입력은 다음과 같습니다:

  • Lot size = 1
  • Time frame = 1 hour
  • MA period = 50

테스트를 실행한 후 우리는 다음과 같은 결과를 얻었습니다:

DEMA 결과

다음 그림에서 볼 수 있듯이 iDEMA를 테스트한 후 알아보아야 할 사항은 다음과 같습니다:

  • 순이익: - 961.60 (- 9.62%)
  • 상대적 DD 밸런스: 39.62%
  • 상대 예탁자산 평가 총액 DD: 41.15%
  • 수익 요소: 0.97
  • 예상 수익: - 3.12
  • 복구 계수: - 0.18
  • 샤프 비율: - 0.21

삼중 지수 이동 평균(iTEMA)

이제 또 다른 이동평균 유형인 삼중 지수 이동평균(Triple Exponential Moving Average; TEMA)을 사용해 보겠습니다. 이는 패트릭 멀로이가 단기 거래에 적합하도록 지표에 더 많은 반응성을 추가하기 위해 개발한 것입니다. 이 지표에서 우리는 삼중 평활 EMA, 단일 및 이중 평활 EMA를 사용합니다. 따라서 이 지표는 가격에 더 민감하게 반응할 것입니다. 이중 지수 이동 평균을 사용한 것과 마찬가지로 TEMA도 가격에 더 빠르게 반응하므로 우리는 추세와 전환점 또는 추세의 변화를 식별하는 데 사용할 수 있습니다.

다음은 이 TEMA 지표를 계산하는 단계입니다:

1. 첫 번째 지수이동평균(EMA) 계산하기

EMA 1 = n 기간의 가격의 EMA

2. EMA 1의 EMA 계산

EMA 2 = EMA 1의 EMA

3. EMA 2의 EMA 계산

EMA 3 = EMA 2의 EMA

4. TEMA 계산하기

DEMA = (3 * EMA 1) - (3 * EMA 2) + (EMA3)

수동 계산 없이 MetaTrader 5에서 사용 가능한 내장 기술 지표에서 이 지표를 삽입한 다음 TEMA 지표를 사용하여 거래 시스템을 만들어 테스트하고 결과를 다른 유형과 비교해 보겠습니다. 다음은 거래 시스템을 만드는 전체 코드로 이전과는 iTEMA 함수를 사용하여 삼중 지수 이동 평균 지표의 핸들을 반환한다는 차이점이 있으며 매개 변수는 DEMA 및 SMA에서 살펴본 것과 동일합니다.

//+------------------------------------------------------------------+
//|                                                 iTEMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
int TEMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   TEMA = iTEMA(_Symbol, timeFrame, MAPeriod,0, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double myTEMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(myTEMAArray,true);
   int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray);
   CopyBuffer(TEMA,0,0,3,myTEMAArray);
   double lastClose=(priceArray[1].close);
   double TEMAVal = NormalizeDouble(myTEMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevTEMAVal = NormalizeDouble(myTEMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(lastClose>TEMAVal && prevClose<prevTEMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(lastClose<TEMAVal && prevClose>prevTEMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

이 소프트웨어를 컴파일하고 실행한 후 동일한 기간에서 백테스트 해서 다른 이동 평균 유형과 결과를 비교할 수 있으며 다음은 이 테스트 프로세스에서 모든 매개 변수를 정하는 데 사용되는 설정 또는 입력입니다:

  • Lot size = 1
  • Time frame = 1 hour
  • MA period = 50

테스트를 실행하고 완료하면 다음과 같은 결과를 확인할 수 있습니다:

TEMA 결과

다음 그림에서 결과 내용을 확인할 수 있습니다:

  • 순이익: - 3973.10 (- 39.74%)
  • 상대적 DD 밸런스: 63.98%
  • 상대 예탁자산 평가 총액 DD: 66.06%
  • 수익 요소: 0.90
  • 예상 수익률: - 10.59
  • 복구 계수: - 0.52
  • 샤프 비율: - 0.83

프랙탈 적응 이동 평균(iFrAMA)

마지막으로 우리가 확인해야 할 이동 평균 유형이 있습니다. 이는 존 엘러스가 개발한 프랙탈 적응 이동 평균(Fractal Adaptive Moving Average; FrAMA) 지표입니다. 이는 추세를 따르는 지표이며 시장 가격이 프랙탈이라고 가정하며 트렌드와 전환점을 감지하는 데에도 사용될 수 있습니다. 다음은 이를 계산하는 방법을 보여주는 단계입니다:

 FrAMA

MetaTrader 5에서 사용 가능한 내장 기술 지표에서 이 지표를 삽입할 수 있습니다. 이제 동일한 전략으로 동일한 거래 시스템을 만들어야 하지만 여기서는 다른 유형과 테스트한 후 결과를 비교하기 위해 FrAMA 지표를 대신 사용할 것입니다. 이 전략은 가격과 FrAMA 지표의 교차로 가격이 FrAMA 위로 교차하면 매수 신호가 되고 FrAMA 아래로 교차하면 매도 신호가 됩니다.

매수 신호:

종가가 프랙탈 적응 이동 평균(FrAMA) 값보다 높습니다.

그리고 이전 종가는 이전 FrAMA 값보다 낮았습니다.

매도 신호:

종가가 FrAMA 값보다 낮습니다.

그리고 이전 종가가 이전 FrAMA 값보다 높았습니다.

다음은 이 트레이딩 시스템을 생성하는 전체 코드로 앞서 다른 유형과 동일하면서 프랙탈 적응 이동 평균의 핸들을 반환하는 (iFrAMA) 함수와 그 매개 변수를 사용합니다:

  • symbol: 심볼을 지정합니다. 현재 심볼을 지정하기 위해 _Symbol을 사용합니다.
  • period: 사용자 입력을 사용하여 기본값이 1시간인 시간 프레임을 지정합니다.
  • ma_period: 이동 평균 기간을 지정합니다. 기본값 50인 사용자 입력을 사용합니다.
  • ma_shift: 수평 이동을 지정하려면 0을 사용합니다. 
  • applied_price: 가격 유형을 지정합니다. 우리는 종가를 사용합니다.
//+------------------------------------------------------------------+
//|                                                iFrAMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
int FrAMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   FrAMA = iFrAMA(_Symbol, timeFrame, MAPeriod,0, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double myFrAMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(myFrAMAArray,true);
   int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray);
   CopyBuffer(FrAMA,0,0,3,myFrAMAArray);
   double lastClose=(priceArray[1].close);
   double FrAMAVal = NormalizeDouble(myFrAMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevFrAMAVal = NormalizeDouble(myFrAMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(lastClose>FrAMAVal && prevClose<prevFrAMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(lastClose<FrAMAVal && prevClose>prevFrAMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

이 EA를 컴파일하고 실행한 후 다음과 같은 설정 또는 입력으로 FrAMA 지표를 사용하여 이 전략을 테스트합니다:

  • 랏 크기: 1
  • 차트 주기: 1시간
  • MA 기간: 50

살펴본 다른 모든 이동 평균과 같은 기간에 이 EA를 테스트한 결과 다음과 같은 결과를 얻었습니다:

FrAMA 결과

보시다시피 우리가 공부해야 할 가장 중요한 수치는 다음과 같습니다:

  • 순이익: - 2993.70 (- 29.94%)
  • 상대적 DD 밸런스: 73.28%
  • 상대 예탁자산 평가 총액 DD: 74.81%
  • 수익 요소: 0.93
  • 예상 수익률: - 6.45
  • 복구 계수: - 0.33
  • 샤프 비율: - 0.46

단순 이동 평균(SMA) 결과와 비교하기

이 부분에서 저는 앞선 모든 이동 평균 유형의 결과를 비교하고 가능한 한 최상의 결과를 제공하려고 노력할 것이지만 이동 평균은 지표 설정 및 시장 상황에 따라 다른 결과를 제공할 수 있습니다. 이동 평균을 최적화하고 기간 또는 테스트 기간을 변경하면 모든 이동 평균이 다른 결과를 제공할 수 있다는 것을 여러분은 알아야 합니다.

여기서 주요 목표는 가능한 한 동일한 조건으로 선택할 수 있는 최상의 설정으로 다른 유형보다 더 나은 유형이 있는지 확인하는 것입니다. 우리가 찾고 있는 것이 무엇인지에 대한 이해를 돕기 위해 가장 중요한 측정값을 가장 높은 성능으로 볼 필요가 있습니다:

  • 순이익: 최고의 값이 가장 좋은 것입니다.
  • 드로다운(DD): 가장 낮은 것이 가장 좋은 것입니다.
  • 수익 비율: 최고가 가장 좋은 것입니다.
  • 예상 보상: 최고의 값이 가장 좋은 것입니다.
  • 복구 계수: 가장 높은 것이 가장 좋은 것입니다.
  • 샤프 비율: 샤프비가 가장 높은 것이 가장 좋습니다.

이제 다음 표를 통해 이전의 단순 이동평균 결과와 이전의 컨텍스트를 기반으로 한 다른 이동평균 유형을 비교해 보겠습니다:

측정 SMA AMA DEMA TEMA FrAMA
순이익 2700.30 (27%) 3638.20 (36.39%) - 961.60 (- 9.62%) - 3973.10 (- 39.74%) - 2993.70 (- 29.94%)
잔고 인출 상대 37.07% 22.48% 39.62% 63.98% 73.28%
예탁금 평가 드로다운 상대  41.76% 35.53% 41.15% 66.06% 74.81%
수익 계수 1.10 1.31 0.97 0.90 0.93
예상 수익 12.68 35.67 - 3.12 - 10.59 - 6.45
복구 계수 0.45 0.65 - 0.18 - 0.52 - 0.33
샤프 비율 0.57 0.86 - 0.21 - 0.83 - 0.46

모든 테스트 결과에 따르면 설정과 테스트 기간에 따라 가장 성능이 좋은 두 가지 유형이 있다는 것이 밝혀졌습니다. 단순 이동 평균과 적응 이동 평균이 그것입니다. 가장 좋은 것은 적응 이동 평균입니다. 그렇습니다:

  • 가장 높은 순이익
  • 가장 낮은 잔액 DD 상대
  • 가장 낮은 지분 DD 상대
  • 최고의 수익률
  • 가장 높은 기대 수익
  • 복구 계수가 높을수록
  • 샤프 비율이 높을수록

앞서의 설정과 전략을 더 최적화하면 우리는 더 나은 결과를 얻을 수 있을 것이라 했지만 여기서의 목표는 실제 예제에서 테스트 프로세스를 이해하고 적용한다는 것입니다.

결론

이 글에서는 다음과 같은 이동 평균 유형의 성능을 알아 보았습니다:

  • 적응 이동 평균(AMA)
  • 이중 지수 이동 평균(DEMA)
  • 삼중 지수 이동 평균(TEMA)
  • 프랙탈 적응 이동 평균(FrAMA)

우리는 이들 유형에 대한 트레이딩 시스템을 만들고 가장 많이 사용되는 이동평균 유형인 단순이동평균과 결과를 비교했습니다. 테스트 결과에 따르면 단순 이동 평균과 적응 이동 평균이 가장 좋은 결과를 냈으며 그 중 적응 이동 평균(AMA)이 가장 우수한 것으로 나타났습니다. 우리는 다음 지표를 분석하고 비교하여 가장 우수한 것을 선정했습니다:

  • 순이익
  • 드로다운(DD)
  • 수익 계수
  • 예상 수익
  • 복구 계수
  • 샤프 비율

트레이딩에서 테스트는 매우 중요한 주제입니다. 저는 여러분이 더 많은 전략에 대해 더 많은 테스트를 해보시기를 권합니다. 전략 자체를 평가하는 것 외에도 테스트를 통해 이해가 깊어지면서 생각지 못한 인사이트를 얻을 수도 있습니다.

이 글을 읽어주셔서 감사합니다. 이 글이 도움이 되셨기를 바라며 여러분의 지식에 가치를 더하는 데 도움이 되었기를 바랍니다. RSI, MACD, 스토캐스틱, 볼린저 밴드 및 기타 주제와 같은 인기있는 기술 지표를 기반으로 거래 시스템을 만드는 방법에 대한 더 많은 기사를 읽고 싶으시면 기고글을 통해 제 기사를 확인할 수 있으니 유용하게 사용하시기 바랍니다.

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

파일 첨부됨 |
SMA_System.mq5 (2.07 KB)
iAMA_System.mq5 (2.15 KB)
iDEMA_System.mq5 (2.06 KB)
iTEMA_System.mq5 (2.06 KB)
iFrAMA_System.mq5 (2.08 KB)
최근 코멘트 | 토론으로 가기 (1)
go123
go123 | 26 2월 2024 에서 03:27
1시간 주기 외환에서 적응 평균 하나만 사용하여 수익을 낼 수 있나요? 백테스트할 때 대부분의 외환 종목에서 손실이 나는 이유는 무엇인가요?
새로운 기능: MQL5의 커스텀 인디케이터 새로운 기능: MQL5의 커스텀 인디케이터
MetaTrader5와 MQL5의 새로운 기능 전체를 나열하지는 않겠습니다. 종류도 많은 데다가, 별도의 설명이 필요한 기능들도 있거든요. 객체 지향 프로그래밍을 이용한 코드 작성법 또한 다음에 알아보도록 하겠습니다. 다른 기능들과 함께 설명하기에는 조금 어려운 이야기일 수 있으니까요. 이 글에서는 인디케이터와 인디케이터의 구조, 드로잉 타입과 프로그래밍 디테일을 MQL4와 비교해 볼게요. 초보자 분들께 많은 도움이 되면 좋겠고 기존에 사용하시던 개발자 분들도 뭔가 새로운 걸 얻어 가실 수 있길 바랍니다.
MQL5 Algo Forge로 이동하기(1부): 메인 리포지토리 만들기 MQL5 Algo Forge로 이동하기(1부): 메인 리포지토리 만들기
MetaEditor에서 프로젝트를 작업할 때 개발자는 종종 코드 버전을 관리해야 하는 상황에 직면합니다. MetaQuotes는 최근 코드 버전 관리 및 협업 기능을 갖춘 MQL5 Algo Forge의 출시와 함께 GIT로의 마이그레이션을 발표했습니다. 이 글에서는 이 새로운 도구와 기존 도구를 더 효율적으로 사용하는 방법에 대해 설명합니다.
새 MetaTrader 와 MQL5를 소개해드립니다 새 MetaTrader 와 MQL5를 소개해드립니다
본 문서는 MetaTrader5의 간략 리뷰입니다. 짧은 시간 내에 시스템의 모든 세부 사항을 안내해드리기는 어렵습니다 - 테스트는 2009.09.09에 시작되었습니다. 이는 상징적인 일자로, 전 이것이 행운의 숫자가 될거라 믿어 의심치않습니다. 제가 새 MetaTrader 5 터미널과 MQL5 베타버전을 받은지 며칠이 지났습니다. 아직 모든 기능을 사용해본 것은 아니지만, 벌써부터 감명깊네요.
MQL5 Algo Forge 시작하기 MQL5 Algo Forge 시작하기
알고리즘 트레이딩 개발자를 위한 전용 포털인 MQL5 Algo Forge를 소개합니다. MQL5 Algo Forge에는 Git의 강력한 기능과 MQL5 에코시스템 내에서 프로젝트를 관리하고 구성할 수 있는 직관적인 인터페이스가 결합되어 있습니다. 여러분은 이곳에서 흥미로운 저자를 팔로우하고 팀을 구성하고 알고리즘 트레이딩 프로젝트에 대해 협업할 수 있습니다.