MQL5における 20のトレードシグナル
はじめに
トレーダーは価格の動きに何かの規則性を見出そうとし、規則を作る努力をしそれを用いて売買に好ましい瞬間を決定する良いチャンスを得ようとする。全自動のシステムを構築するには、そのような瞬間 (トレードシグナル) の前兆を知らせる方法を学ばなければならない。
シグナルはトレーダーにポジションに入る可能性のある時点を知らせるが、その全てが必ず実行すべきものではない。追加の判断基準がたいていのシグナルを選択から外すが、それはここで重要なことではない。この記事での主題は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つの移動平均の交差点
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
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索