English Русский 中文 Español Deutsch Português
カスタムインディケータ作成の特徴

カスタムインディケータ作成の特徴

MetaTrader 4 | 29 9月 2015, 15:48
10 595 0
MetaQuotes
MetaQuotes

MetaTrader取引システムでのカスタムインディケータの作成にはいくつかの特徴があります。

  • プログラムがカスタムインディケータとしてみなされる為には、以下の定義を利用しなければなりません。

    #property indicator_chart_window      // カスタムインディケータはチャートのメインウィンドウで表示される

    又は

    #property indicator_separate_window   // カスタムインディケータはサブウィンドウで表示される
  • インディケータの個別のウィンドウのスケールを固定する為には、以下のパラメータを利用します。

    #property indicator_minimum Min_Value
    #property indicator_maximum Max_Value

    Min_Value・Max_Valueは数値です。例えば、カスタムインディケータRSIにはこれらの数値は0と100になります。

  • カスタム指標の配列の数は以下の通りに定義します。

    #property indicator_buffers N

    ここでは、Nは1から8までの値

  • インディケータの線の色は以下によります。

    #property indicator_color1 Blue
    #property indicator_color2 Red
    ...
    #property indicator_colorN <SomeColor>

    ここではNは、#property indicator_bufferで定義された配列指標数です。

  • インディケータの可視化や計算の管理をすることができる、いくつかの関数があります。例として以下の一目均衡表を使いましょう。

    //+------------------------------------------------------------------+
    //|                                                     Ichimoku.mq4 |
    //|                      Copyright © 2004, MetaQuotes Software Corp. |
    //|                                       https://www.metaquotes.net/ |
    //+------------------------------------------------------------------+
    #property copyright "Copyright © 2004, MetaQuotes Software Corp."
    #property link      "https://www.metaquotes.net/"
     
    #property indicator_chart_window
    #property indicator_buffers 7
    #property indicator_color1 Red
    #property indicator_color2 Blue
    #property indicator_color3 SandyBrown
    #property indicator_color4 Thistle
    #property indicator_color5 Lime
    #property indicator_color6 SandyBrown
    #property indicator_color7 Thistle
    //---- input parameters
    extern int Tenkan=9;
    extern int Kijun=26;
    extern int Senkou=52;
    //---- indicator buffers
    double Tenkan_Buffer[];
    double Kijun_Buffer[];
    double SpanA_Buffer[];
    double SpanB_Buffer[];
    double Chinkou_Buffer[];
    double SpanA2_Buffer[];
    double SpanB2_Buffer[];
    //---- span_a drawing begin
    int a_begin;
    //+------------------------------------------------------------------+
    //| Custom indicator initialization function                         |
    //+------------------------------------------------------------------+
    int init()
      {
    //----
       SetIndexStyle(0,DRAW_LINE);
       SetIndexBuffer(0,Tenkan_Buffer);
       SetIndexDrawBegin(0,Tenkan-1);
       SetIndexLabel(0,"Tenkan Sen");
    //----
       SetIndexStyle(1,DRAW_LINE);
       SetIndexBuffer(1,Kijun_Buffer);
       SetIndexDrawBegin(1,Kijun-1);
       SetIndexLabel(1,"Kijun Sen");
    //----
       a_begin=Kijun; if(a_begin<Tenkan) a_begin=Tenkan;
       SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_DOT);
       SetIndexBuffer(2,SpanA_Buffer);
       SetIndexDrawBegin(2,Kijun+a_begin-1);
       SetIndexShift(2,Kijun);
       SetIndexLabel(2,NULL);
       SetIndexStyle(5,DRAW_LINE,STYLE_DOT);
       SetIndexBuffer(5,SpanA2_Buffer);
       SetIndexDrawBegin(5,Kijun+a_begin-1);
       SetIndexShift(5,Kijun);
       SetIndexLabel(5,"Senkou Span A");
    //----
       SetIndexStyle(3,DRAW_HISTOGRAM,STYLE_DOT);
       SetIndexBuffer(3,SpanB_Buffer);
       SetIndexDrawBegin(3,Kijun+Senkou-1);
       SetIndexShift(3,Kijun);
       SetIndexLabel(3,NULL);
       SetIndexStyle(6,DRAW_LINE,STYLE_DOT);
       SetIndexBuffer(6,SpanB2_Buffer);
       SetIndexDrawBegin(6,Kijun+Senkou-1);
       SetIndexShift(6,Kijun);
       SetIndexLabel(6,"Senkou Span B");
    //----
       SetIndexStyle(4,DRAW_LINE);
       SetIndexBuffer(4,Chinkou_Buffer);
       SetIndexShift(4,-Kijun);
       SetIndexLabel(4,"Chinkou Span");
    //----
       return(0);
      }
    //+------------------------------------------------------------------+
    //| Ichimoku Kinko Hyo                                               |
    //+------------------------------------------------------------------+
    int start()
      {
       int    i,k;
       int    counted_bars=IndicatorCounted();
       double high,low,price;
    //----
       if(Bars<=Tenkan || Bars<=Kijun || Bars<=Senkou) return(0);
    //---- initial zero
       if(counted_bars<1)
         {
          for(i=1;i<=Tenkan;i++)    Tenkan_Buffer[Bars-i]=0;
          for(i=1;i<=Kijun;i++)     Kijun_Buffer[Bars-i]=0;
          for(i=1;i<=a_begin;i++) { SpanA_Buffer[Bars-i]=0; SpanA2_Buffer[Bars-i]=0; }
          for(i=1;i<=Senkou;i++)  { SpanB_Buffer[Bars-i]=0; SpanB2_Buffer[Bars-i]=0; }
         }
    //---- Tenkan Sen
       i=Bars-Tenkan;
       if(counted_bars>Tenkan) i=Bars-counted_bars-1;
       while(i>=0)
         {
          high=High[i]; low=Low[i]; k=i-1+Tenkan;
          while(k>=i)
            {
             price=High[k];
             if(high<price) high=price;
             price=Low[k];
             if(low>price)  low=price;
             k--;
            }
          Tenkan_Buffer[i]=(high+low)/2;
          i--;
         }
    //---- Kijun Sen
       i=Bars-Kijun;
       if(counted_bars>Kijun) i=Bars-counted_bars-1;
       while(i>=0)
         {
          high=High[i]; low=Low[i]; k=i-1+Kijun;
          while(k>=i)
            {
             price=High[k];
             if(high<price) high=price;
             price=Low[k];
             if(low>price)  low=price;
             k--;
            }
          Kijun_Buffer[i]=(high+low)/2;
          i--;
         }
    //---- Senkou Span A
       i=Bars-a_begin+1;
       if(counted_bars>a_begin-1) i=Bars-counted_bars-1;
       while(i>=0)
         {
          price=(Kijun_Buffer[i]+Tenkan_Buffer[i])/2;
          SpanA_Buffer[i]=price;
          SpanA2_Buffer[i]=price;
          i--;
         }
    //---- Senkou Span B
       i=Bars-Senkou;
       if(counted_bars>Senkou) i=Bars-counted_bars-1;
       while(i>=0)
         {
          high=High[i]; low=Low[i]; k=i-1+Senkou;
          while(k>=i)
            {
             price=High[k];
             if(high<price) high=price;
             price=Low[k];
             if(low>price)  low=price;
             k--;
            }
          price=(high+low)/2;
          SpanB_Buffer[i]=price;
          SpanB2_Buffer[i]=price;
          i--;
         }
    //---- Chinkou Span
       i=Bars-1;
       if(counted_bars>1) i=Bars-counted_bars-1;
       while(i>=0) { Chinkou_Buffer[i]=Close[i]; i--; }
    //----
       return(0);
      }
    //+------------------------------------------------------------------+
  • SetIndexStyle()関数はインジケータラインのタイプ、スタイル、幅、色を設定します。 DRAW_LINEは、指標配列の値の範囲内でデータを線で結びます。サブウィンドウでの DRAW_HISTOGRAM もいくつか特徴があります。チャートは偶数の配列値と奇数の配列値の範囲内に描かれます。その場合、最大値の配列の色を利用します。

  • SetIndexDrawBegin()関数は、カスタムインディケータの描画を開始するバーの位置を指定するために使用します。

  • SetIndexBuffer()関数は、各指標バッファを、指標バッファ領域に割り当てるために使用します。システムは指標配列を処理していることにご注意ください。そういった理由で、配列の大きさの指定は必要ありません。

    //---- indicator buffers
    double Tenkan_Buffer[];
    double Kijun_Buffer[];
    double SpanA_Buffer[];
    double SpanB_Buffer[];
    double Chinkou_Buffer[];
    double SpanA2_Buffer[];
    double SpanB2_Buffer[];

    ArrayResize()関数は指標配列値を設定するためには使用できません。又、 ArrayInitialize()関数は指標配列値を設定するためには使用できません。配列は自動的に初期化されます。初期値としてEMPTY_VALUEあるいはSetIndexEmptyValue関数に指定された値を使用します。空の値は表示されません。

  • SetIndexEmptyValue()関数は、インディケータをチャートウィンドウに描画させず、また、データウィンドウにも表示させない値を設定するために使用します。NULLは、インデックス値がデータ ウィンドウに表示されない事を意味します。この場合、「雲」はチャート上で網掛けになっている部分となり、線の範囲内に限られます。線形配列もチャート形配列も同じ値を持っています。

  • IndicatorCounted()関数は経済的計算に利用されます。IndicatorCounted()関数は、インディケータの確定値が計算されたバー(=現在のバー以外)の本数を取得するために使用します。配列の再初期化の場合や、履歴データを更新するときに、バーの数は0になります。

  • もう1つ、例を見てみましょう。Accelerator/Decelerator オシレータ:

    //+------------------------------------------------------------------+
    //|                                                  Accelerator.mq4 |
    //|                      Copyright © 2005, MetaQuotes Software Corp. |
    //|                                       https://www.metaquotes.net/ |
    //+------------------------------------------------------------------+
    #property  copyright "Copyright © 2005, MetaQuotes Software Corp."
    #property  link      "https://www.metaquotes.net/"
    //---- indicator settings
    #property  indicator_separate_window
    #property  indicator_buffers 3
    #property  indicator_color1  Black
    #property  indicator_color2  Green
    #property  indicator_color3  Red
    //---- indicator buffers
    double     ExtBuffer0[];
    double     ExtBuffer1[];
    double     ExtBuffer2[];
    double     ExtBuffer3[];
    double     ExtBuffer4[];
    //+------------------------------------------------------------------+
    //| Custom indicator initialization function                         |
    //+------------------------------------------------------------------+
    int init()
      {
    //---- 2 additional buffers are used for counting.
       IndicatorBuffers(5);
    //---- drawing settings
       SetIndexStyle(0,DRAW_NONE);
       SetIndexStyle(1,DRAW_HISTOGRAM);
       SetIndexStyle(2,DRAW_HISTOGRAM);
       IndicatorDigits(Digits+2);
       SetIndexDrawBegin(0,38);
       SetIndexDrawBegin(1,38);
       SetIndexDrawBegin(2,38);
    //---- 4 indicator buffers mapping
       SetIndexBuffer(0,ExtBuffer0);
       SetIndexBuffer(1,ExtBuffer1);
       SetIndexBuffer(2,ExtBuffer2);
       SetIndexBuffer(3,ExtBuffer3);
       SetIndexBuffer(4,ExtBuffer4);
    //---- name for DataWindow and indicator subwindow label
       IndicatorShortName("AC");
       SetIndexLabel(1,NULL);
       SetIndexLabel(2,NULL);
    //---- initialization done
       return(0);
      }
    //+------------------------------------------------------------------+
    //| Accelerator/Decelerator Oscillator                               |
    //+------------------------------------------------------------------+
    int start()
      {
       int    limit;
       int    counted_bars=IndicatorCounted();
       double prev,current;
    //---- last counted bar will be recounted
       if(counted_bars>0) counted_bars--;
       limit=Bars-counted_bars;
    //---- macd counted in the 1-st additional buffer
       for(int i=0; i<limit; i++)
          ExtBuffer3[i]=iMA(NULL,0,5,0,MODE_SMA,PRICE_MEDIAN,i)-
                        iMA(NULL,0,34,0,MODE_SMA,PRICE_MEDIAN,i);
    //---- signal line counted in the 2-nd additional buffer
       for(i=0; i<limit; i++)
          ExtBuffer4[i]=iMAOnArray(ExtBuffer3,Bars,5,0,MODE_SMA,i);
    //---- dispatch values between 2 buffers
       bool up=true;
       for(i=limit-1; i>=0; i--)
         {
          current=ExtBuffer3[i]-ExtBuffer4[i];
          prev=ExtBuffer3[i+1]-ExtBuffer4[i+1];
          if(current>prev) up=true;
          if(current<prev) up=false;
          if(!up)
            {
             ExtBuffer2[i]=current;
             ExtBuffer1[i]=0.0;
            }
          else
            {
             ExtBuffer1[i]=current;
             ExtBuffer2[i]=0.0;
            }
           ExtBuffer0[i]=current;
         }
    //---- done
       return(0);
      }
    //+------------------------------------------------------------------+
  • IndicatorBuffers()関数は、インディケータの計算に使用するバッファの個数を指定します。IndicatorBuffers()関数は、チャートウィンドウ上に表示させるインディケータバッファの個数と、計算に使用するインディケータバッファの個数とが異なる場合に使用します。ただし、システムは追加の配列を処理します。

  • SetIndexDigits()関数は、情報出力の正確を期します2つの中央線の差分や、結果とシグナル線の差分を計算するときに、小数点以下が3 桁の標準精度は足りません。

  • SetIndexDrawBegin()関数は、インディケータの描画を開始するバーの位置を指定するために使用します。この例では、シグナル線は単純移動平均をもとに計算した単純移動平均のものです。それで、最初の38値は空の値で、表示されません。

  • IndicatorShortName()関数は、チャートのサブウインドウに表示されるカスタムインディケータの短縮名を設定します。デフォルトの短縮名としてカスタムインディケータの名前が使用されます。この例では、SetIndexLabel関数は要りません。1つだけの値を出力するためにカスタムインディケータの名前だけ必要です。

  • SetIndexStyle()関数はインジケータラインのタイプ、スタイル、幅、色を設定します。 DRAW_NONEは、余計な線を指定します。このインディケータによるチャートキャンドルは2つの色に設定しなければなりません。ExtBuffer0のデータはExtBuffer1とExtBuffer2など配列によります。「NULL」のSetIndexLabel関数は、インディケータをチャートウィンドウに描画させず、また、データウィンドウにも表示させない値を設定するために使用します。DRAW_HISTOGRAMは、0値から配列値までの範囲内でチャートを描かせます。

  • 入力パラメータをexternとして指定し、どんな型でも受け入れます。

  • 入力パラメータを指定しなかった場合、カスタムインディケータの呼出は最も簡単な形式で行われます。

    double current_AC = iCustom( NULL, 0, "Accelerator", 0, 0 );

    0とNULLの移転は、当チャートを使用するという意味があります。カスタムインディケータの名前としてmq4拡張子を持たないファイル名が使用されます。 最後の前の0パラメータは最初の指標配列のデータが必要であるということになります。最後の0パラメータは最後の指標配列のデータが必要であるということになります。

  • システムは、そのパラメータの過程を上記の通りに仮定します。例えば、カスタムインディケータの一目均衡表 (9,26,52)を呼び出すのは以下になります:

    iCustom( NULL, 0, "Ichimoku", 9, 26, 52, 0, shift );

    カスタムインディケータのパラメータの入力は必要ありません。入力パラメータをexternとして指定しない場合、適当な変更ができません。パラメータ値を指定するには、初期値も利用できます。例えば、カスタムインディケータの呼出は以下のようになります:

    iCustom( NULL, 0, "Ichimoku", 0, shift );

    転換線の値、基準線の値と先行スパンの値(つまり、9・26・52)が使用されるという意味です。しかし、1つのEAを使ってパラメータが複数あるカスタムインディケータを呼び出す場合、デフォルト設定は勧められません。

注意:カスタムインディケータの余分な数、または間違って作られたカスタムインディケータはクライアント端末の速度を落とす恐れがあります!

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

Strategy Tester: トレード戦略のテストモード Strategy Tester: トレード戦略のテストモード
テクニカル分析の多くのプログラムは、履歴データで取引戦略をテストすることができます。
エキスパートアドバイザ作成の特徴 エキスパートアドバイザ作成の特徴
MetaTrader 4取引システムでのエキスパートアドバイザ作成の特徴
EAのバックテストのレポートの見方 EAのバックテストのレポートの見方
EAのバックテストのレポートのおかげで様々なエキスパートアドバイザーをならべ比べることができます。この記事はそのようなレポートについて説明しています。
トレードシステムの評価 - 参入、退出と取引における一般の有効性 トレードシステムの評価 - 参入、退出と取引における一般の有効性
トレードシステムの有効性と利益性を決定できる多数の尺度がある。しかし、トレーダーは常にどのシステムでも試したいと考えている。この記事はどのようにして有効性の尺度に基づいた統計が MetaTrader 5 のプラットフォームに使えるかを教えるものである。 これは取引による統計の解釈を、S.V.Bulashev(ブラシェフ)による著作"Statistika dlya traderov"(トレーダーのための統計) の記述に矛盾しないものに変換するクラスを含んでいる。また最適化のためのカスタムファンクションの例も含んでいる。