English Русский 中文 Español Deutsch Português
インディケータコードから Expert Advisor コードへの変換Expert Advisor およびインディケータ関数の一般的スキーム

インディケータコードから Expert Advisor コードへの変換Expert Advisor およびインディケータ関数の一般的スキーム

MetaTrader 4 | 17 2月 2016, 14:58
640 0
Nikolay Kositsin
Nikolay Kositsin

はじめに

前稿(Transferring an Indicator Code into an Expert Advisor Code. Indicator Structure) では、インディケータの一般的ストラクチャ、Expert Advisor コードに変換するコードを分析し、インディケータコードの事前調整の主要な考えを記述しました。ここでは取得したコードをカスタム関数に変換してみます。というのもこれはおそらくExpert Advisor でインディケータコードを 表現するのにもっとも便利な方法だからです。カスタム関数は mqh-file として示され、命令を用いて Expert Advisor 内でそれを宣言するのに場所はほとんどいりません。またこの関数の呼び出しはカスタムインディケータの呼び出しほどむつかしくありません。より重要なのは、そのようなカスタム関数はあらゆる Expert Advisors でさらに使用するにあたりどんな状況にも対応することが可能であることです。

その関数を書く前に、内部構造にかかわりなく、この関数がの他 Expert Advisor の部分とどのように連携するか分析します。

カスタムインディケータ呼び出しを伴う EA のストラクチャ

まずカスタムインディケータからデータを受信する EA のストラクチャの概要を調べます。この EA では、最初にカスタムインディケータからデータを受信する部分のみ注目します。今までのところ、EA による受信したデータの処理方法、それのシグナルへの変換、EA の実行箇所のストラクチャについては述べません。この EA のカスタムインディケータを前稿で述べたものとして分析します。以下は Expert Advisor のストラクチャ例です。


//+------------------------------------------------------------------+
//|                                               ExpertIndPlan0.mqh |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
//---- EA input parameters
extern int period10 = 15;
extern int period11 = 15;
extern int period12 = 15;
//---- EA input parameters
extern int period20 = 15;
extern int period21 = 15;
extern int period22 = 15;
//---- Declaring buffers for indicator values
double Ind_Buffer1[6];
double Ind_Buffer2[6];
//+------------------------------------------------------------------+
//| Custom Expert initialization function                            |
//+------------------------------------------------------------------+
int init()
  {
// Here is the code of EA initialization
//---- initialization end
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom Expert iteration function                                 |
//+------------------------------------------------------------------+
int start()
  {
//---- Checking whether the bars number is enough for further calculation
   if(iBars(Symbol(), 0) < period10 + period11 + period12 + 10)
       return(0);
   if(iBars(Symbol(), 0) < period20 + period21 + period22 + 10)
       return(0);
//---- getting indicator values for further calculation
   for(int bar = 5; bar >= 1; bar--)
     {
       Ind_Buffer1[bar] = iCustom("IndicatorPlan", Symbol(), 0, period10, 
                                  period11, period12, 0, bar);
       Ind_Buffer2[bar] = iCustom("IndicatorPlan", Symbol(), 0, period20, 
                                  period21, period22, 0, bar);
     }
// Here is the EA code, forming trade signals 
// based on the values of indicator buffer cells 
//----
// here is the EA executive part code, 
// requesting for placing an order 
//----
   return(0);
  }
//+------------------------------------------------------------------+

このスキームでは、各ティックでカスタムインディケータ IndicatorPlan mq4 の2回の呼び出しのカウント値のゼロバッファを取り、それを共通配列 Ind_Buffer1[] および Ind_Buffer2[] に入れます。インディケータ呼び出しのスキームはさらなる計算のために、ゼロ値以外、最後の5個のインディケータ値が必要になることを考慮します。

カスタムインディケータ呼び出しを伴う EA のストラクチャ
あらゆる Expert Advisor に適したユニバーサルなインディケータ関数を作成しているとき、それは受信値をインディケータバッファの類似体に送信します。それはチャートのバーすべてに対してインディケータ値を格納するのです。まちろん、その呼び出しが完全にカスタムインディケータ呼び出しの類似体であるインディケータ関数を作成することはできますが、書くのには時間がかかりすぎ、コードはひじょうに長いものとなってしまうことでしょう。

もっと簡単にする方法があるのです。この関数は入力パラメータをカスタムインディケータやバッファのパラメータとして受け取り、セルが計算済みのインディケータ値を書き込まれたインディケータモードのエミュレーションを持つ同じバッファとして返します。われわれの関数内にインディケータバッファに対応する関数に対する参照にリンクした外部変数を宣言することで簡単に行えます。MQL4 言語では、それは次のようなものです。:double& InputBuffer。インディケータ関数は論理関数として宣言します。計算が正常に行われれば『真』を返し、チャート上に適切なバー番号がないため計算が正常に行われなければ『偽』を返します。この説明の後、インディケータスキームから構築され、前稿でお話ししたインディケータ関数は以下のような形になるはずです。


bool Get_IndSeries(int Number,string symbol, int timeframe, 
                   bool NullBarRecount, int period0, int period1, 
                   int period2, double& InputBuffer0[],
                   double& InputBuffer1[], double& InputBuffer2[])

インディケータ関数はもうひとつ別の外部変数 Number を持ちます。これはこのインディケータ関数の呼び出し番号の値を受け入れる変数です。

インディケータバッファ以外、外部変数が中間計算用バッファ InputBuffer1 および InputBuffer2 も持つのは当然のことです。なぜなら関数内にこういったバッファを作成するのはひじょうに面倒だからです。関数内にこれらバッファ処理のインディケータモードをエミュレートするほうが好ましいです。それにより問題が発生することはありません。ここから外部変数 NullBarRecount の意味を詳しく説明します。実際、の大半はゼロバーでの計算を必要としません。そして、ユニバーサルなインディケータ関数を書いている間、それは当然のごとくゼロバーでインディケータ値の再計算を行います。それは実質上実行時間をに増やす可能性のあるものです。 関数 NullBarRecount の外部パラメータを『偽』と指摘することで、必要なければ関数がゼロバーで計算するのを禁止します。

ここで関数呼び出しを持つバリアントでインディケータ呼び出し用 EA ストラクチャのスキームを示すことができます。

//+------------------------------------------------------------------+
//|                                               ExpertIndPlan1.mqh |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
//---- EA input parameters
extern int period10 = 15;
extern int period11 = 15;
extern int period12 = 15;
//---- EA input parameters
extern int period20 = 15;
extern int period21 = 15;
extern int period22 = 15;
//---- Indicator buffers declaration
double Ind_Buffer10[], Ind_Buffer11[], Ind_Buffer12[];
double Ind_Buffer20[], Ind_Buffer21[], Ind_Buffer22[];
//+------------------------------------------------------------------+
//| Get_IndSeries() function                                         |
//+------------------------------------------------------------------+
//---- Declaration of the function Get_IndSeries()
bool Get_IndSeries(int Number,string symbol, int timeframe, 
                   bool NullBarRecount, int period0, int period1, 
                   int period2, double& InputBuffer0[],
                   double& InputBuffer1[], double& InputBuffer2[])
  {
    //---- 
    // Here is the code of the function GetIdicator()
    //----
    return(true);
  }
//+------------------------------------------------------------------+
//| Custom Expert initialization function                            |
//+------------------------------------------------------------------+
int init()
  {
//----
// Here is the code of the EA initialization
//---- initialization end
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom Expert iteration function                                 |
//+------------------------------------------------------------------+
int start()
  {
//---- Checking whether the bars number is enough for further calculation
   if(iBars(Symbol(), 0) < period10 + period11 + period12 + 10)
      return(0);
   if(iBars(Symbol(), 0) < period20 + period21 + period22 + 10)
      return(0);
//---- getting indicator values for further calculation
   if(!Get_IndSeries(0,Symbol(), 0, false, period10, period11, period12,
      Ind_Buffer10, Ind_Buffer11, Ind_Buffer12))
       return(0);
   if(!Get_IndSeries(1, Symbol(), 0, false, period20, period21, period22, 
      Ind_Buffer20, Ind_Buffer21,Ind_Buffer22))
       return(0);  
//----
// Here is the EA code, forming trade signals 
// based on the values of indicator buffer cells 
//----
// here is the EA executive part code, 
// requesting for placing an order
//----
 
   return(0);
  }
//+------------------------------------------------------------------+


インディケータコードをカスタム関数に変換する一般的スキーム

この初期作業後、インディケータ関数の内部ストラクチャの一般的スキームに移ることができます。前稿の最後のインディケータスキームを基本にします。むつかしいことはないはずです。

1. 関数 int start() の内容だけを取ります。
2. 関数 Get_IndSeries() の宣言を追加します。

bool Get_IndSeries(string symbol, int timeframe, bool NullBarRecount,
                   int period0, int period1, int period2, 
                   double& InputBuffer0, double& InputBuffer1, 
                   double& InputBuffer2)


3. 関数 Get_IndSeries() の外部変数のバッファ名(InputBuffer)に従いコード(Ind_Buffer)内のインディケータバッファ名を変更します。
4. 変数 LastCountBar の宣言を追加します。
5. 変数 NullBarRecount が真であることを確認します。

if(!NullBarRecount)
    LastCountBar = 1;

6. インディケータ計算の全サイクルでゼロを LastCountBar に変更します。
7. バー数がのちの計算に十分か確認する際、コードの一番最初に変更を加えます。: return(0) を return(false) に。
8. コードの最後で return(0) を return(true) に変更します。

インディケータ関数は準備できました。

//+------------------------------------------------------------------+
//|                                                Get_IndSeries.mqh |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net/ |
//+------------------------------------------------------------------+ 
bool Get_IndSeries(int Number, string symbol,int timeframe, 
                   bool NullBarRecount, int period0, int period1, 
                   int period2, double& InputBuffer0[], 
                   double& InputBuffer1[], double& InputBuffer2[])  
  {
//---- getting the number of all bars of a chart
   int IBARS = iBars(symbol, timeframe);
//---- Checking whether the bars number is enough for further calculation
   if(IBARS < period0 + period1 + period2)
      return(false);
//---- EMULATION OF INDICATOR BUFFERS
   if(ArraySize(InputBuffer0) < IBARS)
     {
       ArraySetAsSeries(InputBuffer0, false);
       ArraySetAsSeries(InputBuffer1, false);
       ArraySetAsSeries(InputBuffer2, false);
       //----  
       ArrayResize(InputBuffer0, IBARS); 
       ArrayResize(InputBuffer1, IBARS); 
       ArrayResize(InputBuffer2, IBARS); 
       //----
       ArraySetAsSeries(InputBuffer0, true);
       ArraySetAsSeries(InputBuffer1, true);
       ArraySetAsSeries(InputBuffer2, true); 
     } 
//----+ introducing static memory variables
   static int IndCounted[];
//----+ changing the size of static variables
   if(ArraySize(IndCounted) < Number + 1)
       ArrayResize(IndCounted, Number + 1); 
//----+ introducing an integer variable
   int LastCountBar;
//----+ Checking if the recalculation of the zero bar is allowed
   if(!NullBarRecount)
       LastCountBar = 1;
   else 
       LastCountBar = 0;
//----+ Inserting a variable with a floating point
   double Resalt0, Resalt1, Resalt2;
//----+ Inserting integer variables and getting already calculated bars
   int limit, MaxBar, bar, counted_bars = IndCounted[Number];
//----+ Remembering the number of all bars of a chart (we do not count the zero bar!)
   IndCounted[Number] = IBARS - 1;
//---- defining the number of the oldest bar, 
// starting from which new bars will be recalculated
   limit = IBARS - counted_bars - 1; 
//---- defining the number of the oldest bar, 
// starting from which new bars will be recalculated
   MaxBar = IBARS - 1 - (period0 + period1 + period2); 
//---- initialization of zero 
   if(limit > MaxBar)
     {
       limit = MaxBar;
       for(bar = IBARS - 1; bar >= 0; bar--)
         {
           InputBuffer0[bar] = 0.0;
           InputBuffer1[bar] = 0.0;
           InputBuffer2[bar] = 0.0;
         }
     }
//----+ THE FIRST CYCLE OF INDICATOR CALCULATION 
   for(bar = limit; bar >= LastCountBar; bar--)
     {
       // Here code of the variable Resalt1 calculation  
       // based on the external variable period1
       InputBuffer1[bar] = Resalt1;
     }
//----+ THE SECOND CYCLE OF INDICATOR CALCULATION 
   for(bar = limit; bar >= LastCountBar; bar--)
     {
       // Here code of the variable Resalt2 calculation 
       // based on the values of the buffer Ind_Buffer1[] 
       // and external variable period2
       InputBuffer2[bar] = Resalt2;
     }
//----+ THE MAIN CYCLE OF INDICATOR CALCULATION 
   for(bar = limit; bar >= LastCountBar; bar--)
     {
       // Here code of the variable Resalt0 calculation 
       // based on the values of the buffer Ind_Buffer2[] 
       // and external variable period0
       InputBuffer0[bar] = Resalt0;
     }
   return(true);
  }
//+------------------------------------------------------------------+

読者のみなさんが MQL4 をひじょうにうまくご利用なら、上述のアクションを読んだあと、与えられたスキームに従ってインディケータ関数を書くのになんの問題もないだろうと思います。

カスタムインディケータ関数を書く例
ここからインディケータ関数を書きます。最大限シンプルなインディケータを取ります。

//+------------------------------------------------------------------+
//|                                                         RAVI.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
//---- drawing the indicator in a separate window
#property indicator_separate_window 
//---- number of indicator buffers
#property indicator_buffers 1 
//---- indicator color
#property indicator_color1 Red 
//---- INPUT PARAMETERS OF THE INDICATOR 
extern int Period1 = 7; 
extern int Period2 = 65; 
extern int MA_Metod = 0;
extern int PRICE = 0;
//---- indicator buffers
double ExtBuffer[]; 
//+------------------------------------------------------------------+ 
//| RAVI initialization function                                     | 
//+------------------------------------------------------------------+ 
int init() 
  { 
//---- indicator drawing style
   SetIndexStyle(0, DRAW_LINE); 
//---- indicator buffers 
   SetIndexBuffer(0,ExtBuffer); 
//---- indicator name and labels for subwindows 
   IndicatorShortName("RAVI (" + Period1+ ", " + Period2 + ")"); 
   SetIndexLabel(0, "RAVI"); 
//---- initialization end
   return(0); 
  } 
//+------------------------------------------------------------------+ 
//| RAVI iteration function                                          | 
//+------------------------------------------------------------------+ 
int start() 
  {
   int MinBars = MathMax(Period1, Period2); 
//---- checking whether the bars number is enough for further calculation
   if(Bars < MinBars)
       return(0);
//----+ Introducing variables with a floating point 
   double MA1, MA2, result; 
//----+ Introducing integer variables and getting already calculated bars
   int MaxBar, bar, limit, counted_bars = IndicatorCounted();
//---- checking for possible errors
   if(counted_bars < 0)
       return(-1);
//---- the last calculated bar should be recalculated 
   if(counted_bars > 0)
       counted_bars--;
//---- defining the number of the oldest bar, 
// starting from which all bars will be recalculated 
   MaxBar = Bars - 1 - MinBars;
//---- defining the number of the oldest bar, 
// starting from which new bars will be recalculated 
   limit = Bars - counted_bars - 1; 
//---- zero initialization
   if(limit > MaxBar)
     {
       for(int ii = Bars - 1; ii >= MaxBar; ii--)
           ExtBuffer[ii] = 0.0;
       limit = MaxBar;
     }
//---- main cycle 
   for(bar = 0; bar <= limit; bar++) 
     { 
       MA1 = iMA(NULL, 0, Period1, 0, MA_Metod, PRICE,bar); 
       MA2 = iMA(NULL, 0, Period2, 0, MA_Metod, PRICE,bar); 
       //---- 
       result = ((MA1 - MA2) / MA2)*100; 
       ExtBuffer[bar] = result; 
     }  
//---- 
   return(0); 
  } 
//+------------------------------------------------------------------+



アルゴリズムの固定

1. インディケータコードにある不要なエレメントをすべて消去します。
2. シングルバッファ ExtBuffer[] 用インディケータバッファのエミュレーションコードを書きます。
3. 関数 IndicatorCounted() を変数 IndCounted に置き換えます。
4. 変数 IndCounted をチャートバー数-1で初期化します。
5. 事前決定された変数 Bars を時系列呼び出しiBars(シンボル、タイムフレーム)に変更します。
6. counted_bars に対する不要な確認を削除します。

//---- checking possible errors
if(counted_bars < 0)
    return(-1);
//---- the last calculated bar must be recalculated 
if(counted_bars > 0) 
    counted_bars--;

7. 関数 int start() のコンテンツのみ残します。


8. 関数 Get_RAVISeries() の宣言を追加します。

bool Get_RAVISeries(int Number, string symbol,int timeframe, 
                    bool NullBarRecount, int Period1, 
                    int Period2, int MA_Metod, int  PRICE, 
                    double& InputBuffer[])

9. コード内のインディケータバッファ名(ExtBuffer)を関数Substitute Get_RAVISeries() の外部変数のバッファ名(InputBuffer)に従い置き換えます。


10. 変数 LastCountBar の宣言を追加します。
11. 静的変数 IndCounted を配列 IndCounted[Number] に変え、関数 Get_RAVISeries の呼び出し数に応じて変数サイズを変更するためのコードを追加します。mqh:

//----+ changing the size of static variables
   if(ArraySize(IndCounted) < Number + 1)
     {
       ArrayResize(IndCounted, Number + 1); 
     }

12. 変数 NullBarRecount が真であることを確認します。

if(!NullBarRecount)
    LastCountBar = 1;

13. インディケータ計算のすべてのサイクルでゼロを LastCountBar に変更します。


for(bar = limit; bar >= LastCountBar; bar--)

14. バー数が十分か確認する際、コードの冒頭に変更を加えます。: return(0) を return(false) に。


15. 末尾で return(0) を return(true) に置き換えます。


すべてのコードを変更したら、インディケータ関数 Get_RAVISeries() を取得します

//+------------------------------------------------------------------+
//|                                               Get_RAVISeries.mqh |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
bool Get_RAVISeries(int Number, string symbol,int timeframe, 
                    bool NullBarRecount, int Period1, int Period2, 
                    int MA_Metod, int  PRICE, double& InputBuffer[])    
  {
//---- getting the number of all bars of a chart
   int IBARS = iBars(symbol, timeframe);  
//---- Checking whether the bars number is enough for further calculation
   if(IBARS < MathMax(Period1, Period2))
       return(false);
//---- EMULATION OF INDICATOR BUFFERS
   if(ArraySize(InputBuffer) < IBARS)
     {
       ArraySetAsSeries(InputBuffer, false);
       //----  
       ArrayResize(InputBuffer, IBARS); 
       //----
       ArraySetAsSeries(InputBuffer, true);
     } 
//----+  inserting static variables of memory
   static int IndCounted[]; 
//----+ changing the size of static variables
   if(ArraySize(IndCounted) < Number + 1)
     {
       ArrayResize(IndCounted, Number + 1); 
     }
 //----+ Introducing an integer variable
   int LastCountBar;
//----+ Checking whether the recalculation of the zero bar is allowed
   if(!NullBarRecount)
       LastCountBar = 1;
//----+ Introducing floating point variables 
   double MA1,MA2,result; 
//----+ Introducing integer variables and getting alreadu calculated bars
   int MaxBar, bar, limit, counted_bars = IndCounted[Number];
//----+ Remembering the amount of all chart bars
   IndCounted[Number] = IBARS - 1;
//---- determining the number of the oldest bar, 
// starting from which new bars will be recalculated
   limit = IBARS - counted_bars - 1; 
   // Print(IBARS - counted_bars); 
//---- determining the number of the oldest bar, 
// starting from which all bars will be recalculated
   MaxBar = IBARS - 1 - MathMax(Period1, Period2); 
//---- zero initialization 
   if(limit > MaxBar)
     {
       limit = MaxBar;
       for(bar = IBARS - 1; bar >= 0; bar--)
         {
           InputBuffer[bar] = 0.0;
         }
     } 
//----+ THE FIRST CYCLE OF INDICATOR CALCULATION 
   for(bar = limit; bar >= LastCountBar; bar--)
     { 
       MA1 = iMA(symbol, timeframe, Period1, 0, MA_Metod, PRICE, bar); 
       MA2 = iMA(symbol, timeframe, Period2, 0, MA_Metod, PRICE, bar); 
       //---- 
       result = ((MA1 - MA2) / MA2)*100; 
       InputBuffer[bar] = result; 
     } 
//----+  
   return(true);
  }
//+------------------------------------------------------------------+


確かにこれはすべてすばらしくできています。Competently, シンプルすぎることはありません。ただ、疑問が一つ浮かびます。このインディケータ関数はカスタムインディケータと同じように計算するのだろうか?

計算精度についてのカスタムインディケータ関数検証
関数計算結果がカスタムインディケータ関数の計算結果に等しいか確認する必要があります。このために最適な Expert Advisor はトレードを行わず、カスタムインディケータ RAVI.mq4 およびカスタム関数 Get_RAVISeries() から値を受け取り、差を見つけ、その後インディエータ値、カスタム関数値、両者の差分をログファイルに送信するだけのものです。必要なことは、カスタム関数 Get_RAVISeries() およびインディケータ RAVI.mq4 のアルゴリズムの対応に関する最終結論を出すためのログファイルの内容を分析することだけです。

//+------------------------------------------------------------------+
//|                                           Get_RAVISeriesTest.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
//---- INPUT EA PARAMETERS
extern bool NullBarRecount = true;
//---- indicator buffers
double RAVI_Buffer0[];
double RAVI_Buffer1[];
double RAVI_Buffer2[];
//+------------------------------------------------------------------+
//| Get_RAVISeries() function                                        |
//+------------------------------------------------------------------+
#include <Get_RAVISeries.mqh>
//+------------------------------------------------------------------+
//| Custom Expert initialization function                            |
//+------------------------------------------------------------------+
int init()
  {
//---- initialization end
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom Expert iteration function                                 |
//+------------------------------------------------------------------+
int start()
  {
//---- 
   double Ind_Velue, Resalt;
//---- 
   if(!Get_RAVISeries(0, Symbol(), 0, NullBarRecount, 10, 20, 1, 0,
      RAVI_Buffer0))
       return(0);  
   if(!Get_RAVISeries(1, Symbol(), 240, NullBarRecount, 25, 66, 2, 1,
      RAVI_Buffer1))
       return(0);
   if(!Get_RAVISeries(2, Symbol(), 1440, NullBarRecount, 30, 70, 3, 3,
      RAVI_Buffer2))
       return(0);
//---- getting indicator values for the test 0
   Ind_Velue = iCustom(NULL, 0, "RAVI", 10, 20, 1, 0, 0, 2); 
   Resalt = RAVI_Buffer0[2] - Ind_Velue; 
   Print("  " + Ind_Velue + "    " + RAVI_Buffer0[2] + "    " + Resalt+"");
//---- getting indicator values for the test 1
   Ind_Velue = iCustom(NULL, 240, "RAVI", 25, 66, 2, 1, 0, 2);
   Resalt = RAVI_Buffer1[2] - Ind_Velue; 
   Print("  " + Ind_Velue + "    " + RAVI_Buffer1[2] + "    " + Resalt+"" );
//---- getting indicator values for the test 2
   Ind_Velue = iCustom(NULL, 1440, "RAVI", 30, 70, 3, 3, 0, 2);
   Resalt = RAVI_Buffer2[2] - Ind_Velue; 
   Print("  " + Ind_Velue + "    " + RAVI_Buffer2[2] + "    " + Resalt + "");
//----
   return(0);
  }
//+------------------------------------------------------------------+

ストラテジーテスタで Expert Advisor の Get_RAVISeries 検証を起動します。当然、コンパイルされたファイル RAVI.ex4 はすでにMetaTrader クライアントターミナルのフォルダ \expert\indicators に、ファイル Get_RAVISeries.mqh はフォルダ \expert \include にあります。ストラテジーテスタのジャーナルおよびログファイルでは、インディケータ値と関数形式をしたその類似体の入った列を2列確認できます。3番目の列はこれらの値の差分が示されます。最後の列の値はすべてゼロです。それは値がどちらの場合にも等しいことを意味します。インディケータカスタム関数の書き込みタスクは正常に遂行された、と結論づけることができます。



おわりに

インディケータの類似体を、mqhファイルに入れられ、類似体がカスタムインディケータに対すると同様にどんな Expert Advisor のコードでも使用されるユニバーサルなインディケータ関数として作成することで、Expert Advisor コードに変換するタスクをなんとか遂行しました。

次の記事では、このテーマに限定し、この類の関数を書き、その関数を基にシンプルな Expert Advisor を実装するもっとむつかしい例を分析しようと思います、


MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/1457

添付されたファイル |
ExpertIndPlan0.mqh (2.27 KB)
ExpertIndPlan1.mqh (2.89 KB)
RAVI.mq4 (2.93 KB)
Expert Advisorのオーダーメード - トレーダー向けマニュアル Expert Advisorのオーダーメード - トレーダー向けマニュアル
トレーダーが全員プログラマーというわけではありません。そしてプログラマーが全員優秀というわけではありません。自分のシステムを自動化する必要がある場合、何をすべきでしょうか?MQL4 を学ぶのに時間も欲求もなしで?
インディケータコードから Expert Advisor コードへの変換インディケータストラクチャ インディケータコードから Expert Advisor コードへの変換インディケータストラクチャ
本稿はインディケータコードを Expert Advisor コードへ変換し、カスタムインディケータの呼び出しなく、Expert Advisor 内で必要なインディケータ値を計算するためのプログラムコード全体を使って Expert Advisor を書く方法に特化して述べます。本稿はインディケータストラクチャの一般的なスキーム、Expert Advisor におけるインディケータバッファの列挙、関数 IndicatorCounted() の置換を提供し述べます。対象とする読者はすでに MQL4 言語でのプログラム経験をお持ちの方です。
4 とおりのタイムフレームからの複数インディケータシグナルの同時表示 4 とおりのタイムフレームからの複数インディケータシグナルの同時表示
マニュアルトレーディングでは、複数インディケータの値から目を離すわけにはいきません。メカニカルトレーディングではそこは少しばかり異なります。2~3個のインディケータがあると、トレーディングにはタイムフレームを1つ選ぶ必要があり、それはむつかしい仕事ではありません。しかし5~6個ものインディケータがあり、トレーディング戦略が複数のタイムフレームについてのシグナルを考慮することを要求すればどうなるのでしょうか?
Forex トレーディングのイロハ Forex トレーディングのイロハ
金融市場を扱うということはまずトレード処理を意味します。ごく幼いころから、われわれは皆、何を売り、買うべきかということについて直観的考えを持っています。ですが Forex トレーディングは何か特別なものです。本稿ではいくつか用語の説明が必要な考えを取り上げます。またそういう語に対応する MQL 4 fの関数についても考察します。