English Русский 中文 Español Deutsch Português 한국어 Français Italiano Türkçe
MQL5における 20のトレードシグナル

MQL5における 20のトレードシグナル

MetaTrader 5 | 18 9月 2015, 18:21
6 607 0
Sergey Gritsay
Sergey Gritsay

はじめに

トレーダーは価格の動きに何かの規則性を見出そうとし、規則を作る努力をしそれを用いて売買に好ましい瞬間を決定する良いチャンスを得ようとする。全自動のシステムを構築するには、そのような瞬間 (トレードシグナル) の前兆を知らせる方法を学ばなければならない。

シグナルはトレーダーにポジションに入る可能性のある時点を知らせるが、その全てが必ず実行すべきものではない。追加の判断基準がたいていのシグナルを選択から外すが、それはここで重要なことではない。この記事での主題はMQL5で最も評判の高いトレードシグナルをプログラムする方法についてである。


1. どのようなシグナルを知っているか?

市場に入る瞬間を決定する方法の全てはいくつかのタイプに分けられる。

  • 移動平均の交点
  • 範囲からの飛び抜け
  • 統計的なレートに基づく買いすぎ/売りすぎの範囲から外れる
  • 跳ね返りチャンネルの境界から跳ね返り
  • チャンネルの境界を飛び抜ける
  • トレンドの変化


2. コーディングをよりよくする行うには?

コードを書く方法はたくさんありOnStart(), OnTick()と他のファンクションの中で書くことができる。このことに関する詳細についてはこのウエブサイトのdocumentation にあるいは MetaEditorに埋め込まれているユーザーガイドに見つけることができるが; この方法は効率が悪く、時にコードの同じ部分を数回も書き直す必要がある。そこで、我々は別の方法を取り、自分のプログラムのどの部分からでも呼び出すことのできるカスタムファンクションを使う。

作成したファンクションを使う便宜上、それらを別のグループに外部 include fileインクルードファイルとしてまとめそれ SignalTrade と名付ける; それは ...\MQL5\Include ディレクトリーに保存される。そうするとこのモジュールを簡単にどのプログラムにも接続できる。

全てのシグナルは異なっているように見えるが、それらは多くのことを共通に持っている。シグナルを発生するファンクションから受け取れる3つの異なったものがある:

  • 買いのシグナル
  • 売りのシグナル
  • シグナル無し

そこでこれらのシグナルに対して対応する目録を作成しよう。

  • 1 - 買いシグナル
  • -1 - 売りシグナル
  • 0 - シグナル無し

シグナルを返すファンクションのプロトタイプを書こう。このファンクションを一つ以上の操作が実行されるいくつかの部分に分割する。データを保存するのに必要な変数はファンクションの最初に宣言し初期化する。さらに作成したインジケーターからの必要な情報をロードしチェックする。データとプログラムの全体に取り組んでいるときに予期しない結末を避けるためには情報をチェックすることは必須のことである。

一旦情報がロードされチェックされたなら、シグナルを作ってみよう。シグナルが作成されるとすぐに、ファンクションから出て上記に述べた値の一つとして得られたシグナルを戻す。

int TradeSignal()
  {
   //--- zero means absence of signal
   int sig=0;
   
   //--- check the handles of indicators

   //--- if all the handles are invalid, create them

   //--- if the handles are valid, copy the values from indicators

   //--- check the copied data

   //--- in case of an error of copying, exit from the function

   //--- perform the indexation of the array as a timeseries

   //--- in case of an indexation error, exit from the function

   //--- check conditions and set the value for sig
 
   //--- return the trade signal
   return(sig);
  }


3. 20 のトレードシグナルの例

トレードシグナルを得るために異なるインジケーターを使う。MQL5 ではインジケーターは特別なファンクション 例えば iMA, iAC, iMACD, iIchimoku, 等を使って呼び出される; それらは 技術的なインジケーターに対応したコピー をクライアント側ターミナルのグローバルなキャッシュの中に作成する。もし同じパラメーターを持つインジケーターのコピーが既に存在する場合には、新しいコピーは作成されず、既存のコピーへのリンクのカウンターを1増やす。

これらのファンクションは対応するインジケーターのコピーのハンドルを戻す。さらに、このハンドルを用いて、対応するインジケーターによって計算されたデータを得ることができる。対応するバッファーのデータ (技術的インジケーターは計算したデータを内部バッファーに含んでいて、その数はインジケーターのタイプによって1から5まで変わる) がCopyBuffer()ファンクションを用いて一つの MQL5-program にコピーできる。

あるインジケーターのデータをその作成の直後に使うことは不可能である。それはインジケーターの値を計算するためにある時間が必要なためで、最も良い方法は OnInit()の中にハンドルを作ることである。iCustom() ファンクションは対応するカスタムインジケーターを作成するので、もし作成が成功すれば、インジケーターのハンドルを戻す。カスタムインジケーターは最大 512 のインジケーターバッファーまで含むことができ、その内容は CopyBuffer() ファンクションと得られたハンドルを用いて得られる。

各シグナルに対して我々のプロトタイプ TradeSignal() に従ってある ファンクションを作成し、次の順序に従ってそれらを数えよう: TradeSignal_01() - TradeSignal_20()。そのファンクションの構造を詳しく見て、移動平均の交差点に基づくシグナルの例を用いてシグナルを形成し、そして似た方法で他のシグナルに対するファンクションを書くことにしよう。

3.1. 移動平均の交差点

図 1. 2つの移動平均の交差点

図 1. 2つの移動平均の交差点

TradeSignal_01() ファンクションを用いて2つの 移動平均 (МА) (速い方は期間8、遅いほうは期間16) の交差点のシグナルを得る。

そのファンクションにおいて、交差の事実のみを修正し対応するシグナルの値をファンクションに戻すことにしよう。我々のルールとプロトタイプによって、そのファンクションは次のようなものになる:

int TradeSignal_01()
  {
//--- zero means that there is no signal
   int sig=0;

//--- check the handles of indicators
   if(h_ma1==INVALID_HANDLE)//--- if the handle is invalid
     {
      //--- create is again                                                      
      h_ma1=iMA(Symbol(),Period(),8,0,MODE_SMA,PRICE_CLOSE);
      //--- exit from the function
      return(0);
     }
   else //--- if the handle is valid
     {
      //--- copy value of the indicator to the array
      if(CopyBuffer(h_ma1,0,0,3,ma1_buffer)<3) //--- if the array of data is less than required
         //--- exit from the function
         return(0);
      //--- set the indexation in the array as in a timeseries                                   
      if(!ArraySetAsSeries(ma1_buffer,true))
         //--- in case of an indexation error, exit from the function
         return(0);
     }

   if(h_ma2==INVALID_HANDLE)//--- if the handle is invalid
     {
      //--- create it again                                                      
      h_ma2=iMA(Symbol(),Period(),16,0,MODE_SMA,PRICE_CLOSE);
      //--- exit from the function
      return(0);
     }
   else //--- if the handle is valid 
     {
      //--- copy values of the indicator to the array
      if(CopyBuffer(h_ma2,0,0,2,ma2_buffer)<2) //--- if there is less data than required
         //--- exit from the function
         return(0);
      //--- set the indexation in the array as in a timeseries                                   
      if(!ArraySetAsSeries(ma1_buffer,true))
         //--- in case of an indexation error, exit from the function
         return(0);
     }

//--- check the condition and set a value for the sig
   if(ma1_buffer[2]<ma2_buffer[1] && ma1_buffer[1]>ma2_buffer[1])
      sig=1;
   else if(ma1_buffer[2]>ma2_buffer[1] && ma1_buffer[1]<ma2_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

ここでコードの全ての部分をもっと詳細に見ていこう。ファンクションの最初にはシグナルのタイプを保存する local variable を宣言し、それをシグナルの無いことを示すゼロで初期化する。

int sig=0;

さらにハンドルの正当性をチェックし、もし ハンドルが不当 であれば、インジケーターの計算には少し時間がかかるため、それを作成してファンクションから出る。これはインジケーターのバッファーからデータをコピーするのにエラーを避けるため実装される。

if(h_ma1==INVALID_HANDLE)//--- if the handle is invalid
     {
      //--- create it again                                                      
      h_ma1=iMA(Symbol(),Period(),8,0,MODE_SMA,PRICE_CLOSE);
      //--- exit from the function
      return(0);
     }

もしハンドルが正当であれば、配列のデータをコピーする。状況を解析するため、早いMAでは最新の3つのバー、遅いものでは2つのバーのデータをコピーすれば十分である。この目的のために次のファンクションを用いる。

int  CopyBuffer(
   int       indicator_handle,     // handle of an indicator
   int       buffer_num,           // number of buffer of an indicator
   int       start_pos,            // where to start from 
   int       count,                // amount to be copied
   double    buffer[]              // an array to copy data to
   );

これらをチェックする。もし要求より少ないデータしかない場合、コピーのエラーがが起こったことを意味する;そしてさらにデータが入っているべき配列を参照することはエラーに導く。これを避けるために、 ファンクションから抜け出る。また、 時系列のような配列のインデックス付け を設定する必要があり、次のファンクションがそれを目的とする。

bool  ArraySetAsSeries(
   void  array[],     // array by a link
   bool  set          // true means that the indexation order is reversed
   );

配列のインデックス付けの間にもしエラーが起こると、ファンクションから出る、さもないと正しくない結果を得る可能性がある。

else //--- if the handle is valid 
     {
      //--- copy values of the indicator to the array
      if(CopyBuffer(h_ma1,0,0,3,ma1_buffer)<3) //--- if there is less data than required
         //--- exit from the function
         return(0);
      //--- set the indexation in the array like in a timeseries                                   
      if(!ArraySetAsSeries(ma1_buffer,true))
         //--- in case of an indexation error, exit from the function
         return(0);
     }

さて、インジケーターが作成され、必要な情報が得られたので、主なステージ であるシグナルの形成 に進もう。

現在のバーにおける信号が揺らぐのをなくすため、近い第1と第2のバーのみを解析する。

買いのシグナルから。この目的のために、第2のバーで速いMAの値をとり、そしてそれを第2バーの遅いMAの値と比較する;そして第1バーでの速いMAの値を第1バーの遅いMAの値と比較する。もし第2のバーで速いMAの値が第2バーの遅いMAの値より小さく、そしてそして第1バーでの速いMAの値が第1バーの遅いMAの値より大きい場合、これは速いMAは遅いものを上方にまたいでいることを意味する;これは買いのシグナルである。もし条件が true であれば、1をsig 変数に書く。

同様の方法で形成される売りのlシグナル。もし第2のバーで速いMAの値が第2バーの遅いMAの値より大きく、そしてそして第1バーでの速いMAの値が第1バーの遅いMAの値より小さい場合、これは速いMAは遅いものを下方にまたいでいることを意味する。もし条件が‘true ならば値 -1 をsig variable に書く。もしどちらの条件もfalse であるならシグナルはないことを意味し、値 0 を sig 変数に書く。これでシグナルは形成されたので得られたシグナルのタイプをTradeSignal_01()ファンクションに入れ戻る。

//--- check the condition and set a value for the sig
   if(ma1_buffer[2]<ma2_buffer[1] && ma1_buffer[1]>ma2_buffer[1])
      sig=1;
   else if(ma1_buffer[2]>ma2_buffer[1] && ma1_buffer[1]<ma2_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);

3.2. 主ラインと MACDのシグナルラインの交差

図 2. 主ラインとMACD インジケーターのラインの交差

TradeSignal_02() ファンクションで主ラインとMACD インジケーターのラインの交差についての信号を得る。この信号ラインが主ラインを上から下に横切ったときには、買いのシグナルである。この信号ラインが主ラインを下から上に横切ったときには、売りのシグナルである。. シグナルが無いときには他のケースが考えられる。

int TradeSignal_02()
  {
   int sig=0;

   if(h_macd==INVALID_HANDLE)
     {
      h_macd=iMACD(Symbol(),Period(),12,26,9,PRICE_CLOSE);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_macd,0,0,2,macd1_buffer)<2)
         return(0);
      if(CopyBuffer(h_macd,1,0,3,macd2_buffer)<3)
         return(0);
      if(!ArraySetAsSeries(macd1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(macd2_buffer,true))
         return(0);
     }

//--- check the condition and set a value for sig
   if(macd2_buffer[2]>macd1_buffer[1] && macd2_buffer[1]<macd1_buffer[1])
      sig=1;
   else if(macd2_buffer[2]<macd1_buffer[1] && macd2_buffer[1]>macd1_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.3.

図 3. 価格帯の突破点

TradeSignal_03()ファンクションで価格帯の上下の限界値の突破時についてのシグナルを受け取る。

もし価格が価格帯の上の限界点を突き抜け、価格がこの境界の上に留まるなら、買いのシグナルである。もし価格が価格帯の下の極値を下回り、価格がこの境界の下に留まるなら、売りのシグナルである。シグナルが無いときには他のケースが考えられる。

前の2つのファンクションと異なり、ここで大引け価格を保存する配列を必要とする。 次のファンクションがそれを得る:

int  CopyClose(
   string           symbol_name,       // symbol name
   ENUM_TIMEFRAMES  timeframe,          // period
   int              start_pos,         // where to start from 
   int              count,             // amount to be copied
   double           close_array[]      // array for copying close prices to
   );
int TradeSignal_03()
  {
   int sig=0;

   if(h_pc==INVALID_HANDLE)
     {
      h_pc=iCustom(Symbol(),Period(),"Price Channel",22);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_pc,0,0,3,pc1_buffer)<3)
         return(0);
      if(CopyBuffer(h_pc,1,0,3,pc2_buffer)<3)
         return(0);
      if(CopyClose(Symbol(),Period(),0,2,Close)<2)
         return(0);
      if(!ArraySetAsSeries(pc1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(pc2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the conditions and set a value for sig
   if(Close[1]>pc1_buffer[2])
      sig=1;
   else if(Close[1]<pc2_buffer[2])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.4. ADX適応帯の突破点

図 4. ADX適応帯の突破点

TradeSignal_04()ファンクションを用いてADX適応帯の上下の境界の突破時についてのシグナルを得る。

もし価格がADX適応帯の幅の上の境界を突き抜け大引け価格がその境界の上に留まるなら買いのシグナルである。もし価格がADX適応帯の幅の下の境界を突き抜け大引け価格がその境界の下に留まるなら売りのシグナルである。シグナルが無いときには他のケースが考えられる。

int TradeSignal_04()
  {
   int sig=0;

   if(h_acadx==INVALID_HANDLE)
     {
      h_acadx=iCustom(Symbol(),Period(),"AdaptiveChannelADX",14);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_acadx,0,0,2,acadx1_buffer)<2)
         return(0);
      if(CopyBuffer(h_acadx,1,0,2,acadx2_buffer)<2)
         return(0);
      if(CopyClose(Symbol(),Period(),0,2,Close)<2)
         return(0);
      if(!ArraySetAsSeries(acadx1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(acadx2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for the sig
   if(Close[1]>acadx1_buffer[1])
      sig=1;
   else if(Close[1]<acadx2_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.5. 統計上の大買い/大売りゾーンから外れる

図 5. 統計による大買いと大売りのレベルを越える。

TradeSignal_05()を用いて大買い/大売りのゾーンからの統計から外れることについてシグナルを得る; それらのゾーンのレベルは80と20の値のレベルである。

発振器 (%K あるいは %D) があるレベルを下回り (通常それは20) そしてそれ以上に立ち上がったときには、買う。発振器 があるレベルを上回り (通常それは80) そしてそれ以下に落ちたときには、売る。

int TradeSignal_05()
  {
   int sig=0;

   if(h_stoh==INVALID_HANDLE)
     {
      h_stoh=iStochastic(Symbol(),Period(),5,3,3,MODE_SMA,STO_LOWHIGH);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_stoh,0,0,3,stoh_buffer)<3)
         return(0);

      if(!ArraySetAsSeries(stoh_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(stoh_buffer[2]<20 && stoh_buffer[1]>20)
      sig=1;
   else if(stoh_buffer[2]>80 && stoh_buffer[1]<80)
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.6. RSIの大買い/大売りゾーンから外れる

図 6. RSIインジケーターによる大買いと大売りレベルを越える

TradeSignal_06() ファンクションを用いて、RSIインジケーターが 大買い/大売りのゾーンから外れるというシグナルを得る;そのゾーンのレベルは 70と30 のレベルである。

RSI が特定のレベルより下落し (通常それは30) そしてそれの上まで上ったなら、買い 。RSI が特定のレベルより高く登り (通常それは70) そしてその下まで落ちたなら、売り 。

int TradeSignal_06()
  {
   int sig=0;

   if(h_rsi==INVALID_HANDLE)
     {
      h_rsi=iRSI(Symbol(),Period(),14,PRICE_CLOSE);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_rsi,0,0,3,rsi_buffer)<3)
         return(0);

      if(!ArraySetAsSeries(rsi_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(rsi_buffer[2]<30 && rsi_buffer[1]>30)
      sig=1;
   else if(rsi_buffer[2]>70 && rsi_buffer[1]<70)
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
 

3.7. CCIの大買い/大売りゾーンから外れる

図 7. CCIインジケーターによる大買いと大売りレベルを越える

TradeSignal_07() ファンクションを用いて、CCIインジケーターが 大買い/大売りのゾーンから外れるというシグナルを得る;そのゾーンのレベルは 100と-100 の値を持つレベルである。

CCI が-100レベルより下落し そしてその上まで上ったなら、買い 。CCI が100レベルより上に 登りそしてその下まで落ちたなら、売り

int TradeSignal_07()
  {
   int sig=0;

   if(h_cci==INVALID_HANDLE)
     {
      h_cci=iCCI(Symbol(),Period(),14,PRICE_TYPICAL);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_cci,0,0,3,cci_buffer)<3)
         return(0);

      if(!ArraySetAsSeries(cci_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(cci_buffer[2]<-100 && cci_buffer[1]>-100)
      sig=1;
   else if(cci_buffer[2]>100 && cci_buffer[1]<100)
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.8. Williamsの大買い/大売りゾーンから外れる

図 8. Williamsインジケーターによる大買いと大売りレベルを越える

TradeSignal_08() ファンクションを用いて、Williamsインジケーターが 大買い/大売りのゾーンから外れるというシグナルを得る;そのゾーンのレベルは -20と-80 のレベルである。

Williams が-80レベルより下落し そしてその上まで登ったなら、買い 。Williams が-20レベルより上に 登りそしてその下まで落ちたなら、売り

int TradeSignal_08()
  {
   int sig=0;

   if(h_wpr==INVALID_HANDLE)
     {
      h_wpr=iWPR(Symbol(),Period(),14);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_wpr,0,0,3,wpr_buffer)<3)
         return(0);

      if(!ArraySetAsSeries(wpr_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(wpr_buffer[2]<-80 && wpr_buffer[1]>-80)
      sig=1;
   else if(wpr_buffer[2]>-20 && wpr_buffer[1]<-20)
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }
3.9. Bolingerチャンネルの境界から跳ね返り

図 9. Bolingerチャンネルの境界から価格の跳ね返り

TradeSignal_09() ファンクションを用いBolingerチャンネルの境界から価格が跳ね返った時のシグナルを得る。

もし価格がBolingerの上の境界を突き抜けあるいは接触し、そして戻ったなら、それは売りのシグナル。もし価格がBolingerの下の境界を突き抜けあるいは接触し、そして戻ったなら、それは買いのシグナル

int TradeSignal_09()
  {
   int sig=0;

   if(h_bb==INVALID_HANDLE)
     {
      h_bb=iBands(Symbol(),Period(),20,0,2,PRICE_CLOSE);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_bb,1,0,2,bb1_buffer)<2)
         return(0);
      if(CopyBuffer(h_bb,2,0,2,bb2_buffer)<2)
         return(0);
      if(CopyClose(Symbol(),Period(),0,3,Close)<3)
         return(0);
      if(!ArraySetAsSeries(bb1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(bb2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(Close[2]<=bb2_buffer[1] && Close[1]>bb2_buffer[1])
      sig=1;
   else if(Close[2]>=bb1_buffer[1] && Close[1]<bb1_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.10. 標準偏差チャンネルの境界から跳ね返り

図 10. 標準偏差チャンネル
の境界から価格の跳ね返り

TradeSignal_10() ファンクションを用い標準偏差チャンネルの境界から価格が跳ね返った時のシグナルを得る。

もし価格が標準偏差の上の境界を突き抜けあるいは接触しそして戻ったなら、それは売りのシグナル。もし価格が標準偏差の下の境界を突き抜けあるいは接触しそして戻ったなら、それは買いのシグナル

int TradeSignal_10()
  {
   int sig=0;

   if(h_sdc==INVALID_HANDLE)
     {
      h_sdc=iCustom(Symbol(),Period(),"StandardDeviationChannel",14,0,MODE_SMA,PRICE_CLOSE,2.0);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_sdc,0,0,2,sdc1_buffer)<2)
         return(0);
      if(CopyBuffer(h_sdc,1,0,2,sdc2_buffer)<2)
         return(0);
      if(CopyClose(Symbol(),Period(),0,3,Close)<3)
         return(0);
      if(!ArraySetAsSeries(sdc1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(sdc2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(Close[2]<=sdc2_buffer[1] && Close[1]>sdc2_buffer[1])
      sig=1;
   else if(Close[2]>=sdc1_buffer[1] && Close[1]<sdc1_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.11. 価格帯の境界から跳ね返り

図 11. 価格帯の境界から価格の跳ね返り

TradeSignal_11() ファンクションを用い価格帯の境界から価格が跳ね返った時のシグナルを得る。

もし価格が価格帯の上の境界を突き抜けあるいは接触しそして戻ったなら、それは売りのシグナル。もし価格が価格帯の下の境界を突き抜けあるいは接触しそして戻ったなら、それは買いのシグナル

int TradeSignal_11()
  {
   int sig=0;

   if(h_pc==INVALID_HANDLE)
     {
      h_pc=iCustom(Symbol(),Period(),"Price Channel",22);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_pc,0,0,4,pc1_buffer)<4)
         return(0);
      if(CopyBuffer(h_pc,1,0,4,pc2_buffer)<4)
         return(0);
      if(CopyClose(Symbol(),Period(),0,3,Close)<3)
         return(0);
      if(!ArraySetAsSeries(pc1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(pc2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(Close[1]>pc2_buffer[2] && Close[2]<=pc2_buffer[3])
      sig=1;
   else if(Close[1]<pc1_buffer[2] && Close[2]>=pc1_buffer[3])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.12. 包絡線チャンネルの境界から跳ね返り

図 12. 包絡線チャンネルの境界から価格の跳ね返り

TradeSignal_12() ファンクションを用い包絡線チャンネルの境界から価格が跳ね返った時のシグナルを得る。

もし価格が包絡線チャンネルの上の境界を突き抜けあるいは接触しそして戻ったなら、それは売りのシグナル。もし価格が包絡線チャンネルの下の境界を突き抜けあるいは接触しそして戻ったなら、それは買いのシグナル

int TradeSignal_12()
  {
   int sig=0;

   if(h_env==INVALID_HANDLE)
     {
      h_env=iEnvelopes(Symbol(),Period(),28,0,MODE_SMA,PRICE_CLOSE,0.1);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_env,0,0,2,env1_buffer)<2)
         return(0);
      if(CopyBuffer(h_env,1,0,2,env2_buffer)<2)
         return(0);
      if(CopyClose(Symbol(),Period(),0,3,Close)<3)
         return(0);
      if(!ArraySetAsSeries(env1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(env2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(Close[2]<=env2_buffer[1] && Close[1]>env2_buffer[1])
      sig=1;
   else if(Close[2]>=env1_buffer[1] && Close[1]<env1_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.13. Donchian チャンネルの突破

図 13. Donchianチャンネルの境界の突破

TradeSignal_13() ファンクションを用いDonchianチャンネルの境界を価格の突破時のシグナルを得る。

もし価格がDonchianチャンネルの上の境界を突き抜け大引け価格がその境界の上に留まったなら、それは買いのシグナルである。もし価格がDonchianチャンネルの下の境界を突き抜け大引け価格がその境界の下に留まったなら、それは売りのシグナルである。

int TradeSignal_13()
  {
   int sig=0;

   if(h_dc==INVALID_HANDLE)
     {
      h_dc=iCustom(Symbol(),Period(),"Donchian Channels",24,3,-2);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_dc,0,0,3,dc1_buffer)<3)
         return(0);
      if(CopyBuffer(h_dc,1,0,3,dc2_buffer)<3)
         return(0);
      if(CopyClose(Symbol(),Period(),0,2,Close)<2)
         return(0);
      if(!ArraySetAsSeries(dc1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(dc2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(Close[1]>dc1_buffer[2])
      sig=1;
   else if(Close[1]<dc2_buffer[2])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.14. Silver チャンネルの突き抜け

図 14. Silverチャンネルの境界を突き抜ける

In the TradeSignal_14() ファンクションを用いSilverチャンネルの境界を価格が突き抜けた時のシグナルを得る。Silverチャンネルのインジケーターは8本の境界を引きそれが保持と抵抗のレベルとして働く。 シグナルを得るために真ん中の2本の境界を用いる

もし価格がSilverチャンネルの上の境界を突き抜け大引け価格がその境界の上に留まったなら、それは買いのシグナルである。もし価格がSilverチャンネルの下の境界を突き抜け大引け価格がその境界の下に留まったなら、それは売りのシグナルである。

int TradeSignal_14()
  {
   int sig=0;

   if(h_sc==INVALID_HANDLE)
     {
      h_sc=iCustom(Symbol(),Period(),"Silver-channels",26,38.2,23.6,0,61.8);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_sc,0,0,2,sc1_buffer)<2)
         return(0);
      if(CopyBuffer(h_sc,1,0,2,sc2_buffer)<2)
         return(0);
      if(CopyClose(Symbol(),Period(),0,3,Close)<3)
         return(0);
      if(!ArraySetAsSeries(sc1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(sc2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(Close[2]<sc1_buffer[1] && Close[1]>sc1_buffer[1])
      sig=1;
   else if(Close[2]>sc2_buffer[1] && Close[1]<sc2_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.15. Gallagher チャンネルの突き抜け

図 15. Gallagherチャンネルの境界を突き抜ける

TradeSignal_15() ファンクションを用いGallagherチャンネルの境界を価格が突き抜けた時のシグナルを得る。Gallagher チャンネルのインジケーターは10日間の最大と最小で描かれる。

もし価格がGallagherチャンネルの上の境界を突き抜け大引け価格がその境界の上に留まったなら、それは買いのシグナルである。もし価格がGallagherチャンネルの下の境界を突き抜け大引け価格がその境界の下に留まったなら、それは売りのシグナルである。

int TradeSignal_15()
  {
   int sig=0;

   if(h_gc==INVALID_HANDLE)
     {
      h_gc=iCustom(Symbol(),Period(),"PriceChannelGalaher");
      return(0);
     }
   else
     {
      if(CopyBuffer(h_gc,0,0,3,gc1_buffer)<3)
         return(0);
      if(CopyBuffer(h_gc,1,0,3,gc2_buffer)<3)
         return(0);
      if(CopyClose(Symbol(),Period(),0,2,Close)<2)
         return(0);
      if(!ArraySetAsSeries(gc1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(gc2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(Close[1]>gc1_buffer[2])
      sig=1;
   else if(Close[1]<gc2_buffer[2])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.16. NRTRのトレンドの変化

図 16. NRTRインジケーターを用いるトレンド変化の識別

TradeSignal_16()ファンクションにおいてNRTRトレンドが変化したときのシグナルを得る。

もし NRTR インジケーターが上昇トレンドを示したなら、それは買いのシグナルである。もし NRTR インジケーターが下降トレンドを示したなら、それは売りのシグナルである。

int TradeSignal_16()
  {
   int sig=0;

   if(h_nrtr==INVALID_HANDLE)
     {
      h_nrtr=iCustom(Symbol(),Period(),"NRTR",40,2.0);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_nrtr,0,0,2,nrtr1_buffer)<2)
         return(0);
      if(CopyBuffer(h_nrtr,1,0,2,nrtr2_buffer)<2)
         return(0);
      if(!ArraySetAsSeries(nrtr1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(nrtr2_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(nrtr1_buffer[1]>0)
      sig=1;
   else if(nrtr2_buffer[1]>0)
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.17. Alligatorのトレンドの変化

図 17. Alligatorのトレンドの変化

TradeSignal_17()ファンクションにおいてAlligatorトレンドが変化したときのシグナルを得る。

もし顎、歯と唇が閉じてねじれていれば、Alligatorは眠る、あるいは既に寝ている状態である。それが眠ると、空腹が募り、そしてさらに眠る、目覚めたときにはさらに空腹である。目覚めたときに最初にすることは口を開けあくびをすることである。そして食べ物の匂いを嗅ぐようになり - 牛あるいはクマの肉, そしてそれを狩に出かける。十分に食べたとたんに、食物(価格)への関心を失い(バランスラインが収束する);それは利得を治すときである。

int TradeSignal_17()
  {
   int sig=0;

   if(h_al==INVALID_HANDLE)
     {
      h_al=iAlligator(Symbol(),Period(),13,0,8,0,5,0,MODE_SMMA,PRICE_MEDIAN);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_al,0,0,2,al1_buffer)<2)
         return(0);
      if(CopyBuffer(h_al,1,0,2,al2_buffer)<2)
         return(0);
      if(CopyBuffer(h_al,2,0,2,al3_buffer)<2)
         return(0);
      if(!ArraySetAsSeries(al1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(al2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(al3_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(al3_buffer[1]>al2_buffer[1] && al2_buffer[1]>al1_buffer[1])
      sig=1;
   else if(al3_buffer[1]<al2_buffer[1] && al2_buffer[1]<al1_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.18. AMAのトレンドの変化

図 18. AMAのトレンドの変化

TradeSignal_18()ファンクションにおいて AMAトレンドが変化したときのシグナルを得る。

もしAMAインジケーターが上昇に向いたなら、それは買いのシグナルである。もしAMAインジケーターが下降に向いたなら、それは売りのシグナルである。

int TradeSignal_18()
  {
   int sig=0;

   if(h_ama==INVALID_HANDLE)
     {
      h_ama=iAMA(Symbol(),Period(),9,2,30,0,PRICE_CLOSE);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_ama,0,0,3,ama_buffer)<3)
         return(0);
      if(!ArraySetAsSeries(ama_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(ama_buffer[2]<ama_buffer[1])
      sig=1;
   else if(ama_buffer[2]>ama_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.19. Awesome Oscillatorの色の変化

図 19. Awesome Oscillatorインジケーターを用いるトレンド変化の識別

TradeSignal_19() ファンクションにおいてAwesome Oscillatorのヒストグラムの色が変化したときのシグナルを得る。

MQL5の特徴の一つはインジケーターのバッファーを作成する可能性であり、そこで#property indicator_colorNのプロパティに設定されるラインの色のインデックスを保存できる。もし Awesome Oscillator のヒストグラムの色が緑なら、それは買いのシグナルである。もしその色が赤なら、それは売りのシグナルである。

int TradeSignal_19()
  {
   int sig=0;

   if(h_ao==INVALID_HANDLE)
     {
      h_ao=iAO(Symbol(),Period());
      return(0);
     }
   else
     {
      if(CopyBuffer(h_ao,1,0,20,ao_buffer)<20)
         return(0);
      if(!ArraySetAsSeries(ao_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(ao_buffer[1]==0)
      sig=1;
   else if(ao_buffer[1]==1)
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.20. Ichimokuのトレンドの変化

図 20. Ichimokuインジケーターを用いるトレンド変化の識別

TradeSignal_20()ファンクションにおいてIchimokuトレンドが変化したときのシグナルを得る。この目的のために転換線と基準線の交差を解析する。

買いのシグナルは転換線が基準線を下から上に交差したときに発生する。上から下への交差は売りのシグナルである。

int TradeSignal_20()
  {
   int sig=0;

   if(h_ich==INVALID_HANDLE)
     {
      h_ich=iIchimoku(Symbol(),Period(),9,26,52);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_ich,0,0,2,ich1_buffer)<2)
         return(0);
      if(CopyBuffer(h_ich,1,0,2,ich2_buffer)<2)
         return(0);
      if(!ArraySetAsSeries(ich1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(ich2_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(ich1_buffer[1]>ich2_buffer[1])
      sig=1;
   else if(ich1_buffer[1]<ich2_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }


4. インジケーターを完成させる

これで、インジケーターのための出来合いのブロックがあるので、全ての選択した方法をベースとしたシグナルを示すインジケーターを書き始めることができる。作成したテンプレートを用いてどのインジケーターからのシグナルでも受け取る処理を実装し、シグナルの条件を正しく形成し、コードに加えるのに十分な処理を書く。

組み込みのパラメーターを用いて、インジケーターを書こう。インジケーターのシグナルは矢印の形で(上向き矢印 - 買い、下向き - 売り、バツ印 - シグナル無し)チャートの正しい場所に描かれる。標準のWingdingsフォントを矢印を書くために採用する。 またチャート上のシグナルについての情報を表示するいくつかの他のファンクションを作成する必要がある。これらをライブラリとしてまとめて分離したブロックにし、それに新しいファンクションを加えて自身のプログラムを書くために用いることができる。このライブラリをLibFunctions と名付けよう。

将来のインジケーターのヘッダーに、シグナルを発生させるファンクションとシグナルのグラフィック表示に必要な重要なファンクション のファイルへの接続を書き、またインジケーターから受け取るシグナルのタイプを保存するglobal scape 上の変数を宣言する。

//--- Connect necessary libraries of functions
#include <SignalTrade.mqh>
//--- Import of functions from the LibFunctions library
#import "LibFunctions.ex5"
void SetLabel(string nm,string tx,ENUM_BASE_CORNER cn,ENUM_ANCHOR_POINT cr,int xd,int yd,string fn,int fs,double yg,color ct);
string arrow(int sig);
color Colorarrow(int sig);
#import
//+------------------------------------------------------------------+
//| Declare variables for storing signals of indicators              |
//+------------------------------------------------------------------+
int SignalMA;
int SignalMACD;
int SignalPC;
int SignalACADX;
int SignalST;
int SignalRSI;
int SignalCCI;
int SignalWPR;
int SignalBB;
int SignalSDC;
int SignalPC2;
int SignalENV;
int SignalDC;
int SignalSC;
int SignalGC;
int SignalNRTR;
int SignalAL;
int SignalAMA;
int SignalAO;
int SignalICH;

前に述べたように、インジケーターは一度だけ端末にロードされそしてそのインジケーターへのポインター(ハンドル)が作成される;これが作成したものを OnInit()ファンクションに実装する理由であり、このファンクションはプログラムのスタート時に一度だけ走るのである。

int OnInit()
  {
//--- create indicator handles
   h_ma1=iMA(Symbol(),Period(),8,0,MODE_SMA,PRICE_CLOSE);
   h_ma2=iMA(Symbol(),Period(),16,0,MODE_SMA,PRICE_CLOSE);
   h_macd=iMACD(Symbol(),Period(),12,26,9,PRICE_CLOSE);
   h_pc=iCustom(Symbol(),Period(),"Price Channel",22);
   h_acadx=iCustom(Symbol(),Period(),"AdaptiveChannelADX",14);
   h_stoh=iStochastic(Symbol(),Period(),5,3,3,MODE_SMA,STO_LOWHIGH);
   h_rsi=iRSI(Symbol(),Period(),14,PRICE_CLOSE);
   h_cci=iCCI(Symbol(),Period(),14,PRICE_TYPICAL);
   h_wpr=iWPR(Symbol(),Period(),14);
   h_bb=iBands(Symbol(),Period(),20,0,2,PRICE_CLOSE);
   h_sdc=iCustom(Symbol(),Period(),"StandardDeviationChannel",14,0,MODE_SMA,PRICE_CLOSE,2.0);
   h_env=iEnvelopes(Symbol(),Period(),28,0,MODE_SMA,PRICE_CLOSE,0.1);
   h_dc=iCustom(Symbol(),Period(),"Donchian Channels",24,3,-2);
   h_sc=iCustom(Symbol(),Period(),"Silver-channels",26,38.2,23.6,0,61.8);
   h_gc=iCustom(Symbol(),Period(),"PriceChannelGalaher");
   h_nrtr=iCustom(Symbol(),Period(),"NRTR",40,2.0);
   h_al=iAlligator(Symbol(),Period(),13,0,8,0,5,0,MODE_SMMA,PRICE_MEDIAN);
   h_ama=iAMA(Symbol(),Period(),9,2,30,0,PRICE_CLOSE);
   h_ao=iAO(Symbol(),Period());
   h_ich=iIchimoku(Symbol(),Period(),9,26,52);
   return(0);
  }

主な計算の全ては OnCalculate()ファンクションで実行され、そこに残るインジケーター のコードを置くのである。

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[])
  {
//---assign the signal value to the variable
   SignalMA    = TradeSignal_01();
   SignalMACD  = TradeSignal_02();
   SignalPC    = TradeSignal_03();
   SignalACADX = TradeSignal_04();
   SignalST    = TradeSignal_05();
   SignalRSI   = TradeSignal_06();
   SignalCCI   = TradeSignal_07();
   SignalWPR   = TradeSignal_08();
   SignalBB    = TradeSignal_09();
   SignalSDC   = TradeSignal_10();
   SignalPC2   = TradeSignal_11();
   SignalENV   = TradeSignal_12();
   SignalDC    = TradeSignal_13();
   SignalSC    = TradeSignal_14();
   SignalGC    = TradeSignal_15();
   SignalNRTR  = TradeSignal_16();
   SignalAL    = TradeSignal_17();
   SignalAMA   = TradeSignal_18();
   SignalAO    = TradeSignal_19();
   SignalICH   = TradeSignal_20();

//--- draw graphical objects on the chart in the upper left corner
   int size=((int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS)/22);
   int i=0;
   int x=10;
   int y=0;
   int fz=size-4;

   y+=size;
   SetLabel("arrow"+(string)i,arrow(SignalMA),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalMA));
   x+=size;
   SetLabel("label"+(string)i,"Moving Average",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalMACD),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalMACD));
   x+=size;
   SetLabel("label"+(string)i,"MACD",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalPC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalPC));
   x+=size;
   SetLabel("label"+(string)i,"Price Channell",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalACADX),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalACADX));
   x+=size;
   SetLabel("label"+(string)i,"Adaptive Channel ADX",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalST),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalST));
   x+=size;
   SetLabel("label"+(string)i,"Stochastic Oscillator",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalRSI),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalRSI));
   x+=size;
   SetLabel("label"+(string)i,"RSI",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalCCI),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalCCI));
   x+=size;
   SetLabel("label"+(string)i,"CCI",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalWPR),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalWPR));
   x+=size;
   SetLabel("label"+(string)i,"WPR",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalBB),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalBB));
   x+=size;
   SetLabel("label"+(string)i,"Bollinger Bands",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalSDC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalSDC));
   x+=size;
   SetLabel("label"+(string)i,"StDevChannel",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalPC2),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalPC2));
   x+=size;
   SetLabel("label"+(string)i,"Price Channell 2",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalENV),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalENV));
   x+=size;
   SetLabel("label"+(string)i,"Envelopes",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalDC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalDC));
   x+=size;
   SetLabel("label"+(string)i,"Donchian Channels",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalSC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalSC));
   x+=size;
   SetLabel("label"+(string)i,"Silver-channels",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalGC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalGC));
   x+=size;
   SetLabel("label"+(string)i,"Galaher Channel",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalNRTR),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalNRTR));
   x+=size;
   SetLabel("label"+(string)i,"NRTR",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalAL),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalAL));
   x+=size;
   SetLabel("label"+(string)i,"Alligator",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalAMA),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalAMA));
   x+=size;
   SetLabel("label"+(string)i,"AMA",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalAO),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalAO));
   x+=size;
   SetLabel("label"+(string)i,"Awesome oscillator",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalICH),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalICH));
   x+=size;
   SetLabel("label"+(string)i,"Ichimoku Kinko Hyo",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);

   return(rates_total);
  }

さて、インジケーターの準備ができた。最後に次の図をチャートに載せる。


5. エキスパートアドバイザーを作成する

同様の方法でインジケーターのシグナルをチャート上に示すエキスパートアドバイザーを書くことができる。グラフィックな制御する情報システムを実装しよう。必要なインジケーターを選択しそしてそのパラメーターをグラフィカルインターフェースを通じて設定することができる。

ここではグラフィカルインターフェースの実装については述べない。その情報は Creating Active Control Panels in MQL5 for Trading の記事の中で得ることができる。

グラフィカルインターフェースを通じてインジケーターの設定を変更するには、SignalTrade.mqh library を改良し、それを SignalTradeExp.mqh と名付けよう。

まず最初に、インジケーターの設定を保存する追加の変数を必要とする。

//--- input parameters Moving Average
int                periodma1=8;
int                periodma2=16;
ENUM_MA_METHOD     MAmethod=MODE_SMA;
ENUM_APPLIED_PRICE MAprice=PRICE_CLOSE;
//--- input parameters MACD
int                FastMACD=12;
int                SlowMACD=26;
int                MACDSMA=9;
ENUM_APPLIED_PRICE MACDprice=PRICE_CLOSE;
//--- input parameters Price Channel
int                PCPeriod=22;
//--- input parameters Adaptive Channel ADX
int                ADXPeriod=14;
//--- input parameters Stochastic Oscillator
int                SOPeriodK=5;
int                SOPeriodD=3;
int                SOslowing=3;
ENUM_MA_METHOD     SOmethod=MODE_SMA;
ENUM_STO_PRICE     SOpricefield=STO_LOWHIGH;
//--- input parameters RSI
int                RSIPeriod=14;
ENUM_APPLIED_PRICE RSIprice=PRICE_CLOSE;
//--- input parameters CCI
int                CCIPeriod=14;
ENUM_APPLIED_PRICE CCIprice=PRICE_TYPICAL;
//--- input parameters WPR
int                WPRPeriod=14;
//--- input parameters Bollinger Bands
int                BBPeriod=20;
double             BBdeviation=2.0;
ENUM_APPLIED_PRICE BBprice=PRICE_CLOSE;
//--- input parameters Standard Deviation Channel
int                SDCPeriod=14;
double             SDCdeviation=2.0;
ENUM_APPLIED_PRICE SDCprice=PRICE_CLOSE;
ENUM_MA_METHOD     SDCmethod=MODE_SMA;
//--- input parameters Price Channel 2
int                PC2Period=22;
//--- input parameters Envelopes
int                ENVPeriod=14;
double             ENVdeviation=0.1;
ENUM_APPLIED_PRICE ENVprice=PRICE_CLOSE;
ENUM_MA_METHOD     ENVmethod=MODE_SMA;
//--- input parameters Donchian Channels
int                DCPeriod=24;
int                DCExtremes=3;
int                DCMargins=-2;
//--- input parameters Silver-channels
int                SCPeriod=26;
double             SCSilvCh=38.2;
double             SCSkyCh=23.6;
double             SCFutCh=61.8;
//--- input parameters NRTR
int                NRTRPeriod   =  40;
double             NRTRK        =  2.0;
//--- input parameters Alligator
int                ALjawperiod=13;
int                ALteethperiod=8;
int                ALlipsperiod=5;
ENUM_MA_METHOD     ALmethod=MODE_SMMA;
ENUM_APPLIED_PRICE ALprice=PRICE_MEDIAN;
//--- input parameters AMA
int                AMAperiod=9;
int                AMAfastperiod=2;
int                AMAslowperiod=30;
ENUM_APPLIED_PRICE AMAprice=PRICE_CLOSE;
//--- input parameters Ichimoku Kinko Hyo
int                IKHtenkansen=9;
int                IKHkijunsen=26;
int                IKHsenkouspanb=52;

インジケーターの定数値を変数に置き換える。他のものは変えずに残しておく。

h_ma1=iMA(Symbol(),Period(),periodma1,0,MAmethod,MAprice);

重要な観点はコンピュータメモリーの経済的な使用であり、設定を変更したとき古い設定のインジケーターのコピーをアンロードし、新しいインジケーターをロードする。以下のファンクションがそのような処理を実行します。:

bool  IndicatorRelease(
   int       indicator_handle,     // indicator handle
   );
if(id==CHARTEVENT_OBJECT_ENDEDIT && sparam=="PIPSetEditMA2")
     {
      periodma2=(int)ObjectGetString(0,"PIPSetEditMA2",OBJPROP_TEXT);
      ObjectSetString(0,"PIPSetEditMA2",OBJPROP_TEXT,(string)periodma2);
      //--- unload old copy of the indicator
      IndicatorRelease(h_ma2);
      //--- create new copy of the indicator
      h_ma2=iMA(Symbol(),Period(),periodma2,0,MAmethod,MAprice);
      ChartRedraw();
     }


結論

こうして、インジケーターからの情報を読む方法とそれをエキスパートアドバイザーに渡す方法を学んだ。そのようなやりかたで、どのインジケーターからのシグナルでも得ることができる。

ノート

  • SignalTrade.mq5、 AdaptiveChannelADX.mq5、 Donchian Channels.mq5、 NRTR.mq5、 Price Channel.mq5、 PriceChannelGalaher.mq5、 Silver-channels.mq5、StandardDeviationChannel.mq5 インジケーター のファイルは ...\MQL5\Indicators フォルダーにコピーされたはずである。
  • SignalTrade.mqh と SignalTradeExp.mqh のインクルードファイルは ...\MQL5\Include フォルダーにコピーされたはずである。
  • LibFunctions.mq5 のファンクションライブラリは ...\MQL5\Libraries フォルダーにコピーされたはずである。
  • ExpSignalTrade.mq5 エキスパートアドバイザーは ...\MQL5\Experts にコピーされたはずである。

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

添付されたファイル |
indicators.zip (8.9 KB)
expsignaltrade.mq5 (165.84 KB)
signaltrade.mq5 (10.57 KB)
signaltrade.mqh (20.16 KB)
signaltradeexp.mqh (23.26 KB)
トレードロボットのプロトタイプ トレードロボットのプロトタイプ
この論説ではトレーディングシステムのアルゴリズムと要素の作成の原理を要約しシステム化する。この論説はエキスパートアルゴリズムの設計について考察する。トレーディングシステムCExpertAdvisor クラスのある例について考察する。これはトレーディングシステムを素早く簡単に開発するのに使える。
エキスパートアドバイザーの資金管理のためのファンクション エキスパートアドバイザーの資金管理のためのファンクション
トレード戦略の開発は主に市場に入り、そして、出るためのパターンの探索と、ポジションの維持に注目している。もし自動トレーディングのためにあるパターンをルールとして形式化できれば、トレーダーはポジションの量、マージンのサイズを計算する問題に立ち向かい、さらに貸付資金の安全なレベルを維持して自動モードでオープンなポジションを確実にするであろう。この論説では MQL5 言語を用いてこれらの計算を行う簡単な例を構築する
独自のトレーリングストップ注文を作成する方法 独自のトレーリングストップ注文を作成する方法
トレーダーの基本原則 - 利得を増やし、損失を削る!この論説では基本技術の一つ、この原則に従うことを可能にする - 保護的停止レベル (ストップ・ロスレベル) をポジションの利得が増大した時点で動かす、すなわちトレーリングストップレベルを考察する。ここではSAR と NRTR インジケーターに基づいてトレーリングストップをするためのクラスを作成する手続きをステップを追って示す。誰でもこのトレーリングストップをそのエキスパートに挿入し、あるいは独立にそれをそのアカウントのポジションを制御するために使用することができる。
スタンダードライブラリーのクラスとグーグルチャートAPIを用いて情報ボードを生成する スタンダードライブラリーのクラスとグーグルチャートAPIを用いて情報ボードを生成する
MQL5 プログラミング言語は主に自動取引システムと複雑な技術的解析の道具の創造をターゲットとしている。. しかしこのことを別として、これはマーケットの状況の追跡に対する興味深いシステムの創造も可能にし、トレーダーとの相互のつながりを与える。この記事ではMQL5の標準ライブラリーの要素とこのような目的に到達するための実例を示すことにする。またチャート作成のためのグーグルチャートAPIの使用についても例を示す。