English Русский 中文 Español Deutsch Português 한국어 Français Italiano Türkçe
MQL4からMQL5へのインディケータ変換

MQL4からMQL5へのインディケータ変換

MetaTrader 5 | 6 10月 2015, 10:29
9 363 0
Vasily
Vasily

はじめに

読者のみなさん、こんにちは!

本稿では、シンプルな価格計算をMQL4からMQL5に変換するアルゴリズムをご紹介しようと思います。MQL5とMQL4の違いを知り、mql4_2_mql5.mqh関数ライブラリを追加しました。本稿を読み終わったら、その使い方を理解していることでしょう。


1. 変換に必要なインディケータの準備

本稿は変換インディケータの計算に特化しています。インディケータが描画エレメントや複雑な価格計算を含んでいるなら問題に遭遇することでしょう。

まず、変換のためのMQL4コードの準備が必要です。そのために何が必要か見てみます。

たとえば MACD、必要なインディケータを用いてMetaEditor 4を開きます。 そして、その入力パラメータの変更を始めます。

//---- 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のメニューの『新規』アイテムを選択し、その後『カスタムインディケータ』を選択します。

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の変数名に対応しているので、以下の変更を変換された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()について以下のように言います。

注意

timeseriesのインデックスが前もってバウンド配列にインストールされていても、バインディング後、動的配列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から書き直されたMACDインディケータとMQL5の標準インディケータの比較

図3 MQL4から書き直されたMACDインディケータとMQL5の標準インディケータの比較


4. ストキャスティック インディケータ変換例

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価格ストラクチャの完成したストキャスティックを取得しました。

作業結果は図6に示されています。

MQL4から書き直したインディケータ ストキャスティックとMQL5内標準ストキャスティックの比較

図6 MQL4から書き直したインディケータストキャスティック とMQL5内の標準ストキャスティックの比較


5. RSIインディケータ変換例

われわれのインディケータについての情報を収集します。

//---- input parameters
extern int RSIPeriod=14;
//---- buffers
double RSIBuffer[];
double PosBuffer[];
double NegBuffer[];

MetaEditor 5でそれのテンプレートを作成します。(図7~8)

MACDインディケータの入力パラメータ

図7 MACDインディケータの入力パラメータ

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()関数の代わりにここでは名前を変更しました。

int start()
  {

使うのはMQL5の

int RSImql4(

です。関数自体の名前とその関数がMQL5プログラムで呼び出される行の両方を変更します。

ライブラリの作業結果は図9に示されています。

MQL4から書き直されたRSIcインディケータとMQL5のRSIインディケータの比較

図9 MQL4から書き直されたRSIcインディケータとMQL5のRSIインディケータの比較


6. 設定

このモジュールを設定するには、mql4_2_mql5.mqhファイルをMQL5\Include\ フォルダにコピーする必要があります。

結果はMQL5\Indicators フォルダに置かれます。


7. 改善

ご希望ならMQL4のミグレーションからのライブラリを MQL5項に連携することでモジュールの機能性を拡張することが可能です。InitMQL4.mqhファイルをMQL5\Include フォルダと入力パラメータの前に以下の行に追加します。

#include <InitMQL4.mqh>

MQL4からMQL5への移植記事により必要な変更事項のリストを知ることができます。


おわりに

特殊なmql4_2_mql5.mqhライブラリを使用しシンプルな 価格コンストラクションをMQL4からMQL5に変換するアルゴリズムは本稿内で表記しています。

デバッグ中に多少の問題に出くわすことがあるかもしれませんが、MQL4になじみのある方にとっては、たいした問題ではないでしょう。

MQL5環境でのデータアクセスの特殊性を考えると、インディケータの再計算には多少時間を要するかもしれません。 その理由はMQL4環境からのデータのために必要なデータを作成し再計算する必要があるからです。MQL5環境にインディケータを全面的に変換するには、 MQL5でデータを保管し、アクセスする特殊性を考慮して書き直しをしなければならないのです。


追伸

「MQL5環境でのデータアクセスの特殊性を考えると、インディケータの再計算には多少時間を要するかもしれません。その理由はMQL4環境からのデータのために必要なデータを作成し再計算する必要があるからです。」という一文に注意を払っていただきたいと思います。この待ち時間には数秒かかることがあります。(図10~11参照)

図10 データは計算されていません。 図11データは使用可能です。

それはクライアント端末の機能に接続されています。計算部分の1件のコピーだけがインディケータハンドル作成時に端末のキャッシュに作成されます。そのようなインディケータ(同じ入力パラメータを伴います)はまだ作成されていません。()

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

関数の呼び出しは移動平均指数を作成しますが、一度限りです。

次回、既存のインディケータ作成を試みる際、端末はハンドルのみを返します。

そのため、インディケータの計算は一度だけ行われ、それはハンドル作成の直後ではありません。

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: 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)
市場分析のための実践的なデーターベースの活用 市場分析のための実践的なデーターベースの活用
データを扱うことは、現代のソフトウェアのメインの業務となっています。これは、スタンドアロン系、ネットワーク系のアプリ双方において言えることです。この問題を解決するために、特別なソフトウェアが開発されました。それは、データベース管理システム(DBMS)です。コンピューター内ストレージや、その処理においてデータを整理し、構築します。トレーディングにおいて、多くの分析はデータベースを使用しません。しかし、ソリューションがより便利になる必要のある業務があります。この記事では、クライアントサーバー、ファイルサーバー構造の両方において、データベースからデータをロードし、保存できるインジケーターの例を紹介します。
MQL5での「スネーク」ゲームの作成 MQL5での「スネーク」ゲームの作成
本稿では『スネーク』ゲームのプログラム例を述べていきます。MQL5では、主にイベントハンドル機能によりゲームのプログラムが可能となりました。オブジェクト指向プログラミングによりこのプロセスが格段に簡素化されます。本稿では、イベント処理機能 標準的な MQL5 ライブラリクラスの使用例、また定期的関数呼び出しの詳細を学習します。
例で紹介するMQL5のOOP:警告処理とエラーコード 例で紹介するMQL5のOOP:警告処理とエラーコード
この記事は、MQLプログラム稼働中に発生するすべてのエラーや、トレードサーバーを扱うクラスを作成する例を紹介しています。記事を読めば、MQL5のオブジェクトやクラスを使用する方法を学ぶことができます。同時に、これはエラーをハンドリングする便利なツールでもあり、さらに、あなたの個別な要求に応じてツールのカスタマイズが可能です。
利益のある取引戦略を見つける方法 利益のある取引戦略を見つける方法
この記事では、『ニューラルネットワークを利用しつつ、履歴データ上でコンピュータを使って取引戦略を作り上げることは可能か?』という問いについての答えを与えます。