English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
MQL4에서 MQL5로 인디케이터 넘기기

MQL4에서 MQL5로 인디케이터 넘기기

MetaTrader 5 | 5 7월 2021, 13:46
135 0
Vasily
Vasily

들어가며

독자 여러분 안녕하세요!

오늘 이 문서에서는 단순 매매가 계산을 MQL4에서 MQL5로 옮기는 알고리즘을 다룰 것입니다. MQL4와 5간의 차이를 보고 나서 제가 mql4_2_mql5.mqh 라이브러리를 추가했습니다; 이 문서를 읽은 후에 어떻게 쓰면 되는지 배울 것입니다.

1. 전환을 위해 인디케이터 준비하기

이 문서는 인디케이터 계산만 전환하는 것에 대한 내용입니다. 인디케이터에 그래픽 요소 또는 보다 복잡한 가격 계산이 포함된 경우 인디케이터 사용에 어려움이 있을 수 있습니다.

우선, 우리는 전환용 MQL4 코드를 준비해야 합니다. 뭐가 필요한지 한 번 봅시다.

적절한 인디케이터로 MetaEditor 4를 여십시오, 예를 들면 MACD가 있습니다; 그리고 입력 패러미터를 변경하기 시작합시다:

//---- indicator parameters
extern int FastEMA=12;
extern int SlowEMA=26;
extern int SignalSMA=9;
//---- indicator buffers
double     MacdBuffer[];
double     SignalBuffer[];

우리는 이 모든 것을 다음과 같은 상태로 만들어야 합니다:

double &MacdBuffer[],double &SignalBuffer[],int FastEMA,int SlowEMA,int SignalSMA

줄 시작 부분에 인디케이터 버퍼가 이름 앞에 & 기호와 함께 지정됩니다. 그 이유는 모든 변경사항이 적용되어야할 어레이들의 링크를 보내야지 어레이 자체를 보내면 안되기 때문입니다!!!

이 다음이 입력 패러미터 차례입니다. MQL4 인디케이터에서 이하의 줄을 바꾸십시오:

int start()

에서

int start(int rates_total,
         int prev_calculated,
         double &MacdBuffer[],
         double &SignalBuffer[],
         int FastEMA,
         int SlowEMA,
         int SignalSMA)

보시다시피 필수 요소가 2개 더 생겼습니다:

int rates_total, int prev_calculated,

다음 파트는 이전에 이미 형성한 줄입니다.

마지막 심볼까지의 전체 섹션을 복사하세요.

//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence                           |
//+------------------------------------------------------------------+
int start(int rates_total
         ,int prev_calculated
         ,double &MacdBuffer[]
         ,double &SignalBuffer[]
         ,int FastEMA
         ,int SlowEMA
         ,int SignalSMA)
  {
   int limit;
   int counted_bars=IndicatorCounted();
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
//---- macd counted in the 1-st buffer
   for(int i=0; i<limit; i++)
      MacdBuffer[i]=iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i)
                     -iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//---- signal line counted in the 2-nd buffer
   for(i=0; i<limit; i++)
      SignalBuffer[i]=iMAOnArray(MacdBuffer,Bars,SignalSMA,0,MODE_SMA,i);
//---- done
   return(0);
  }
//+------------------------------------------------------------------

2. MQL4 프로그램을 위해 MQL5 템플릿 만들기

이제 우리 섹션에 맞는 환경을 준비해야 합니다.

MetaEditor 5 메뉴에서 "New"를 누르고 그 후 "Custom indicator"를 선택하십시오.

MQL4 인디케이터의 입력 패러미터대로 입력 패러미터 (1번 그림)을 만드세요:

//---- indicator parameters
extern int FastEMA=12;
extern int SlowEMA=26;
extern int SignalSMA=9;

MACD 인디케이터의 입력 패러미터

1번 그림. MACD 인디케이터 의 입력패러미터

다음으로, MQL4 프로그램에 쓰인대로 인디케이터 버퍼 (2번 그림)을 만드세요:

//---- indicator buffers
double     MacdBuffer[];
double     SignalBuffer[];

MACD의 인디케이터 버퍼

2번 그림. MACD의 인디케이터 버퍼

이제 새 인디케이터를 위한 템플릿을 완성했습니다.

여기에다 몇가지를 변경시켜야합니다. 입력 패러미터들 위해 선 하나를 추가하십시오:

#include <mql4_2_mql5.mqh>
//--- input parameters

함수에:

int OnInit()

선을 추가

    InitMql4();
MQL4 프로그램의 환경을 시작하는 라인을 프로그램의 본문에 추가합니다.
int bars=MQL4Run(rates_total,prev_calculated);
// bars - number of bars available to MQL4 programs

보시는 것처럼 이 함수는 MQL4 환경에 사용할 수 있는 바 수를 반환합니다. 여기에도 새 변수가 나타납니다. 

int CountedMQL4;

이 변수는 MQL5 쪽의 변수와 유사합니다

 prev_calculated,

CountedMQL4 변수는 포함된 파일에 있고; 이걸 통해 계산된 데이터의 양을 전달합니다.

그런 다음 준비한 MQL4 섹션을 마지막 심볼 뒤에 형성된 MQL5 템플릿에 삽입합니다.

이제 인디케이터를 시작합니다.

그렇게 하기 위해선 다음 라인을 프로그램의 본문에 넣으십시오:

Start(bars,
      CountedMQL4,
      MacdBuffer,
      SignalBuffer,
      FastEMA,
      SlowEMA,
      SignalSMA);

보시다시피 이 라인은 MQL4 프로그램에 필요한 데이터뿐만 아니라 MQL5에서 생성된 템플릿에서 가져올 결과 버퍼에 대한 링크를 전달합니다.

다음과 같은 결과를 얻을 수 있습니다:

//+------------------------------------------------------------------+
//|                                                     MACD_MQ4.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot MacdBuffer
#property indicator_label1  "MacdBuffer"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot SignalBuffer
#property indicator_label2  "SignalBuffer"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- input parameters
#include <mql4_2_mql5.mqh>
input int      FastEMA=12;
input int      SlowEMA=26;
input int      SignalSMA=9;
//--- indicator buffers
double         MacdBuffer[];
double         SignalBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MacdBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
//---
   InitMql4();
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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 bars=MQL4Run(rates_total,prev_calculated);
// bars - number of bars available to MQL4 programs

   Start(bars,
         CountedMQL4,
         MacdBuffer,
         SignalBuffer,
         FastEMA,
         SlowEMA,
         SignalSMA);//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence                           |
//+------------------------------------------------------------------+
int Start(int rates_total,
         int prev_calculated,
         double &MacdBuffer[],
         double &SignalBuffer[],
         int FastEMA,
         int SlowEMA,
         int SignalSMA)
  {
   int limit;
   int counted_bars=IndicatorCounted();
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
//---- macd counted in the 1-st buffer
   for(int i=0; i<limit; i++)
      MacdBuffer[i]=iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i)
                       -iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//---- signal line counted in the 2-nd buffer
   for(i=0; i<limit; i++)
      SignalBuffer[i]=iMAOnArray(MacdBuffer,Bars,SignalSMA,0,MODE_SMA,i);
//---- done
   return(0);
  }

이는 전환의 첫 단계에 불과합니다; 이제 인디케이터를 디버깅해보겠습니다.

3. MQL5 인디케이터를 다룰 때 주의해야할 점

MQL4의 사전 정의된 변수들 여럿은 MQL5의 사전 정의된 변수들의 이름과 1:1로 대응되므로 전환된 MQL4 섹션을 다음과 같이 변경해야 합니다.

MQL4
MQL5
IndicatorCounted()
prev_calculated
 Bars rates_total
 iMA( iMAMql4(
 iMAOnArray( iMAOnArrayMql4(
//+--------------------+------------------+
//|              MQL4  | MQL5             |
//+--------------------+------------------+
//|IndicatorCounted()  | prev_calculated  |
//|              Bars  | rates_total      |
//|              iMA(  | iMAMql4(         |
//|       iMAOnArray(  | iMAOnArrayMql4(  |
//+--------------------+------------------+ 

데이터 스토리지 조직의 특성에 대해 MQL5 레퍼런스에서는 SetIndexBuffer()에 대해 다음과 같이 설명합니다.

기타

바인드 후, 동적 어레이 buffer[]는타임시리즈의 인덱싱이 바운드 어레이 용으로 사전 설치되었다해도 일반 어레이들처럼 인덱싱 될 것입니다. 만약 인디케이터 어레이의 요소들에 대한 액세스 순서를 바꾸고 싶다면 SetIndexBuffer() 함수로 어레이를 바인딩 한 후 ArraySetAsSeries() 함수를 사용하십시오.

따라서 인디케이터 버퍼에 액세스하는 초기 정책은 이제 일반 어레이에서 작동하는 것과 같으므로 항상 다음 바인딩을 추가해야 합니다.

   ArraySetAsSeries(MacdBuffer,true);
   ArraySetAsSeries(SignalBuffer,true);

결과 코드는 이렇습니다:

//+------------------------------------------------------------------+
//|                                                    MACD_MQL4.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot MacdBuffer
#property indicator_label1  "MacdBuffer"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot SignalBuffer
#property indicator_label2  "SignalBuffer"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

#include <mql4_2_mql5.mqh>
//--- input parameters
input int      FastEMA=12;
input int      SlowEMA=26;
input int      SignalSMA=9;
//--- indicator buffers
double         MacdBuffer[];
double         SignalBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MacdBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
//---   
   InitMql4();
//---
   ArraySetAsSeries(MacdBuffer,true);
   ArraySetAsSeries(SignalBuffer,true);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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 bars=MQL4Run(rates_total,prev_calculated);
// bars - number of bars available for MQL4 programs   
   Start(bars,
         CountedMQL4,
         MacdBuffer,
         SignalBuffer,
         FastEMA,
         SlowEMA,
         SignalSMA);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence                           |
//+------------------------------------------------------------------+
//+--------------------+------------------+
//|              MQL4  | MQL5             |
//+--------------------+------------------+
//|IndicatorCounted()  | prev_calculated  |
//|              Bars  | rates_total      |
//|              iMA(  | iMAMql4(         |
//|       iMAOnArray(  | iMAOnArrayMql4(  |
//+--------------------+------------------+ 
int Start(int rates_total,
         int prev_calculated,
         double &MacdBuffer[],
         double &SignalBuffer[],
         int FastEMA,
         int SlowEMA,
         int SignalSMA)
  {
   int limit;
   int counted_bars=prev_calculated;
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=rates_total-counted_bars;
//---- macd counted in the 1-st buffer
   for(int i=0; i<limit; i++)
      MacdBuffer[i]=iMAMql4(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i)
                    -iMAMql4(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//---- signal line counted in the 2-nd buffer
   for(int i=0; i<limit; i++)
      SignalBuffer[i]=iMAOnArrayMql4(MacdBuffer,rates_total,SignalSMA,0,MODE_SMA,i);
//---- done
   return(0);
  }
//+------------------------------------------------------------------+

실행 결과는 3번 그림에 나타나있습니다:

3번 그림. MQL4에서 MQL5 표준으로 다시 쓰인 MACD 인디케이터의 비교.


4. Stochastic 인디케이터 전환 예시

MetaEditor 5에서 인디케이터를 위한 새 템플릿을 만들어 봅시다 (그림 4-5):

입력 패러미터

4번 그림. 입력 패러미터

버퍼

5번 그림. 버퍼

디버깅 하는 동안 MQL4 "OnInit" 함수의 여러 계산이 "Start" 함수로 옮겨져야한단걸 확인했습니다. 이것은 다음과 같이 복제하는걸로 충분합니다:

int draw_begin1=KPeriod+Slowing;
int draw_begin2=draw_begin1+DPeriod;
또한 우리의 MQL4 프로그램 내의 버퍼 2개는 내부 계산에 사용되고 나머지 2개는 그림 그리기에 사용되므로 그림 그리기용 버퍼의 수를 바꿀 필요가 있습니다.
#property indicator_plots   2

또한 내부 계산을 위해 MQL4 프로그램에서 사용할 버퍼의 상태를 변경합니다.

   SetIndexBuffer(2,HighesBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,LowesBuffer,INDICATOR_CALCULATIONS);
필요한 변경을 합시다:
//+------------------------------------------------------------------+
//|                                              Stochastic_MQL4.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 4
#property indicator_plots   2
//--- plot MainBuffer
#property indicator_label1  "MainBuffer"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot SignalBuffer
#property indicator_label2  "SignalBuffer"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

#include <mql4_2_mql5.mqh>
//--- input parameters
input int      Kperiod=14;
input int      Dperiod=5;
input int      Slowing=5;
//--- indicator buffers
double         MainBuffer[];
double         SignalBuffer[];
double         HighesBuffer[];
double         LowesBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,HighesBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,LowesBuffer,INDICATOR_CALCULATIONS);
//---
    InitMql4();
//---
   ArraySetAsSeries(MainBuffer,true);
   ArraySetAsSeries(SignalBuffer,true);
   ArraySetAsSeries(HighesBuffer,true);
   ArraySetAsSeries(LowesBuffer,true);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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 bars=MQL4Run(rates_total,prev_calculated);
// bars - количество баров, доступных mql4-программам
   start(bars,
         CountedMQL4,
         MainBuffer,
         SignalBuffer,
         HighesBuffer,
         LowesBuffer,
         Kperiod,
         Dperiod,
         Slowing);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+--------------------+------------------+
//|              MQL4  | MQL5             |
//+--------------------+------------------+
//|IndicatorCounted()  | prev_calculated  |
//|              Bars  | rates_total      |
//|              iMA(  | iMAMql4(         |
//|       iMAOnArray(  | iMAOnArrayMql4(  |
//+--------------------+------------------+ 
int start(int rates_total,
          int prev_calculated,
          double &MainBuffer[],
          double &SignalBuffer[],
          double &HighesBuffer[],
          double &LowesBuffer[],
          int KPeriod,
          int DPeriod,
          int Slowing)
  {
   int draw_begin1=KPeriod+Slowing;
   int draw_begin2=draw_begin1+DPeriod;
   int    i,k;
   int    counted_bars=prev_calculated;
   double price;
//----
   if(rates_total<=draw_begin2) return(0);
//---- initial zero
   if(counted_bars<1)
     {
      for(i=1;i<=draw_begin1;i++) MainBuffer[rates_total-i]=0;
      for(i=1;i<=draw_begin2;i++) SignalBuffer[rates_total-i]=0;
     }
//---- minimums counting
   i=rates_total-KPeriod;
   if(counted_bars>KPeriod) i=rates_total-counted_bars-1;
   while(i>=0)
     {
      double min=1000000;
      k=i+KPeriod-1;
      while(k>=i)
        {
         price=Low[k];
         if(min>price) min=price;
         k--;
        }
      LowesBuffer[i]=min;
      i--;
     }
//---- maximums counting
   i=rates_total-KPeriod;
   if(counted_bars>KPeriod) i=rates_total-counted_bars-1;
   while(i>=0)
     {
      double max=-1000000;
      k=i+KPeriod-1;
      while(k>=i)
        {
         price=High[k];
         if(max<price) max=price;
         k--;
        }
      HighesBuffer[i]=max;
      i--;
     }
//---- %K line
   i=rates_total-draw_begin1;
   if(counted_bars>draw_begin1) i=rates_total-counted_bars-1;
   while(i>=0)
     {
      double sumlow=0.0;
      double sumhigh=0.0;
      for(k=(i+Slowing-1);k>=i;k--)
        {
         sumlow+=Close[k]-LowesBuffer[k];
         sumhigh+=HighesBuffer[k]-LowesBuffer[k];
        }
      if(sumhigh==0.0) MainBuffer[i]=100.0;
      else MainBuffer[i]=sumlow/sumhigh*100;
      i--;
     }
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   int limit=rates_total-counted_bars;
//---- signal line is simple moving average
   for(i=0; i<limit; i++)
      SignalBuffer[i]=iMAOnArrayMql4(MainBuffer,rates_total,DPeriod,0,MODE_SMA,i);
//----
   return(0);
  }
//+------------------------------------------------------------------+

그 결과로 MQL5에서 MQL4 매매가 구조를 가진 완전 Stochastic을 얻을 수 있습니다.

결과물 작동은 6번 그림에 나타나 있습니다:

MQL4에서 다시 작성된 인디케이터 Stochastic과 MQL5 표준 Stochastic의 비교

6번 그림. MQL4에서 리팩토링된 인디케이터 Stochastic과 표준 MQL5 Stochastic.

5. RSI 인디케이터 전환 예시

인디케이터에 대한 정보를 모읍니다:
//---- input parameters
extern int RSIPeriod=14;
//---- buffers
double RSIBuffer[];
double PosBuffer[];
double NegBuffer[];

MetaEditor 5에 해당되는 템플릿을 만듭니다 (그림 7-8).

RSI 인디케이터의 입력 패러미터

7번 그림. RSI 인디케이터의 입력 패러미터

RSI 인디케이터의 버퍼들

8번 그림. RSI 인디케이터의 버퍼들

총 버퍼 수는 3 입니다:

#property indicator_buffers 3

그림 그리기용 버퍼의 숫자는 1입니다:

#property indicator_plots   1

계산을 위한 버퍼들의 상태를 설정합니다:

   SetIndexBuffer(1,PosBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,NegBuffer,INDICATOR_CALCULATIONS)

파트들을 재배치하고 필요한 수정을 합니다:

//+------------------------------------------------------------------+
//|                                                     RSI_MQL4.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   1
//--- plot RSIBuffer
#property indicator_label1  "RSIBuffer"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Green
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot PosBuffer
#property indicator_label2  "PosBuffer"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- plot NegBuffer
#property indicator_label3  "NegBuffer"
#property indicator_type3   DRAW_LINE
#property indicator_color3  Red
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1

#include <mql4_2_mql5.mqh>
//--- input parameters
input int      RSIPeriod=14;
//--- indicator buffers
double         RSIBuffer[];
double         PosBuffer[];
double         NegBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,RSIBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,PosBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,NegBuffer,INDICATOR_CALCULATIONS);
//---
   InitMql4(3);

   ArraySetAsSeries(RSIBuffer,true);
   ArraySetAsSeries(PosBuffer,true);
   ArraySetAsSeries(NegBuffer,true);

   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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 bars=MQL4Run(rates_total,prev_calculated);
// bars - number of bars available for MQL4 programs
   RSImql4(bars,
           CountedMQL4,
           RSIBuffer,
           PosBuffer,
           NegBuffer,
           RSIPeriod);
   return(rates_total);
  }
//+--------------------+------------------+
//|              MQL4  | MQL5             |
//+--------------------+------------------+
//|IndicatorCounted()  | prev_calculated  |
//|              Bars  | rates_total      |
//|              iMA(  | iMAMql4(         |
//|       iMAOnArray(  | iMAOnArrayMql4(  |
//+--------------------+------------------+ 
int RSImql4(int rates_total,
            int prev_calculated,
            double &RSIBuffer[],
            double &PosBuffer[],
            double &NegBuffer[],
            int RSIPeriod)
  {
   int    i,counted_bars=prev_calculated;
   double rel,negative,positive;
//----fd
   if(rates_total<=RSIPeriod) return(0);
//---- initial zero
   if(counted_bars<1)
      for(i=1;i<=RSIPeriod;i++) RSIBuffer[rates_total-i]=0.0;
//----
   i=rates_total-RSIPeriod-1;
   if(counted_bars>=RSIPeriod) i=rates_total-counted_bars-1;
   while(i>=0)
     {
      double sumn=0.0,sump=0.0;
      if(i==rates_total-RSIPeriod-1)
        {
         int k=rates_total-2;
         //---- initial accumulation
         while(k>=i)
           {
            rel=Close[k]-Close[k+1];
            if(rel>0) sump+=rel;
            else      sumn-=rel;
            k--;
           }
         positive=sump/RSIPeriod;
         negative=sumn/RSIPeriod;
        }
      else
        {
         //---- smoothed moving average
         rel=Close[i]-Close[i+1];
         if(rel>0) sump=rel;
         else      sumn=-rel;
         positive=(PosBuffer[i+1]*(RSIPeriod-1)+sump)/RSIPeriod;
         negative=(NegBuffer[i+1]*(RSIPeriod-1)+sumn)/RSIPeriod;
        }
      PosBuffer[i]=positive;
      NegBuffer[i]=negative;
      if(negative==0.0) RSIBuffer[i]=0.0;
      else RSIBuffer[i]=100.0-100.0/(1+positive/negative);
      i--;
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+

여기서는 이전 인디케이터와 달리 MQL4의 일반적인 int Start() 함수 대신 now 로 이름을 변경했습니다.

int start()
  {

이걸 씁니다

int RSImql4(

MQL5에서는. 함수 자체의 이름과 MQL5 프로그램에서 호출된 라인이 모두 변경됩니다.

라이브러리 작업의 결과물은 9번 그림에 나타나 있습니다.

MQL4에서 리팩토링된 RSIc 인디케이터와 MQL5 표준 RSI 인디케이터의 비교.

9번 그림. MQL4에서 리팩토링된 RSIc 인디케이터와 MQL5 표준 RSI 인디케이터의 비교.

6. 설치

이 모듈을 설치하려면 mql4_2_mql5.mqh파일을 MQL5\Include\ folder 로 복사하십시오.

테스트파일은 MQL5\Indicators 폴더에 놓여야합니다.

7. 개선

원하는 경우 MQL4에서 MQL5로 이전하기 문서에서 라이브러리를 연결하여 모듈의 기능을 확장할 수 있습니다. MQL5\Include 폴더에 InitMQL4.mqh 파일을 추가하고 입력 패러미터 앞에 이하의 코드를 넣으십시오:

#include <InitMQL4.mqh>

MQL4에서 MQL5로 이전하기 문서에서 필수적인 변경 사항 목록에 대해 알아볼 수 있습니다.

마치며

생성된 단순 매매가를 mql4_2_mql5.mqh 특수 라이브러리를 이용하여 MQL4에서 MQL5로 전환 시키는 알고리즘을 이 문서에서 알아보았습니다.

디버깅하는 동안 약간의 문제가 발생할 수 있지만 MQL4에 익숙한 사용자에게는 그다지 문제가 되지 않을 것입니다.

MQL5 환경에서 데이터에 액세스하는 특성을 고려할 때 인디케이터들을 다시 계산하는데에는 다소 시간이 걸릴 수 있습니다. MQL4 환경에서 프로그램에 필요한 데이터를 생성하고 재계산해야 하기 때문입니다. 인디케이터가 MQL5 환경으로 완전히 전송되려면 MQL5의 데이터 저장 및 액세스 특성을 고려하여 인디케이터를 다시 작성해야 합니다.

추신

"MQL5 환경에서 데이터에 액세스할 때의 특성을 고려할 때 지표를 재계산하는 데 다소 시간이 걸릴 수 있습니다. 그 이유는 MQL4 환경에서 프로그램에 필요한 데이터를 생성하고 다시 계산해야 하기 때문입니다." "라는 말에 주의를 기울여주셨으면 합니다. 때로는 이러한 대기 시간이 몇 초 동안 지속될 수 있습니다(그림 10-11 참조):

  

10번 그림. 데이터 계산되지않음                                                                                                  11번 그림. 데이터 사용가능

클라이언트 터미널의 기능에 연결되며, 인디케이터 핸들 생성 시 터미널 캐시에 계산 파트의 복사본이 딱 하나만 생성됩니다. 만약 그런 인디케이터(같은 입력 패러미터를 가진)가 아직(yet()) 생성되지 않았다면, 

iMA(Symb,TimFram,iMAPeriod,ma_shift,ma_method,applied_price);

함수를 호출하면 이동평균 인디케이터를 생성합니다. 딱 한 번만.

다음 번에는 기존 인디케이터를 생성하려고 하면 터미널에서 핸들을 반환하기만 하면 됩니다.

따라서 인디케이터 계산은 핸들 생성 직후가 아니라 한 번만 수행됩니다.

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

파일 첨부됨 |
mql4_2_mql5.mqh (16.45 KB)
macd_mql4.mq5 (4.07 KB)
rsi_mql4.mq5 (4.77 KB)
시장 분석을 위한 데이터베이스의 실용적 활용 시장 분석을 위한 데이터베이스의 실용적 활용
데이터를 다루는 것이야말로 스탠드얼론이나 네트워크 앱을 가리지 않고, 오늘날 개발되는 소프트웨어들의 주 임무가 되었습니다. 이런 문제를 해결하기위해 특화된 소프트웨어가 탄생했습니다. 이들은 데이터베이스 매니지먼트 시스템(Database Management Systems, DBMS)이라고 불리며, 컴퓨터 저장 및 처리를 위해 구조화, 시스템화, 자료 정리가 가능합니다. 거래와 관련해서는 대부분의 분석가들이 업무에서 데이터베이스를 사용하지 않습니다. 그러나 이러한 솔루션을 쓰는 편이 편리한 작업도 있습니다. 이 문서에서는 클라이언트-서버 및 파일-서버 아키텍처 모두에서 데이터베이스에서 데이터를 저장하고 로드할 수 있는 인디케이터의 일례를 보여드리겠습니다.
MQL5으로 "스네이크" 게임 만들기 MQL5으로 "스네이크" 게임 만들기
본 문서에서는 "스네이크" 게임을 만드는 법에 대해서 설명하겠습니다. MQL5에서 게임 프로그래밍은 이벤트 핸들러 기능 덕분에 가능하게 되었다고 볼 수 있습니다. 객체 지향 프로그래밍이기에 이 프로세스가 크게 간소화됩니다. 이 문서에서는 이벤트 처리 기능, 표준 MQL5 라이브러리 클래스의 사용 예, 정기적 함수 호출에 대하여 살펴보겠습니다.
MetaTrader 5: 이메일을 통해 거래 전망과 실시간 거래 명세서를 블로그, SNS, 지정된 웹사이트에 게시하기 MetaTrader 5: 이메일을 통해 거래 전망과 실시간 거래 명세서를 블로그, SNS, 지정된 웹사이트에 게시하기
이 문서는 MetaTrader 5를 통해 시장 예상을 게시할 수 있게 해주는 레디메이드 솔루션을 다룰 것입니다. MetaTrader 명세서를 게시하기 위해 전용 웹 사이트를 사용하는 것에서부터 웹 프로그래밍 경험이 거의 필요 없는 자체 웹 사이트를 구축하는 것, 그리고 마지막으로 많은 독자들이 예측에 참여하고 따를 수 있는 소셜 네트워크 마이크로블로깅 서비스와의 통합에 이르기까지 다양한 아이디어를 다루고 있습니다. 이 문서에서 다룰 솔루션들은 100% 무료이며, 이메일이나 ftp 서비스에 대한 기초적인 지식이 있는 독자라면 누구건 따라할 수 있습니다. 전문 호스팅 및 상업 거래 예측 서비스에 동일한 기술을 사용하는 데도 어렵지 않습니다.
MQL5에서 ICQ 와 Expert Advisor 사이의 연결 MQL5에서 ICQ 와 Expert Advisor 사이의 연결
본 문서는 Expert Advisor와 ICQ 사용자 간의 정보 교환 방법을 설명하고 있으며, 몇 가지 예가 제시되어 있습니다. 고객 단말기에서 원격으로 ICQ 클라이언트를 통해 휴대폰이나 PDA로 거래 정보를 제공받으려는 분들에게 흥미로운 자료가 될 것입니다.