English Русский 中文 Español Deutsch Português 한국어 Français Italiano Türkçe
MQL5: 自分のインディケーターの作成

MQL5: 自分のインディケーターの作成

MetaTrader 5 | 13 8月 2015, 10:09
13 568 0
MetaQuotes
MetaQuotes

はじめに

インディケーターとは何でしょう? チャート上に便利な方法で表示したい計算値の一式です。値の一式はプログラムでarraysと表示されます。そのため、インディケーターの作成は配列 (価格配列) を取り扱い、他の配列 (インディケーター 値)に結果を記録するアルゴリズムを書くことを意味します。

すぐに使えるインディケーターが多くあるにもかかわらず(それはもうお馴染みになりましたが)、自分のインディケーターを作る必要性が常に存在します。このような自分のアルゴリズムで作ったインディケーターはカスタムインディケーターと呼ばれます。本記事はシンプルなカスタム・インディケーターの作成方法について説明します。


それぞれ異なるインディケーター

インディケーターによっては、カラーラインや領域、ポジションエンターの最適な時を指す特別ラベルポインターであったりします。またこれらのタイプは組み合わせることができるので、さらに多くのインディケータータイプが存在します。William Blauが開発した有名なTrue Strength Indexの例をとってインディケーターの作成について考察しましょう。


True Strength Index

TSIインディケーターは、トレンドまたは買われすぎ/売られすぎの領域を特定するために、ダブル平滑化モメンタムに基づいています。数学的説明はWilliam BlauによるMomentum, Direction, and Divergenceにあります。ここではその計算式だけを書きます。

TSI(CLOSE,r,s) =100*EMA(EMA(mtm,r),s) / EMA(EMA(|mtm|,r),s)

ここで:

  • mtm = CLOSEcurrent – CLOSprev, 配列値は現在のバーと以前のバーの終値の相違を表す。;
  • EMA(mtm,r) = 周期長が rに等しいmtm値の指数平滑;
  • EMA(EMA(mtm,r),s) = s 期間のEMA(mtm,r) 値の指数平滑;
  • |mtm| = mtm;
  • r = 25,
  • s = 13.

この式から、インディケーター計算に影響する3つのパラメータを抽出できます。それらは r と s期間、そして計算に使われる価格タイプです。ここでは終値を使います。


MQL5 ウィザード

TSIをブルーラインで表示しましょう。 ここではMQL5 ウィザードをスタートする必要があります。最初のステージでは作成したいプログラムのタイプ、カスタムインディケーターを示す必要があります。第2のステージではプログラム名、rs パラメーターとその値を設定しましょう。

MQL5 ウィザード: インディケーター名とパラメーターの設定

次に、インディケーターが別のウインドウでブルーラインとして表示されるように定義し 、このライン用にTSI ラベルを設定しましょう。

MQL5 ウィザード: 設定 インディケーター タイプ

全ての初期 データが入力されたので完了を押し、インディケーターのドラフトを入手します。

//+------------------------------------------------------------------+
//|                                          True Strength Index.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//---- plot TSI
#property indicator_label1  "TSI"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Blue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      r=25;
input int      s=13;
//--- indicator buffers
double         TSIBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,TSIBuffer,INDICATOR_DATA);
//---
   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[])
  {
//---
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

MQL5 ウィザードはインディケータープロパティーを書くインディケーターヘッダーを作成します。つまり、

  • インディケーターは別のウインドウで表示されます。;
  • インディケーターバッファーの数, indicator_buffers=1;
  • プロットの数 , indicator_plots= 1;
  • プロットNo 1の名前, indicator_label1="TSI";
  • 最初のプロットのスタイル -ライン, indicator_type1=DRAW_LINE;
  • プロット No 1の色, indicator_color1=Blue;
  • ラインのスタイル, indicator_style1=STYLE_SOLID;
  • プロット1のライン幅 , indicator_width1=1.

全ての準備が整ったので、これで私たちのコードを洗練・改良できます。


OnCalculate()

OnCalculate() 関数は、Calculate イベントのハンドラーで、インディケーター 値の再計算とそれをチャートへの再度作画が必要な時に現れます。これは新しい ティック受領やシンボルヒストリー更新などのイベントです。そのため、インディケーター 値のすべての計算メインコードは必ずこの関数の中になければなりません。

もちろん、補助計算は他の別の関数でも実行できますが、これらの関数はOnCalculateハンドラーで使用されなければなりません。

デフォルトでは、 MQL5 ウィザードは全タイプの時系列へのアクセスを提供するOnCalculate()の第二のフォームを作ります。

  • 始値・高値・安値・終値;
  • ボリューム (リアルそして/または ティック);
  • スプレッド;
  • オープニング時間期間

しかし我々のケースでは一つのデータ配列のみ必要ですから、OnCalculate() 第一のフォーム の呼び出しを変えましょう。

int OnCalculate (const int rates_total,      // size of the price[] array
                 const int prev_calculated,  // number of available bars at the previous call
                 const int begin,            // from what index in price[] authentic data start
                 const double& price[])      // array, on which the indicator will be calculated
  {
//---
//--- return value of prev_calculated for next call
   return(rates_total);
  }

これによってインディケーターを価格データにさらに適用できるだけでなく、他のインディケーター値に基づいてインディケーターを作ることができます。

カスタムインディケーター計算用のデータタイプの指定

price[] もし、パラメータータブでClose を選択すると(これはデフォルトで表示されます)、OnCalculate() に渡された価格[] が終値を含みます。例えばもし Typical Priceを選択すると、価格[]が各期間の(High+Low+Close)/3の価格を含みます。

rates_total パラメーターは価格[] 配列のサイズを表し、サイクル計算の組織化に便利です。価格[]における要素のインデックス作成はゼロから始まり過去から将来に向かっています。例えば、価格[0] 要素は一番古い値を含み、一方、価格[rates_total-1]は最新の配列エレメントを含みます。


補助インディケーターバッファーの組織化

インディケーター配列データなど、一本のラインのみがチャートに表示されます。でもその前に中間計算をまとめる必要があります。中間データはインディケーター配列に保管され 、INDICATOR_CALCULATIONS 属性でマークされます。この式から追加の配列が必要なことが見えます。

  1. for values mtm - array MTMBuffer[];
  2. for values |mtm| - array AbsMTMBuffer[];
  3. for EMA(mtm,r) - array EMA_MTMBuffer[];
  4. for EMA(EMA(mtm,r),s) - array EMA2_MTMBuffer[];
  5. for EMA(|mtm|,r) - array EMA_AbsMTMBuffer[];
  6. for EMA(EMA(|mtm|,r),s) - array EMA2_AbsMTMBuffer[].

また、ダブルタイプの配列をさらに6つグローバルレベルに追加し、これらの配列をインディケーターバッファーとOnInit()関数で組み合わせる必要があります。インディケーターバッファーの新しい数を示すのを忘れないで下さい。 indicator_buffers プロパティは7に等しくなければなりません。 (1つだったのでさらに6つのバッファーが追加)

#property indicator_buffers 7

今、インディケーターコードはこのように見えます。

#property indicator_separate_window
#property indicator_buffers 7
#property indicator_plots   1
//---- plot TSI
#property indicator_label1  "TSI"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Blue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      r=25;
input int      s=13;
//--- indicator buffers
double         TSIBuffer[];
double         MTMBuffer[];
double         AbsMTMBuffer[];
double         EMA_MTMBuffer[];
double         EMA2_MTMBuffer[];
double         EMA_AbsMTMBuffer[];
double         EMA2_AbsMTMBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,TSIBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,MTMBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,AbsMTMBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,EMA_MTMBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,EMA2_MTMBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,EMA_AbsMTMBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(6,EMA2_AbsMTMBuffer,INDICATOR_CALCULATIONS);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,    // size of the price[] array;
                 const int prev_calculated,// number of available bars;
                                           // during the previous call;
                 const int begin,          // from what index in  
                                           // price[] authentic data start;
                 const double& price[])    // array, on which the indicator will be calculated;
  {
//---
//--- return value of prev_calculated for next call
   return(rates_total);
  }


中間計算

バッファー MTMBuffer[] と AbsMTMBuffer[]のための計算値を組織化することはとても簡単です。ループで、一つ一つ価格[1]から価格[rates_total-1]まで、一つの配列に相違を書き、2つ目に相違の絶対値を書きます。

//--- calculate values of mtm and |mtm|
   for(int i=1;i<rates_total;i++)
     {
      MTMBuffer[i]=price[i]-price[i-1];
      AbsMTMBuffer[i]=fabs(MTMBuffer[i]);
     }

次のステージはこれらの配列の指数平均計算です。それには2つの方法があります。1つはアルゴリズム全体を間違いなく書こうとする事です。 2つ目はデバッグ済でまさにこの目的のためにすぐに使える関数を使う事です。

MQL5では、配列値による移動平均計算用の内蔵関数はありません。しかし、すぐに使えるライブラリ関数MovingAverages.mqhがあります。その完全なパスは terminal_directory/MQL5/Include/MovingAverages.mqhで、terminal_directory はMetaTrader 5 ターミナルがインストールされたカタログです。そのライブラリは インクルードファイルで、4つの古典的方法を使って配列の移動平均 を計算する関数を含みます。

  • 単純平均
  • 指数平均
  • 平滑平均
  • 線形加重平均

MQL5プログラムでこれらの関数を使うには、次をコードヘッダーに追加します。

#include <MovingAverages.mqh>

配列値の指数移動平均を計算し、その平均を別の配列に記録する ExponentialMAOnBuffer()関数が必要です。


配列平滑関数

MovingAverages.mqhのインクルードファイルは8つの関数を含み、それは2つの同じ関数を持つグループに分けることができますが、それぞれ4つ含みます。 最初のグループは配列を受け取り、指定ポジションの移動平均値を単に戻す関数を含みます。

  • SimpleMA() - 単純平均値計算
  • ExponentialMA() - 指数平均値計算;
  • SmoothedMA() - 平滑平均値計算;
  • LinearWeightedMA() - 線形加重平均値計算;

これらの関数は配列平均値の一回入手を目的としており、複数セルには最適でありません。もしループでこのグループからの関数を使う必要がある場合(平均値計算とさらに配列に各計算値を書くため)、最適アルゴリズムを組織化しなければなりません。

第二の関数グループは初期値配列に基づいた移動平均値で受信配列を記入することを目的としています。

  • SimpleMAOnBuffer() - 価格[] 配列からの単純平均値で出力配列バッファー[]を記入
  • ExponentialMAOnBuffer() - 価格[] 配列からの指数平均値で出力配列バッファー[]を記入
  • SmoothedMAOnBuffer() - 価格[] 配列からの平滑平均値で出力配列バッファー[]を記入
  • LinearWeightedMAOnBuffer() - 価格[] 配列からの線形加重平均値で出力配列バッファー[]を記入

配列バッファー[]・価格[] ・平均期間 period 以外の全ての指定関数は、さらに3つのパラメーターを入手し、その目的はOnCalculate() 関数、rates_total・ prev_calculated そして beginパラメーターに似ています。 このグループの関数はインデックス(AS_SERIES フラグ)の方向 を考慮に入れながら、渡された価格[] とバッファー[] の配列を正常に処理します。

begin パラメーターはソース配列のインデックスを示しますが、そこから取り扱わなければならないデータなど重要データが始まります。MTMBuffer[] 配列は、MTMBuffer[1]=price[1]-price[0]なのでリアルデータはインデックス1で始まります。MTMBuffer[0]値は未定義なのでbegin=1です。

//--- calculate the first moving
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         1,  // index, starting from which data for smoothing are available 
                         r,  // period of the exponential average
                         MTMBuffer,       // buffer to calculate average
                         EMA_MTMBuffer);  // into this buffer locate value of the average
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         1,r,AbsMTMBuffer,EMA_AbsMTMBuffer);

平均化時、出力配列では計算値が少し遅れて記入されるため、期間値を考慮しなければなりません。 その遅れは大きな平均化期間では大きくなります。例えば、もしperiod=10の場合、その配列の値はbegin+period-1=begin+10-1で始まります。バッファー[]のさらなる呼び出しでは、 インデックス begin+period-1で処理を始めなければならないことに考慮するべきです。

このようにしてMTMBuffer[] と AbsMTMBuffer配列から簡単に第二指数平均を入手できます。

//--- calculate the second moving average on arrays
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         r,s,EMA_MTMBuffer,EMA2_MTMBuffer);
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         r,s,EMA_AbsMTMBuffer,EMA2_AbsMTMBuffer);

begin=1+r-1 なのでbegin値は今 r に等しいです。 (r は主要指数平均の期間。 インデックス 1で処理が始まる)。インデックス rで入力配列の処理を開始し、第二指数平均期間は s に等しいので、EMA2_MTMBuffer[] と EMA2_AbsMTMBuffer[]の出力配列では、計算値はindex r+s-1で始まります。

全て事前計算が整ったので、チャートにプロットされるインディケーター バッファー値TSIバッファー[]を計算できます。

//--- now calculate values of the indicator
   for(int i=r+s-1;i<rates_total;i++)
     {
      TSIBuffer[i]=100*EMA2_MTMBuffer[i]/EMA2_AbsMTMBuffer[i];
     }
F7 キーを押してコードをコンパイルし、MetaTrader 5 ターミナルを開始します。うまくいきました!

最初のバージョンのTrue Strength Index

それでも疑問点が残りました。


計算の最適化

実は、実働インディケーターを書くだけでは十分ではありません。OnCalculate()の現在の実行を注意してみると最適でないのが見えます。

int OnCalculate (const int rates_total,    // size of the price[] array;
                 const int prev_calculated,// number of available bars;
                 // at the previous call;
                 const int begin,// from what index of the 
                 // price[] array true data start;
                 const double &price[]) // array, at which the indicator will be calculated;
  {
//--- calculate values of mtm and |mtm|
   MTMBuffer[0]=0.0;
   AbsMTMBuffer[0]=0.0;
   for(int i=1;i<rates_total;i++)
     {
      MTMBuffer[i]=price[i]-price[i-1];
      AbsMTMBuffer[i]=fabs(MTMBuffer[i]);
     }
//--- calculate the first moving average on arrays
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         1,  // index, starting from which data for smoothing are available 
                         r,  // period of the exponential average
                         MTMBuffer,       // buffer to calculate average
                         EMA_MTMBuffer);  // into this buffer locate value of the average
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         1,r,AbsMTMBuffer,EMA_AbsMTMBuffer);

//--- calculate the second moving average on arrays
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         r,s,EMA_MTMBuffer,EMA2_MTMBuffer);
   ExponentialMAOnBuffer(rates_total,prev_calculated,
                         r,s,EMA_AbsMTMBuffer,EMA2_AbsMTMBuffer);
//--- now calculate values of the indicator
   for(int i=r+s-1;i<rates_total;i++)
     {
      TSIBuffer[i]=100*EMA2_MTMBuffer[i]/EMA2_AbsMTMBuffer[i];
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

各関数のスタートでは、 我々はMTMBuffer[] と AbsMTMBuffer[]配列値を計算します。この場合、もし価格[]サイズが数百、数千、または数百万の場合、 不必要な計算の繰り返しがどんなパワフルなCPUだとしても全てのCPUリソースをとってしまいます。

最適計算の組織化には、prev_calculated 入力パラメーターを使います。それは以前の呼び出し時のOnCalculate() によって戻された値に等しいです。関数の最初の呼び出しでは、 prev_calculatedは常に0に等しいです。この場合、インディケーターバッファー内のすべての値を計算します。次の呼び出し中、バッファー全体を計算する必要はありません。最後の値だけ計算されます。以下のように書きましょう。

//--- if it is first call 
   if(prev_calculated==0)
     {
      //--- set zero values to zero indexes
      MTMBuffer[0]=0.0;
      AbsMTMBuffer[0]=0.0;
     }
//--- calculate values of mtm and |mtm|
   int start;
   if(prev_calculated==0) start=1;  // start filling out MTMBuffer[] and AbsMTMBuffer[] from the 1st index 
   else start=prev_calculated-1;    // set start equal to the last index in the arrays 
   for(int i=start;i<rates_total;i++)
     {
      MTMBuffer[i]=price[i]-price[i-1];
      AbsMTMBuffer[i]=fabs(MTMBuffer[i]);
     }

EMA_MTMBuffer[], EMA_AbsMTMBuffer[], EMA2_MTMBuffer[] そして EMA2_AbsMTMBuffer[]の計算ブロックは計算の最適化を必要としません。 なぜなら ExponentialMAOnBuffer()はすでに最適な方法で書かれているからです。TSIBuffer[] 配列用の計算値を最適化すればいいだけです。MTMBuffer[]に使用されるものと同じ方法を使います。

//--- now calculate the indicator values
   if(prev_calculated==0) start=r+s-1; // set the starting index for input arrays
   for(int i=start;i<rates_total;i++)
     {
      TSIBuffer[i]=100*EMA2_MTMBuffer[i]/EMA2_AbsMTMBuffer[i];
     }
//--- return value of prev_calculated for next call
   return(rates_total);

最適化手順の最後の注意点: OnCalculate() はrates_total値を戻します。それはインディケーター計算に使用される価格[] 入力配列の要素数を意味します。

OnCalculate()で戻された値はターミナルメモリに保存され、OnCalculate()の次の呼び出し時に 入力 パラメーター prev_calculated値として関数に渡されます。

このことで、以前のOnCalculate()の呼び出し時の入力配列サイズを常に知り、不要な計算なく正しいインデックスからインディケーター バッファーの計算を始めることができます。


入力データの確認

OnCalculate() が完全に操作するためにもう一つやらなければならない事があります。インディケーター値が計算される価格[] 配列の確認を追加しましょう。もし配列(rates_total) のサイズ が小さすぎると、計算が要求されません。データが十分な時OnCalculate()が次に呼び出されるまで待たなければなりません。

//--- if the size of price[] is too small
  if(rates_total<r+s) return(0); // do not calculate or draw anything
//--- if it's first call 
   if(prev_calculated==0)
     {
      //--- set zero values for zero indexes
      MTMBuffer[0]=0.0;
      AbsMTMBuffer[0]=0.0;
     }

True Strength Indexを計算するために指数平滑が2度順に使われるため、価格[]のサイズは 少なくとも r と s期間の合計に等しいか、それよりも大きくなければなりません。そうでないと実行が終了し、OnCalculate() が0に戻ってしまいます。戻ったゼロ値はインディケーターの値が計算されなかったためインディケーターがチャートにプロットされないことを意味します。


表現セットアップ

計算の正確性については、インディケーターが使用可能です。しかし、もし別のmql5-プログラムからそれを呼ぶ場合、デフォルトにより終値で作られます。別のデフォルト価格タイプを指定できます。 indicator_applied_price のインディケータープロパティ にあるENUM_APPLIED_PRICE 列挙から値を指定します。

例えば、ある価格に典型的な価格 ( (high+low+close)/3) を設定するには以下を書きましょう。

#property indicator_applied_price PRICE_TYPICAL

もし iCustom() または IndicatorCreate() 関数を使ってその値だけを使うつもりの場合、それ以上手を加える必要はありません。しかし、チャート内にプロットなど直接使われた場合、追加設定が推奨されます。:

  • インディケーターがプロットされ始めるバー数;
  • データウインドウに反映されるTSIBuffer[]値のラベル;
  • インディケーター ライン上にマウスカーソルをポイントしている時に別のウインドウとポップアップヘルプ現れるインディケーターの短い名前;
  • インディケーター値に表示される桁数後の桁数 (これは正確性に影響しません。)

これらの設定はOnInit() ハンドラーでカスタムインディケーター グループからの関数を使って調整できます。新しいラインを追加して、True_Strength_Index_ver2.mq5としてインディケーター を保存します。

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,TSIBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,MTMBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,AbsMTMBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,EMA_MTMBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,EMA2_MTMBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,EMA_AbsMTMBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(6,EMA2_AbsMTMBuffer,INDICATOR_CALCULATIONS);
//--- bar, starting from which the indicator is drawn
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,r+s-1);
   string shortname;
   StringConcatenate(shortname,"TSI(",r,",",s,")");
//--- set a label do display in DataWindow
   PlotIndexSetString(0,PLOT_LABEL,shortname);   
//--- set a name to show in a separate sub-window or a pop-up help
   IndicatorSetString(INDICATOR_SHORTNAME,shortname);
//--- set accuracy of displaying the indicator values
   IndicatorSetInteger(INDICATOR_DIGITS,2);
//---
   return(0);
  }

もし両方のインディケーターのバージョンを開始し、 チャートを始めにスクロールすると違いが見えます。

True Strength Index インディケーターの第二バージョンはもっと良く見えます。


結論

True Strength Index インディケーターの作成例に基づき、MQL5でインディケーターを書く基本プロセスを概説できます。

  • 自分自身のカスタムインディケーター作るためには、インディケーター セットアップで予備的ルーチン動作の実行を助けるMQL5 ウィザードを使います。OnCalculate() 関数の必要変数を選択。
  • 必要な場合、中間計算にもっと配列を追加し、SetIndexBuffer()関数を使って 対応するインディケーター バッファーと結合します。これらのバッファー用にINDICATOR_CALCULATIONS タイプ を示します。
  • 価格データが変わるたびに、この関数が呼ばれるのでOnCalculate()での計算を最適化します。 コードの作成を楽にし可読性を増すために、デバッグ済ですぐに使える関数を使います。.
  • インディケーターのさらなる視覚チューニングを行い、他のmql5 プログラムとユーザーの両方にとってプログラムを使いやすくします。

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

インディケーターを別のインディケーターに適用 インディケーターを別のインディケーターに適用
OnCalculate() 関数呼び出しショートフォームのインディケーターを書くとき、インディケーターが価格データだけでなく、他のインディケーターデータによっても計算できる事実を見逃すかもしれません。 (内蔵またはカスタムのインディケーターにかかわらず)。他のインディケーターデータに正しく適用するためにインディケーターを改善したいですか?本記事ではそのような修正に必要なステップを復習します。
新しいレールへの第一歩: MQL5内のカスタムインディケーター 新しいレールへの第一歩: MQL5内のカスタムインディケーター
新しいターミナルと言語のすべての可能性と特徴をリストすることはしません。それらはあまりにも多くありすぎ、新規の特徴によっては別の記事で説明するに値します。またここにはオブジェクト指向プログラミングで書かれたコードがありません。開発者にとってさらに有利になる点として、ただ単に言及するにはあまりにも真剣なトピックです。本記事ではインディケーターとその構造・図面・タイプ・プログラミング の詳細についてMQL4と比較しながら考察します。初心者にも経験のある開発者にも本記事が有益となる事を願います。おそらく何か新しく学べることがあると思います。
Expert Advisorの限界と検証 Expert Advisorの限界と検証
このシンボルは月曜ににトレードできる? ポジションをオープンするのに必要なお金が十分ある? ストップロスが起こった時ロスの大きさは? ペンディングオーダーの数を制限するには? トレード操作が実行されたのは現在のバーそれとも以前のバー? トレードロボットがこの種の検証をできない場合、どんなトレードストラテジーも負け戦略になる可能性があります。本記事はどんなExpert Advisorにおいても便利な検証例を紹介します。
新しいMetaTrader 5 とMQL5の登場 新しいMetaTrader 5 とMQL5の登場
これはMetaTrader5のただの簡単なレビューです。このような短い時間でシステムのすべての特徴を述べることはできません。2009年9月9日に試用を開始しました。これはシンボル的な日付でラッキーナンバーになると信じています。ベータ版のMetaTrader5とMQL5を手に入れて数日が経ちました。まだ全ての特徴を使ってはいませんが、すでに関心させられました。