MQL5 위자드를 활용하면 자동으로 전문가 조언자(EA)의 코드를 생성할 수 있습니다. 자세한 내용은 MQL5 위자드에서 준비된 전문가 조언자 만들기를 참고하세요.
이번 전략은 두 개의 이동 평균선 교차를 기반으로 한 트레이딩 신호를 다루며, MQL5 위자드 - 두 개의 지수이동평균(EMA) 교차 기반 트레이드 신호에 대한 설명이 포함되어 있습니다. 이동 평균선은 트렌드가 있을 때 효과적이며 그 외의 경우에는 많은 잘못된 신호를 제공합니다. 전략의 개선 방법 중 하나는 시간 필터를 사용하는 것입니다(예: 유럽 외환 세션 중에만 새로운 포지션을 여는 것).
여기에서는 두 개의 지수이동평균(빠른 EMA와 느린 EMA) 교차에 기반한 시간 필터가 적용된 전략을 설명하겠습니다. 이 전략은 “두 EMA 교차 기반의 트레이드 신호(시간 필터 포함)”라고 불리며, MQL5 위자드에서 EA를 자동으로 생성할 때 사용됩니다.
트레이드 신호:
- 롱 포지션 열기: 빠른 EMA가 느린 EMA를 위로 교차하고 시간 필터 조건이 충족되지 않을 때.
- 숏 포지션 열기: 빠른 EMA가 느린 EMA를 아래로 교차하고 시간 필터 조건이 충족되지 않을 때.
이 전략은 CSignal2EMA_ITF 클래스에서 구현됩니다.
이 트레이딩 시스템은 미결제 주문을 기반으로 하며, 가격 수준은 이동 평균 값에 따라 계산되며, ATR(평균 진폭 범위) 단위가 사용됩니다.

두 EMA 교차 기반의 트레이드 신호
트레이드 신호
이 트레이딩 전략은 CSignal2EMA_ITF에 구현되어 있으며, 지표 값에 대한 접근을 간소화하기 위해 몇 가지 보호된 메서드를 제공합니다:
double FastEMA(int ind) // 바의 빠른 EMA 값을 반환합니다 double SlowEMA(int ind) // 바의 느린 EMA 값을 반환합니다 double StateFastEMA(int ind) // 빠른 EMA가 증가/감소했는지의 양수/음수를 반환합니다 double StateSlowEMA(int ind) // 느린 EMA가 증가/감소했는지의 양수/음수를 반환합니다 double StateEMA(int ind) // 빠른 EMA와 느린 EMA의 차이를 반환합니다 double ATR(int ind) // 바의 ATR 값을 반환합니다
- Limit>0. 잘못된 이탈이 발생할 때 시장 가격보다 낮은 가격에 진입합니다(거래 신호에 따라 Buy Limit 및 Sell Limit 주문이 배치됩니다).
- Limit<0. 가격 움직임 방향으로 진입합니다(거래 신호에 따라 Buy Stop 및 Sell Stop 주문이 배치됩니다).
- Limit=0. 이 경우 시장 가격을 사용하여 거래합니다.
1. 롱 포지션 열기
롱 포지션을 열기 위한 조건을 확인합니다: 마지막 완료된 바의 빠른 EMA와 느린 EMA의 차이가 부호를 변경했는지 확인합니다 (StateEMA(1)>0 && StateEMA(2)<0).
다음으로 CSignalITF 클래스의 CheckOpenLong() 메서드를 호출하여 시간 필터 조건을 확인합니다. 거래가 허용되면 기본 가격 수준(이동 평균 값)과 마지막 완료된 바의 ATR 범위를 계산합니다.
Limit 입력 매개변수의 부호에 따라 매수 미결제 주문을 배치합니다. 주문 가격, 이익 실현 및 손실 제한 수준은 기본 가격 수준에 상대적으로 계산됩니다(ATR 단위로). 주문 만료 시간은 Expiration 입력 매개변수에 의해 정의됩니다.
//+------------------------------------------------------------------+ //| 롱 포지션(매수) 열기 조건 확인 | //+------------------------------------------------------------------+ bool CSignal2EMA_ITF::CheckOpenLong(double& price,double& sl,double& tp,datetime& expiration) { if(!(StateEMA(1)>0 && StateEMA(2)<0)) return(false); if(!m_time_filter.CheckOpenLong(price,sl,tp,expiration)) return(false); //--- double ema=SlowEMA(1); double atr=ATR(1); double spread=m_symbol.Ask()-m_symbol.Bid(); //--- price=m_symbol.NormalizePrice(ema-m_limit*atr+spread); sl =m_symbol.NormalizePrice(price+m_stop_loss*atr); tp =m_symbol.NormalizePrice(price-m_take_profit*atr); expiration+=m_expiration*PeriodSeconds(m_period); //--- return(true); }
2. 롱 포지션 닫기
우리의 경우 롱 포지션을 닫기 위한 조건을 확인하는 함수는 항상 false를 반환합니다. 즉, 롱 포지션은 이익 실현 또는 손실 제한에 의해 닫힐 것으로 가정됩니다. 필요하다면 이 메서드를 구현한 코드를 작성할 수 있습니다.
//+------------------------------------------------------------------+ //| 롱 포지션 닫기 조건 확인 | //+------------------------------------------------------------------+ bool CSignal2EMA_ITF::CheckCloseLong(double& price) { return(false); }
3. 숏 포지션 열기
숏 포지션을 열기 위한 조건을 확인합니다: 마지막 완료된 바의 빠른 EMA와 느린 EMA의 차이가 부호를 변경했는지 확인합니다 (StateEMA(1)<0 && StateEMA(2)>0).
다음으로 CSignalITF 클래스의 CheckOpenLong() 메서드를 호출하여 시간 필터 조건을 확인합니다. 거래가 허용되면 기본 가격 수준(이동 평균 값)과 마지막 완료된 바의 ATR 범위를 계산합니다.
Limit 입력 매개변수의 부호에 따라 매도 미결제 주문을 배치합니다. 주문 가격, 이익 실현 및 손실 제한 수준은 기본 가격 수준에 상대적으로 계산됩니다(ATR 단위로). 주문 만료 시간은 Expiration 입력 매개변수에 의해 정의됩니다.
//+------------------------------------------------------------------+ //| 숏 포지션(매도) 열기 조건 확인 | //+------------------------------------------------------------------+ bool CSignal2EMA_ITF::CheckOpenShort(double& price,double& sl,double& tp,datetime& expiration) { if(!(StateEMA(1)<0 && StateEMA(2)>0)) return(false); if(!m_time_filter.CheckOpenShort(price,sl,tp,expiration)) return(false); //--- double ema=SlowEMA(1); double atr=ATR(1); //--- price =m_symbol.NormalizePrice(ema+m_limit*atr); sl =m_symbol.NormalizePrice(price+m_stop_loss*atr); tp =m_symbol.NormalizePrice(price-m_take_profit*atr); expiration+=m_expiration*PeriodSeconds(m_period); //--- return(true); }
4. 숏 포지션 닫기
우리의 경우 숏 포지션을 닫기 위한 조건을 확인하는 함수는 항상 false를 반환합니다. 즉, 숏 포지션은 이익 실현 또는 손실 제한에 의해 닫힐 것으로 가정됩니다. 필요하다면 이 메서드를 구현한 코드를 작성할 수 있습니다.
//+------------------------------------------------------------------+ //| 숏 포지션 닫기 조건 확인 | //+------------------------------------------------------------------+ bool CSignal2EMA_ITF::CheckCloseShort(double& price) { return(false); }
5. 매수 미결제 주문의 트레일링 스톱
전문가 조언자는 현재의 이동 평균 값과 ATR에 따라 미결제 주문을 트레일링합니다.
//+--------------------------------------------------------------------+ //| 매수 미결제 주문 수정 조건 확인 | //+--------------------------------------------------------------------+ bool CSignal2EMA_ITF::CheckTrailingOrderLong(COrderInfo* order,double& price) { //--- 확인 if(order==NULL) return(false); //--- double ema=SlowEMA(1); double atr=ATR(1); double spread=m_symbol.Ask()-m_symbol.Bid(); //--- price=m_symbol.NormalizePrice(ema-m_limit*atr+spread); //--- return(true); }
6. 매도 미결제 주문의 트레일링 스톱
전문가 조언자는 현재의 이동 평균 값과 ATR에 따라 미결제 주문을 트레일링합니다.
주문이 시장 가격에 도달하면 주문이 실행됩니다.
//+--------------------------------------------------------------------+ //| 매도 미결제 주문 수정 조건 확인 | //+--------------------------------------------------------------------+ bool CSignal2EMA_ITF::CheckTrailingOrderShort(COrderInfo* order,double& price) { //--- 확인 if(order==NULL) return(false); //--- double ema=SlowEMA(1); double atr=ATR(1); //--- price=m_symbol.NormalizePrice(ema+m_limit*atr); //--- return(true); }
MQL5 위자드로 전문가 조언자 만들기
이 전략에 기반한 거래 로봇을 만들기 위해서는 MQL5 위자드의 “두 EMA 교차 기반의 트레이드 신호(시간 필터 포함)” 속성을 선택해야 합니다:

두 EMA 교차 기반의 트레이드 신호(시간 필터 포함)
다음으로 필요한 트레일링 스톱 알고리즘과 자금 및 위험 관리 시스템을 지정해야 합니다. 전문가 조언자의 코드는 자동으로 생성되며, 이를 컴파일하고 전략 테스터에서 테스트할 수 있습니다.
테스트 결과
전문가 조언자의 역사적 데이터에 대한 백테스트를 살펴보겠습니다 (EUenSD H1, 테스트 기간: 2010.1.1-2011.5.1, PeriodFastEMA=5, PeriodSlowEMA=30, PeriodATR=7, Limit=1.2, StopLoss=5, TakeProfit=8, Expiration=4, GoodMinuteOfHour=-1, BadMinutesOfHour=0, GoodHourOfDay=-1, BadHoursOfDay=0, GoodDayOfWeek=-1, BadDaysOfWeek=0).
고정 로트 거래, 0.1)을 사용했으며, 트레일링 스톱 알고리즘은 사용하지 않았습니다(트레일링 미사용).

두 EMA 교차 기반의 트레이드 신호(ITF 필터 미사용)
시간 필터를 사용하지 않기 때문에 많은 잘못된 신호가 발생합니다. 거래 신호는 거래 시간에 따른 결과 분석을 수행하면 개선될 수 있습니다.
이번 사례에서는 두 EMA의 교차가 6:00부터 23:59까지 많은 잘못된 신호를 제공한다는 것을 발견했습니다. 우리는 필터 매개변수를 설정하여 시간 필터를 지정할 수 있습니다.
예를 들어, 0:00부터 5:59까지 포지션을 여는 것을 허용하는 시간 필터를 지정할 수 있습니다. 이는 BadHoursOfDay=16777152=111111111111111111000000b 값을 설정하여 수행할 수 있습니다. 모든 다른 거래 시간은 “나쁜” 시간이므로, 6:00부터 하루의 끝까지 새로운 포지션을 여는 것을 금지하는 것이 좋습니다.
BadHoursOfDay=16777152 값을 설정하면 많은 잘못된 신호를 필터링할 수 있습니다:

두 EMA 교차 기반의 트레이드 신호(ITF 필터 사용)
CSignalITF는 시간 필터링 기능을 추가로 제공합니다(예: 시간 내의 좋은 및 나쁜 분, 하루의 좋은 및 나쁜 시간, 주의 좋은 및 나쁜 날 지정 등).
첨부 파일: Signal2EMA-ITF.mqh 파일은 terminal_data_folder\MQL5\Include\Expert\Signal 폴더에 배치해야 합니다.
expert_2ema_itf.mq5 파일에는 MQL5 위자드로 생성된 전문가 조언자의 코드가 포함되어 있습니다.