English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
세마포어 인디케이터를 사용하는 간단한 거래 시스템

세마포어 인디케이터를 사용하는 간단한 거래 시스템

MetaTrader 5트레이딩 시스템 | 5 7월 2021, 11:04
82 0
Nikolay Kositsin
Nikolay Kositsin

소개

세마포어 또는 신호 인디케이터는 시장 진입 또는 종료 시점을 나타내는 간단한 탐지기입니다. 현재 바에 진입 신호가있는 경우 해당 레이블이 기호 차트에 나타납니다. 그런 다음이 라벨을 거래를 수행하기 위한 조건으로 사용할 수 있습니다.

그런 종류의 지표가 많이 있지만 이러한 지표를 기반으로 한 원래 거래 시스템의 본질은 전혀 변하지 않았습니다. 따라서 가장 간단하고 보편적인 형태로 구현하는 것이 좋습니다. 이렇게 하면 상당한 변경없이 유사한 지표로 작업 할 때 얻은 결과를 추가로 사용할 수 있습니다.

그림.1. ASCtrend 세마포어 신호 인디케이터

그림.1. ASCtrend 세마포어 신호 인디케이터

그림.2. ASCtrend 표시. 거래 수행을 위한 거래 신호 

그림.2. ASCtrend 세마포어 신호 인디케이터를 사용하여 거래를 수행하기 위한 거래 신호


일반적인 세마포 신호 인디케이터의 샘플

현재 코드 베이스에는 이러한 지표가 많이 있습니다. 이 글에서는 적절한 웹 페이지에 대한 몇 가지 링크만 제공합니다.

세마포어 신호 인디케이터 외에도 세마포어 추세 인디케이터 그룹이 있습니다.

그림.3. Heiken_Ashi_Smoothed 인디케이터를 사용한 거래 신호 

그림.3. 세마포어 추세 인디케이터

 

그림.4. Heiken Ashi Smoothed 세마포어 추세 인디케이터를 사용하여 거래를 수행하기 위한 거래 신호

그림.4. Heiken Ashi Smoothed 세마포어 추세 인디케이터를 사용하여 거래를 수행하기 위한 거래 신호

이러한 지표를 사용하는 거래 시스템은 거래 신호를 얻기위한 코드가 약간 다른 반면 Expert Advisor 코드는 거의 변경되지 않습니다.

일반적인 세마포어 추세 인디케이터 샘플

코드베이스에는 이러한 지표가 많이 포함되어 있습니다. 이 글에서는 적절한 웹 페이지에 대한 몇 가지 링크만 제공합니다.

 

거래 시스템 구축을위한 기본 데이터:

  1. Expert Advisor에 표시되는 입력 매개 변수가있는 세마포어 인디케이터.
  2. 추가 입력 Expert Advisor 거래 매개 변수 목록:
    • 거래에 사용된 예금 재정 자원의 일부;
    • 손절매 및 이익 실현의 크기 (값이 0 인 경우 보류중인 주문을 사용해서는 안 됨).
    • 슬리 피지 (세트 가격과 실제 거래 가격의 최대 허용 차이)
    • 거래 신호가 수신되는 바의 색인;
    • 롱 및 숏 포지션 개설 허가;
    • 인디케이터 신호에 따라 롱 및 숏 포지션의 강제 청산 권한.

물론 범용 거래 기능을 사용하여 거래를 수행하기 위해 주문을 내리는 것이 훨씬 더 편리 할 것입니다. 이러한 함수는 매우 복잡하며 응용 프로그램 코드를 가능한 한 쉽게 만들기 위해 별도의 라이브러리 파일에 압축되어야 합니다.

세마포어 거래 시스템을 구현하는 Expert Advisor의 코드:

//+------------------------------------------------------------------+
//|                                                 Exp_ASCtrend.mq5 |
//|                             Copyright © 2011,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, Nikolay Kositsin"
#property link      "farria@mail.redcom.ru"
#property version   "1.00"
//+----------------------------------------------+
//| Expert Advisor indicator input parameters    |
//+----------------------------------------------+
input double MM=-0.1;             // Share of a deposit in a deal, negative values - lot size
input int    StopLoss_=1000;      // Stop loss in points
input int    TakeProfit_=2000;    // Take profit in points
input int    Deviation_=10;       // Max. price deviation in points
input bool   BuyPosOpen=true;     // Permission to buy
input bool   SellPosOpen=true;    // Permission to sell
input bool   BuyPosClose=true;    // Permission to exit long positions
input bool   SellPosClose=true;   // Permission to exit short positions
//+----------------------------------------------+
//| ASCtrend indicator input parameters          |
//+----------------------------------------------+
input ENUM_TIMEFRAMES InpInd_Timeframe=PERIOD_H1; // ASCtrend indicator time frame
input int  RISK=4;                               // Risk level
input uint SignalBar=1;                          // Bar index for getting an entry signal
//+----------------------------------------------+

int TimeShiftSec;
//---- declaration of integer variables for the indicators handles
int InpInd_Handle;
//---- declaration of integer variables of the start of data calculation
int min_rates_total;
//+------------------------------------------------------------------+
//| Trading algorithms                                               | 
//+------------------------------------------------------------------+
#include <TradeAlgorithms.mqh>
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---- getting ASCtrend indicator handle
   InpInd_Handle=iCustom(Symbol(),InpInd_Timeframe,"ASCtrend",RISK);
   if(InpInd_Handle==INVALID_HANDLE) Print(" Failed to get handle of ASCtrend indicator");

//---- initialization of a variable for storing a chart period in seconds  
   TimeShiftSec=PeriodSeconds(InpInd_Timeframe);

//---- initialization of variables of the start of data calculation
   min_rates_total=int(3+RISK*2+SignalBar);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//----
   GlobalVariableDel_(Symbol());
//----
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---- checking the number of bars to be enough for calculation
   if(BarsCalculated(InpInd_Handle)<min_rates_total) return;
   
//---- uploading history for IsNewBar() and SeriesInfoInteger() functions normal operation  
   LoadHistory(TimeCurrent()-PeriodSeconds(InpInd_Timeframe)-1,Symbol(),InpInd_Timeframe);

//---- declaration of local variables
   double DnVelue[1],UpVelue[1];
//---- declaration of static variables
   static bool Recount=true;
   static bool BUY_Open=false,BUY_Close=false;
   static bool SELL_Open=false,SELL_Close=false;
   static datetime UpSignalTime,DnSignalTime;
   static CIsNewBar NB;

//+----------------------------------------------+
//| Searching for deals performing signals       |
//+----------------------------------------------+
   if(!SignalBar || NB.IsNewBar(Symbol(),InpInd_Timeframe) || Recount) // checking for a new bar
     {
      //---- zeroing out trading signals
      BUY_Open=false;
      SELL_Open=false;
      BUY_Close=false;
      SELL_Close=false;
      Recount=false;

      //---- copy newly appeared data into the arrays
      if(CopyBuffer(InpInd_Handle,1,SignalBar,1,UpVelue)<=0) {Recount=true; return;}
      if(CopyBuffer(InpInd_Handle,0,SignalBar,1,DnVelue)<=0) {Recount=true; return;}

      //---- getting buy signals
      if(UpVelue[0] && UpVelue[0]!=EMPTY_VALUE)
        {
         if(BuyPosOpen) BUY_Open=true;
         if(SellPosClose) SELL_Close=true;
         UpSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec;
        }

      //---- getting sell signals
      if(DnVelue[0] && DnVelue[0]!=EMPTY_VALUE)
        {
         if(SellPosOpen) SELL_Open=true;
         if(BuyPosClose) BUY_Close=true;
         DnSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec;
        }

      //---- searching for the last trading direction for getting positions closing signals
      //if(!MQL5InfoInteger(MQL5_TESTING) && !MQL5InfoInteger(MQL5_OPTIMIZATION)) //if execution is set to "Random delay" in the Strategy Tester 
      if((BuyPosOpen && BuyPosClose || SellPosOpen && SellPosClose) && (!BUY_Close && !SELL_Close))
        {
         int Bars_=Bars(Symbol(),InpInd_Timeframe);

         for(int bar=int(SignalBar+1); bar<Bars_; bar++)
           {
            if(SellPosClose)
              {
               if(CopyBuffer(InpInd_Handle,1,bar,1,UpVelue)<=0) {Recount=true; return;}
               if(UpVelue[0]!=0 && UpVelue[0]!=EMPTY_VALUE)
                 {
                  SELL_Close=true;
                  break;
                 }
              }

            if(BuyPosClose)
              {
               if(CopyBuffer(InpInd_Handle,0,bar,1,DnVelue)<=0) {Recount=true; return;}
               if(DnVelue[0]!=0 && DnVelue[0]!=EMPTY_VALUE)
                 {
                  BUY_Close=true;
                  break;
                 }
              }
           }
        }
     }

//+----------------------------------------------+
//| Performing deals                             |
//+----------------------------------------------+
//---- Closing a long position
   BuyPositionClose(BUY_Close,Symbol(),Deviation_);

//---- Closing a short position   
   SellPositionClose(SELL_Close,Symbol(),Deviation_);

//---- Buying
   BuyPositionOpen(BUY_Open,Symbol(),UpSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_);

//---- Selling
   SellPositionOpen(SELL_Open,Symbol(),DnSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_);
//----
  }
//+------------------------------------------------------------------+

이러한 아이디어를 실현하기 위한 코드는 매우 간단하고 명확하지만 일부 세부 사항은 명확히 해야 합니다.

신호 인디케이터와 Expert Advisor가 사용하는 차트 기간은 Expert Advisor의 InpInd_Timeframe 입력 변수에 고정되어 있습니다. 따라서 Expert Advisor가 있는 차트를 변경해도 Expert Advisor에 대한 이 매개 변수는 변경되지 않습니다.

새로운 바 도착 순간을 결정하는 데 필요한 IsNewBar() 함수는 TradeAlgorithms.mqh 파일에 배치된 클래스로 구현됩니다. 이를 통해 각각에 대해 개별 정적 CIsNewBar 변수를 설정하여 코드에서 이러한 함수를 쉽게 사용할 수 있습니다.

UpSignalTime 및 DnSignalTime 변수는 시간을 저장하고 이전 거래 이후의 다음 거래를 거래 기능으로 전송할 수 있도록하는데 사용됩니다 저희의 경우 이 기능은 동일한 바에서 동일한 방향으로 여러 거래를 수행하는 것을 방지하는 데 사용됩니다 (거래를 수행 할 때 거래 기능은 현재 바 종료 시간을 저장하고 그 순간까지 같은 방향으로 새로운 거래를 수행하지 않습니다).

OnTick() 함수의 "마지막 거래 방향을 검색하여 포지션 청산 신호 얻기" 블록은 거래 신호가 없는 바에서 포지션 청산 신호를 수신하는 데 필요합니다. Expert Advisor 정상 작동시에는 필요하지 않습니다. 그러나 인터넷 연결이 실패할 경우 새로운 거래 신호를 놓칠 가능성이 높습니다. 사후에 시장에 진입하는 것은 좋은 생각이 아니지만 오픈 포지션을 청산하는 것은 현명한 조치입니다.

다른 세마포 신호 인디케이터와 함께 거래 시스템 사용

이제 이 코드를 다른 세마포 신호 인디케이터와 함께 사용해야 하는 경우 다음 작업을 수행해야 합니다.

  1. Expert Advisor 입력 매개 변수에서 새 지표의 필수 매개 변수로 이전 지표 데이터를 대체합니다.
  2. OnInit() 블록에서 인디케이터 핸들을 가져오는 코드를 변경합니다.
  3. 인디케이터 코드에서 매매 신호를 저장하는데 사용되는 인디케이터 버퍼의 인덱스를 결정하고 OnTick() 블록의 CopyBuffer() 함수 호출에 적절하게 입력합니다. 이 경우 0 및 첫 번째 인디케이터 버퍼가 사용됩니다.
  4. 지표 코드에 따라 Expert Advisor에서 데이터 계산 시작점 변수 (min_rates_total) 초기화 변경
  5. 인디케이터 코드에 따라 OnTick() 함수에서 "마지막 거래 방향을 검색하여 포지션 청산 신호 얻기" 블록을 변경합니다. 

다른 세마포어 추세 지표와 함께 거래 시스템 사용

세마포어 추세 인디케이터와 함께 이 거래 시스템을 사용할 때, Expert Advisor 코드는 OnTick() 함수 거래에 대한 신호를 결정하기 위해 블록에서 약간 변경되었습니다. 예를 들어, 코드는 FiboCandles 인디케이터를 기반으로하는 Expert Advisor에 대해 다음과 같이 보입니다.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---- checking the number of bars to be enough for calculation
   if(BarsCalculated(InpInd_Handle)<min_rates_total) return;
   
//---- uploading history for IsNewBar() and SeriesInfoInteger() functions  
   LoadHistory(TimeCurrent()-PeriodSeconds(InpInd_Timeframe)-1,Symbol(),InpInd_Timeframe);

//---- declaration of local variables
   double TrendVelue[2];
//---- declaration of static variables
   static bool Recount=true;
   static bool BUY_Open=false,BUY_Close=false;
   static bool SELL_Open=false,SELL_Close=false;
   static datetime UpSignalTime,DnSignalTime;
   static CIsNewBar NB;

//+----------------------------------------------+
//| Searching for deals performing signals       |
//+----------------------------------------------+
   if(!SignalBar || NB.IsNewBar(Symbol(),InpInd_Timeframe) || Recount) // checking for a new bar
     {
      //---- zeroing out trading signals
      BUY_Open=false;
      SELL_Open=false;
      BUY_Close=false;
      SELL_Close=false;
      Recount=false;

      //---- copy the newly obtained data into the arrays
      if(CopyBuffer(InpInd_Handle,4,SignalBar,2,TrendVelue)<=0) {Recount=true; return;}

      //---- getting buy signals
      if(TrendVelue[0]==1 && TrendVelue[1]==0)
        {
         if(BuyPosOpen) BUY_Open=true;
         if(SellPosClose)SELL_Close=true;
         UpSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec;
        }

      //---- getting sell signals
      if(TrendVelue[0]==0 && TrendVelue[1]==1)
        {
         if(SellPosOpen) SELL_Open=true;
         if(BuyPosClose) BUY_Close=true;
         DnSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec;
        }

      //---- searching for the last trading direction for getting positions closing signals
      //if(!MQL5InfoInteger(MQL5_TESTING) && !MQL5InfoInteger(MQL5_OPTIMIZATION)) //if execution is set to "Random delay" in the Strategy Tester 
        {
         if(SellPosOpen && SellPosClose  &&  TrendVelue[1]==0) SELL_Close=true;
         if(BuyPosOpen  &&  BuyPosClose  &&  TrendVelue[1]==1) BUY_Close=true;
        }
     }

//+----------------------------------------------+
//| Performing deals                             |
//+----------------------------------------------+
//---- Closing a long position
   BuyPositionClose(BUY_Close,Symbol(),Deviation_);

//---- Closing a short position   
   SellPositionClose(SELL_Close,Symbol(),Deviation_);

//---- Buying
   BuyPositionOpen(BUY_Open,Symbol(),UpSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_);

//---- Selling
   SellPositionOpen(SELL_Open,Symbol(),DnSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_);
//----
  }

이 경우 거래 신호는 하나의 색상 인디케이터 버퍼 (색상 인덱스 포함)에서만 수신됩니다. 이 버퍼의 데이터는 오름차순 시장의 경우 0과 내림차순의 경우 1의 두 가지 값만 가질 수 있습니다. "포지션 마감 신호를 얻기 위한 마지막 거래 방향 검색" 블록 코드는 가능한 한 간단해졌습니다. 모든 바의 추세 방향은 인디케이터 버퍼의 해당 셀에서 직접 수신할 수 있기 때문입니다.

"거래 수행" 블록에서는 포지션 청산 기능이 먼저 진행되고 그 다음으로 청산 기능이 수행됩니다. 반대 순서의 경우, 하나의 바에서만 거래를 성사 할 수 있으며 "공개 가격만"모드에서 테스트 할 때 동시에 열 수 없습니다! 따라서 거래 결과가 심각하게 중단됩니다.


거래 시스템 테스트

거래 시스템 테스트를 진행하기 전에 한 가지 중요한 세부 사항을 명확히해야 합니다. SignalBar 입력 변수 값이 0 인 경우 Expert Advisor는 현재 바에서 신호를 수행하는 거래를 가져옵니다. 그러나 현재의 바 신호는 이전 바에서 이 신호에 대해 이동한 추세의 변화를 나타내는 데 신뢰할 수 없습니다. 현재 바의 신호는 나타나고 사라질 수 있지만 추세는 오랫동안 이러한 신호에 대해 움직일 수 있습니다. 시각화를 활성화하고 SignalBar 변수가 0 인 모든 틱에서 Expert Advisor를 테스트하면 쉽게 확인할 수 있습니다. ASCtrend 지표 작동 시각화는 이러한 경우에 이 사실에 대한 매우 명확한 증거를 제공합니다.

다시 말하지만, "Every tick"모드만 현재 바에서 수신된 신호를 사용하는 Expert Advisor 최적화에 적합합니다. 이미 폐쇄된 다른 바에서 받을 경우 "오픈 가격만" 모드로 충분합니다. 이는 품질에 심각한 손실없이 거래 시스템 행동 분석을 크게 가속화합니다.

따라서 이러한 거래 시스템의 테스트 및 최적화를 위해 현재 바의 신호를 사용하지 않는 것이 좋습니다!

따라서 연초부터 12 월 초까지 EUR/USD의 기본 매개 변수를 사용하여 Expert Advisor를 테스트 해 보겠습니다.

그림.5. EUR/USD H1에 대한 기본 매개 변수가 있는 Exp_ASCtrend Expert Advisor의 테스트 결과 

Fig.5. EUR/USD H1에 대한 기본 매개 변수가 있는 Exp_ASCtrend Expert Advisor의 테스트 결과

Strategy Tester에서 Expert Advisor 설정을 약간 변경하면 기존 기록 데이터에 가장 적합한 Expert Advisor 매개 변수 조합을 매우 쉽게 찾을 수 있습니다.

 그림.6. EUR/USD H1에 대한 더 나은 매개 변수로 최적화 후 Exp_ASCtrend Expert Advisor의 테스트 결과

그림.6. EUR/USD H1에 대한 더 나은 매개 변수로 최적화 후 Exp_ASCtrend Expert Advisor의 테스트 결과

거래 시스템 최적화 프로세스에는 특이성이 없으므로이 프로세스를 자세히 설명하는 글 에 대한 링크를 하나만 제공합니다: "MQL5 : MQL5에서 Expert Advisors 테스트 및 최적화 가이드".

물론 이런 간단한 거래 시스템으로 괄목할 만한 수익을 기대하는 것은 순진하다. 그러나 이 반자동 시스템을 능숙하게 다루고 시장의 현재 행동에 따라 정기적으로 조정하면 좋은 결과를 얻을 수 있습니다.

예를 들어, 2011년 1월부터 5월까지 EUR/USD H12 차트에는 상승 추세가 있었습니다. 그리고 초기 단계에서 쉽게 감지 할 수 있었습니다.

그림.7. EUR/USD H12 차트 (1월/5월 2011)

그림.7. EUR/USD H12 차트 (1월/5월 2011)

이 시간 간격에서 기본 설정, 구매만 가능, 예금의 5% 만 사용 (MM=0.05)으로 Expert Advisor를 테스트하는 것은 흥미로울 것입니다. 다음은 H1 차트에서 이러한 매개 변수를 테스트 한 Expert Advisor의 결과입니다.

그림.8. 2011년 1월/5월 EUR/USD H1에 대한 기본 매개 변수가 있는 Exp_ASCtrend Expert Advisor의 테스트 결과 (매수 포지션 만 해당, MM=0.05) 

Fig.8. 2011년 1월/5월 EUR/USD H1에 대한 기본 매개 변수가있는 Exp_ASCtrend Expert Advisor의 테스트 결과 (매수 포지션만 해당, MM=0.05)

물론 이 경우 거래 방향을 선택하는 것은 트레이더가 전적으로 책임집니다. 그러나 큰 시간 프레임 차트를 사용하여 수행해야한다는 것을 명심하면 어려움에 거의 직면하지 않을 것입니다.


다른 지표와 함께 사용하기 위한 거래 모듈의 수정

이 글은 여기서 끝낼 수 있었지만 MetaEditor는 미리 만들어진 거래 모듈을 기반으로 전문 고문을 생성 할 수 있는 가능성을 획득했습니다. 여기에 제시된 모든 자료를 고려하여 이러한 모듈을 만드는 과정은 매우 복잡하며 별도의 연구가 필요합니다. 따라서 내가 제안한 거래 시스템과 완전히 유사한 이미 생성 된 거래 모듈에 초점을 맞출 것입니다. 그리고 그 후에야 불필요한 삭제를 피하는 특정 신호 인디케이터에 따라 이러한 모듈 수정에 대한 세부 정보로 이동합니다.

세마포어 신호 시스템 (MySignals.zip)에 대한 거래 모듈 모음이 이미 있고 특정 지표에 대한 유사한 모듈을 만들고 싶다고 가정해 보겠습니다. 일반적인 세마포어 신호 인디케이터인 BykovTrendSignal.mq5 인디케이터로 합시다. 우선, 이 컬렉션 (Indicators.zip)에서 가장 정확한 지표 아날로그를 찾아야 합니다. 시각적으로 저희는 이 글 (ASCtrend)의 첫 번째 지표가 이와 가장 유사하다고 판단합니다. 따라서 수정을 위해 이 지표의 거래 모듈을 사용합니다.

필수 프로그램 코드에서의 사용을 고려할 때 인디케이터 자체 (BykovTrend)에는 입력 매개 변수 세트가 있습니다.

//+----------------------------------------------+
//| Indicator input parameters                   |
//+----------------------------------------------+
input int RISK=3;
input int SSP=9;
//+----------------------------------------------+

그리고 거래를 수행하기 위해 신호를 저장하는데 사용되는 인디케이터 버퍼의 인덱스가 필요합니다. 여기서는 0 - 매도 신호, 1 - 매수 신호입니다

수정에 사용할 모듈을 알았으니 이제 BykovTrendSignal.mqh 파일 이름으로\MQL5\Include\Expert\Signal\MySignals\ 폴더에 복사 한 다음 MetaEditor에서 엽니다. 사용된 코드에 정기적으로 발견되는 "ASCtrend"(이전 인디케이터 이름) 표현식이 있습니다. 새 인디케이터의 이름인 "BykovTrend"로 바꿔야 합니다. 이렇게 하려면 "Ctrl" 및 "H"키를 동시에 누르고 필요한 변경을 수행하십시오.

 거래 모듈 코드에서 지표 이름 바꾸기

그림.9. 거래 모듈 코드에서 지표 이름 바꾸기

저희 작업의 다음 단계는 가장 세심한 작업입니다. 거래 모듈 코드에서 지표 입력 매개 변수와 관련된 모든 것을 교체해야 합니다. 이 과정은 글 에 명시된 것과 매우 유사합니다. "MQL5 마법사: 거래 신호 모듈을 만드는 방법".

먼저, MQL5 마법사 거래 신호 클래스 설명의 주석 처리된 블록을 약간 변경해야 합니다

//+----------------------------------------------------------------------+
//| Description of the class                                             |
//| Title=The signals based on BykovTrend indicator                      |
//| Type=SignalAdvanced                                                  |
//| Name=BykovTrend                                                      |
//| Class=CBykovTrendSignal                                              |
//| Page=                                                                |
//| Parameter=BuyPosOpen,bool,true,Permission to buy                     |
//| Parameter=SellPosOpen,bool,true,Permission to sell                   |
//| Parameter=BuyPosClose,bool,true,Permission to exit a long position   |
//| Parameter=SellPosClose,bool,true,Permission to exit a short position |
//| Parameter=Ind_Timeframe,ENUM_TIMEFRAMES,PERIOD_H1,Timeframe          |
//| Parameter=RISK,int,4,Risk level                                      |
//| Parameter=SSP,int,9,SSP                                              |
//| Parameter=SignalBar,uint,1,Bar index for entry signal                |
//+----------------------------------------------------------------------+
//--- wizard description end
//+----------------------------------------------------------------------+
//| CBykovTrendSignal class.                                             |
//| Purpose: Class of generator of trade signals based on                |
//| BykovTrend indicator https://www.mql5.com/ru/code/497/.               |
//|             Is derived from the CExpertSignal class.                 |
//+----------------------------------------------------------------------+

두 인디케이터 모두 동일한 위험 입력 변수를 포함하므로 그대로 둘 수 있습니다. 그러나 이러한 지표에서는 기본값이 다릅니다. 사실, 이 차이는 중요하지 않으며 변경되지 않을 수 있습니다. SSP 변수에 대한 주석 줄이 추가되었습니다.

//| Parameter=SSP,int,9,SSP                                    |

그리고 코드베이스 인디케이터에 대한 링크가 대체되었습니다.

//| Purpose: Class of generator of trade signals based on      |
//| BykovTrend values https://www.mql5.com/ru/code/497/.        |

이제 입력 매개 변수의 변경과 관련된 모든 것은 CBykovTrendSignal 거래 신호 클래스의 설명에 반영되어야 합니다. 설정 매개 변수에 새로운 전역 m_SSP 클래스 변수 선언 라인이 있습니다.

   uint              m_SSP;              // SSP

 새 SSP() 설정 매개 변수 설치 방법 선언의 행:

   void               SSP(uint value)                         { m_SSP=value;              } 

저희가 생성하는 거래 신호 모듈의 위험 입력 변수와 관련된 모든 것은 입력 모듈과 동일하므로 현재 및 기타 거래 모듈 블록에는 변경 사항이 없습니다.

이제 CBykovTrendSignal::CBykovTrendSignal() 클래스 생성자에 전달합니다. 새 변수의 초기화는이 블록에 추가되어야 합니다.

   m_SSP=4;

CBykovTrendSignal::ValidationSettings() 설정 매개 변수 검증 블록에서 새 변수의 정확성을 확인해야 합니다.

   if(m_SSP<=0)
     {
      printf(__FUNCTION__+": SSP must be above zero");
      return(false);
     }

그 후 BykovTrend 인디케이터 초기화 블록인 BykovTrendSignal::InitBykovTrend()로 전달할 수 있습니다. 새 인디케이터에는 입력 변수 수가 다르므로 선언된 입력 매개 변수 배열의 차원도 다릅니다.

//--- setting the indicator parameters
   MqlParam parameters[3];

이 경우 인디케이터 문자열 이름에 1 차원이 필요하고 입력 매개 변수에 2 차원이 더 필요합니다.

이제 입력 매개 변수 배열의 새 셀을 초기화하여 여기에 저장할 변수의 유형을 지정해야 합니다.

   parameters[2].type=TYPE_INT;
   parameters[2].integer_value=m_SSP;

 그 후 인디케이터 초기화 호출에서이 블록에서 입력 변수의 수를 3으로 변경합니다.

//--- object initialization   
   if(!m_indicator.Create(m_symbol.Name(),m_Ind_Timeframe,IND_CUSTOM,3,parameters))

인디케이터의 인디케이터 버퍼 수는 동일하고 2 개이므로, 저희의 경우 인디케이터 버퍼 번호 초기화 라인에서 아무것도 변경할 필요가 없습니다.

//--- number of buffers
   if(!m_indicator.NumBuffers(2))  return(false);

ASCtrend 및 BykovTrend 지표에는 각각 두 개의 지표 버퍼가 있습니다. 버퍼의 기능은 완전히 유사합니다. 제로 버퍼는 매도 신호를 저장하는 데 사용되며 인덱스가 1 인 버퍼는 매수 신호를 저장하는 데 사용됩니다. 따라서 CBykovTrendSignal::LongCondition() 및 CBykovTrendSignal::ShortCondition() 거래 신호를 전달하기 위한 함수 블록에서 아무것도 변경할 필요가 없으며 거래 신호 모듈 수정 작업이 완료된 것으로 간주 될 수 있습니다.

그러나 일반적으로 모든 세마포어 인디케이터는 다르므로 서로 다른 세마포어 인디케이터에 대한 이러한 블록은 서로 상당히 다를 수 있습니다. MySignals.zip 거래 모듈 아카이브와 적절한 Indicators.zip 아카이브에는 다양한 지표를 만들기위한 충분한 양의 예제가 포함되어 있습니다. 몇 가지 검사 후 교체 프로세스의 세부 사항과 가능한 코드 버전을 찾을 수 있습니다.

이제 거래 신호 모듈의 Ind_Timeframe 입력 변수에 집중하겠습니다. 이 변수를 사용하면 적절한 시간 프레임을 인디케이터에 다운로드 할 수 있습니다. 그러나 생성된 Expert Advisor는 할당된 시간 프레임에서 작동합니다. 이는 Ind_Timeframe 입력 변수 시간 프레임이 Expert Advisor가 모듈 정상 작동을 제공하기 위해 작동하는 차트의 기간을 초과하지 않아야 함을 의미합니다.

마지막으로 거래 신호 모듈을 만드는 또 다른 특징을 밝히고 싶습니다. 모듈 입력 변수의 유형으로 기본 인디케이터 코드에 사용자 지정 열거 형이 구현되는 경우가 있습니다. 예를 들어 Smooth_Method 사용자 정의 열거는 Candles_Smoothed 인디케이터에 대한 MA_SMethod 변수 유형으로 사용됩니다.

//+-----------------------------------+
//|  Declaration of enumerations      |
//+-----------------------------------+
enum Smooth_Method
  {
   MODE_SMA_,  // SMA
   MODE_EMA_,  // EMA
   MODE_SMMA_, // SMMA
   MODE_LWMA_, // LWMA
   MODE_JJMA,  // JJMA
   MODE_JurX,  // JurX
   MODE_ParMA, // ParMA
   MODE_T3,    // T3
   MODE_VIDYA, // VIDYA
   MODE_AMA,   // AMA
  }; */
//+----------------------------------------------+
//| Indicator input parameters                   |
//+----------------------------------------------+
input Smooth_Method MA_SMethod=MODE_LWMA; // Smoothing method
input int MA_Length=30;                   // Smoothing depth                    
input int MA_Phase=100;                   // Smoothing parameter
                                          // for JJMA varying within the range -100 ... +100,
                                          // for VIDIA it is a CMO period, for AMA it is a slow average period
//+----------------------------------------------+

이러한 경우 해당 종류의 입력 변수와 거래 신호 모듈 (Candles_SmoothedSignal.mqh)의 모든 관련 요소는 int 또는 uint 유형의 변수로 수정되어야 합니다. 또한 완성된 Expert의 이미 생성 된 코드에서이 입력 변수를 쉽게 사용할 수 있도록 Expert Advisor 입력 매개 변수까지 사용자 지정 열거의 역순으로 수행하고 필요한 입력 변수 유형 (ExpM_Candles_Smoothed Expert Advisor)을 교체해야 합니다.

//+------------------------------------------------------------------+
//|  Declaration of enumerations                                     |
//+------------------------------------------------------------------+
enum Smooth_Method
  {
   MODE_SMA_,  // SMA
   MODE_EMA_,  // EMA
   MODE_SMMA_, // SMMA
   MODE_LWMA_, // LWMA
   MODE_JJMA,  // JJMA
   MODE_JurX,  // JurX
   MODE_ParMA, // ParMA
   MODE_T3,    // T3
   MODE_VIDYA, // VIDYA
   MODE_AMA,   // AMA
  };
//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
//--- inputs for expert
input string          Expert_Title         ="Candles_Smoothed"; // Document name
ulong                 Expert_MagicNumber   =29976;              // 
bool                  Expert_EveryTick     =false;              // 
//--- inputs for main signal
input int             Signal_ThresholdOpen =40;                 // Signal threshold value to open [0...100]
input int             Signal_ThresholdClose=20;                 // Signal threshold value to close [0...100]
input double          Signal_PriceLevel    =0.0;                // Price level to execute a deal
input double          Signal_StopLevel     =50.0;               // Stop Loss level (in points)
input double          Signal_TakeLevel     =50.0;               // Take Profit level (in points)
input int             Signal_Expiration    =1;                  // Expiration of pending orders (in bars)
input bool            Signal__BuyPosOpen   =true;               // Candles_Smoothed() Permission to buy
input bool            Signal__SellPosOpen  =true;               // Candles_Smoothed() Permission to sell
input bool            Signal__BuyPosClose  =true;               // Candles_Smoothed() Permission to exit a long position
input bool            Signal__SellPosClose =true;               // Candles_Smoothed() Permission to exit a short position
input ENUM_TIMEFRAMES Signal__Ind_Timeframe=PERIOD_H1;            // Candles_Smoothed() Timeframe
input Smooth_Method   Signal__MA_SMethod   =4;                  // Candles_Smoothed() Smoothing method (1 - 10)
input uint            Signal__MA_Length    =30;                 // Candles_Smoothed() Smoothing depth
input uint            Signal__MA_Phase     =100;                // Candles_Smoothed() Smoothing parameter
input uint            Signal__SignalBar    =1;                  // Candles_Smoothed() Bar index for the entry signal
input double          Signal__Weight       =1.0;                // Candles_Smoothed() Weight [0...1.0]
//--- inputs for money
input double          Money_FixLot_Percent =10.0;               // Percent
input double          Money_FixLot_Lots    =0.1;                // Fixed volume

저희의 경우 이것은 Signal__MA_SMethod 입력 변수로 수행되었습니다.

편집기에서 두 코드 버전 (ASCtrendSignal.mqh 및 BykovTrendSignal.mqh)을 동시에 열고 (하나는 왼쪽에, 다른 하나는 오른쪽에 배치) 두 코드 버전을주의 깊게 비교하면 코드 수정을 상당히 가속화 할 수 있습니다.

결론

이 글 에 첨부 된 Experts.zip 아카이브에 세마포어 거래 시스템을 기반으로 충분한 양의 Expert Advisors를 배치하여 초보자 Expert Advisors 작성자가 이러한 코드를 작성하는 모든 기능을 쉽게 이해하거나 꽤 인기있는 지표를 이용해 적어도 미리 만들어진 Expert Advisors와 함께 작업 할 수 있습니다.

첨부된 모든 Expert Advisors는 자체 거래 시스템의 기반으로 거래 전략 생성기를 사용하려는 사람들을 위해 거래 모듈로 추가로 제공됩니다. 이 모듈은 MySignals.zip에 있으며, 이를 기반으로하는 거래 시스템은 Expertsez.zip에서 찾을 수 있습니다. Expert Advisors에서 사용되는 지표는 Indicators.zip에 있습니다. 파일을 추출하는 경로는 다음과 같습니다.

  • Experts.zip: "\MQL5\Experts\";
  • Expertsez.zip: "\MQL5\Experts\"; 
  • MySignals.zip: "\MQL5\Include\Expert\Signal\MySignals\"; 
  • Indicators.zip: "\MQL5\Indicators\";
  • SmoothAlgorithms.mqh: "\Include\";
  • TradeAlgorithms.mqh: "\Include\".

MetaEditor를 다시 시작하고 네비게이터 (Navigator) 창을 열고 MQL5 레이블을 마우스 오른쪽 버튼으로 클릭 한 다음 팝업 메뉴에서 "Compile"을 선택합니다.

SmoothAlgorithms.mqh 파일은 Indicators.zip의 일부 지표를 컴파일하는 데 필요하며 TradeAlgorithms.mqh 파일은 Experts.zip의 모든 Expert Advisors를 컴파일하는 데 필요합니다.

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

파일 첨부됨 |
expertsez.zip (31.51 KB)
mysignals.zip (44.08 KB)
indicators.zip (39.15 KB)
experts.zip (34.67 KB)
6 단계로 나만의 거래 로봇을 만드세요! 6 단계로 나만의 거래 로봇을 만드세요!
거래 클래스가 어떻게 구성되는지 모르고 "객체 지향 프로그래밍" 이라는 단어가 두렵다면 이 글이 당신에게 딱입니다. 사실, 거래 신호 모듈을 작성하기 위해 세부 사항을 알 필요가 없습니다. 몇 가지 간단한 규칙을 따르십시오. 나머지는 모두 MQL5 마법사가 수행하고 즉시 사용 가능한 거래 로봇을 얻게 됩니다!
다중 시간대 및 다중 통화 패널 구축을 위한 객체 지향 접근 방식 다중 시간대 및 다중 통화 패널 구축을 위한 객체 지향 접근 방식
이 글에서는 MetaTrader 5 용 다중 시간 프레임 및 다중 통화 패널을 생성하는데 객체 지향 프로그래밍을 사용하는 방법을 설명합니다. 주요 목표는 패널 자체의 코드를 수정할 필요 없이 가격, 가격 변동, 지표 값 또는 맞춤형 구매/판매 조건과 같은 다양한 종류의 데이터를 표시하는 데 사용할 수 있는 범용 패널을 구축하는 것입니다.
MetaTrader 5 - 상상 이상! MetaTrader 5 - 상상 이상!
MetaTrader 5 클라이언트 터미널은 처음부터 개발되었으며 물론 이전 제품을 훨씬 능가합니다. 새로운 거래 플랫폼은 모든 금융 시장에서 거래할 수 있는 무한한 기회를 제공합니다. 또한 그 기능은 더욱 유용한 기능과 편리함을 제공하기 위해 계속 확장되고 있습니다. 따라서 MetaTrader 5의 수많은 장점을 모두 나열하는 것은 매우 어렵습니다. 우리는 그것들을 하나의 기사로 간략하게 설명하려고했는데 그 결과에 놀랐습니다. 기사가 간단하지 않습니다!
객체 지향 프로그래밍의 기초 객체 지향 프로그래밍의 기초
객체 지향 프로그래밍 (OOP)을 사용하기 위해 다형성, 캡슐화 등이 무엇인지 알 필요가 없습니다. 단순히 이러한 기능을 사용할 수 있습니다. 이 글에서는 실습 예제를 통해 OOP의 기본 사항을 다룹니다.