カスタムインディケータ作成の特徴
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
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索