インディケータのサウンドアラート
はじめに
自動トレーディングがますます一般的なものとなっていますが、トレーダーの多くはいまだにマニュアルトレーディングを行っています。現在の市況を評価するのに Expert Advisor が数ミリ秒を必要とする場面で、人間は多くの時間、労力、そして最も重要な注意力を費やします。
数年前には数多くトレーダーは一つ以上の テクニカルインディケータを使用していました。いくつかの戦略は複数のタイムフレームにおけるインディケータ値を同時に考察するのです。
それで重要なシグナルをどのように『キャッチ』できるのでしょうか?選択肢はいくつかあります。
- 市場を分析し、重要なイベントについて警告を出す Expert Advisor を書く。
- モニターの前に座り、その間何十ものチャートの間を切り替え、すべてのチャートからの情報分析を試みる。
- 使用しているインディケータすべてにアラートシステムを追加する。
私の意見では、第1の選択はもっとも適切なものです。ただ、実現するにはプログラミングのスキルか人に支払う費用のどちらかが必要です。第2の方法は、時間がかかり骨が折れ、非効率的なものです。第 3 の選択は前の 2 つの折衷案です。要求されるスキルはずっと低く実装するのにかかる時間も短くてすむ割にはユーザーのマニュアルトレーディングより断然優れています。
本稿で取り上げるのは第 3 の選択の実装です。読み終わったら、トレーダーのどなたもがインディケータに便利なアラートを追加することができるようになっていることでしょう。
アラートタイプ
インディケータを解釈する方法は数多くあります。MetaTrader 4 クライアントターミナルのインディケータでさえ、その意味の理解はさまざまです。ましてや多様なカスタムインディケータに至っては推して知るべし、です。
MACD のメインラインがシグナルラインに達すると買いを行う人もいれば、別のトレーダーはそれがゼロラインと交わるのを待ち、また MACD が 0 を下回り上昇し始めたらロングポジションをオープンする人もいます。私は可能性あるすべての解釈のバリエーションを考慮できるような気はしません。ですので、インディケータにアラートブロックを追加する方法の基本を説明するに留めます。そうすれば、お好みに合わせてみなさんが実質上あらゆるインディケータにどんな種類のアラートも追加できるようになるのです。
もっとも可能性のあるアラートを以下にリストアップしました。
- インディケータの 2 つの線の交点(上の例にあります。メインラインと MACD のシグナルライン)
- インディケータラインと特定レベルの交点(たとえば、MACD のメインラインとゼロライン、ストキャスティックとレベル70 と30、CCI とレベル-100と100)
- インディケータの逆転変動(たとえば、 AC と AO、通常の MA)
- 価格に向かって変更されたロケーション(パラボリック SAR)
- 価格値の上または下に矢印表示(フラクタル)
おそらく忘れているか、私が知らない解釈がいくつかあるでしょうが、上でリストアップした 5 とおりについて説明します。
アラートの方法
MetaTrader 4 および MQL4 によりビジュアル、音声アラートのどちらも複数の方法で実装することが可能となりました。
- 通常のスクリーンメッセージ(関数 Comment)
- ログのレコード(関数)
- メッセージウィンドウプラス音声(関数 Alert)
- 特殊サウンド、選択し再生されるファイル(関数 PlaySound)
その上、ファイルを FTP サーバーに送信(関数 SendFTP())、メッセージ/ダイアログ ボックス表示(MessageBox())、メール送信(SendMail())を行う関数があります。関数 SendFTP() は通常ユーザーからはほとんど必要とされません。関数 MessageBox() は、メッセージボックスが閉じるまで処理を停止するためインディケータで使用するには適していません。関数 SendMail() は送信には優れているものの、使うにはかなり『危険』です。チャートに多くのインディケータを書くと、きりのない制御されないメッセージストリームをもたらすことになります。関数は使われますが、EA からだと、たとえば複数のインディケータで同時にアラートが出るときメッセージを送信することで使用するのが良いでしょう。そのときは十分注意を払います。
本稿では、MetaTrader 4 クライアントターミナルでのオーディオとビジュアルのアラート方法のみ考察していきます。
そのうちもっとも便利で簡単なのは、関数 Alert です。そこにはテキストとサウンドの両方が含まれているからです。また、ターミナルは Alerts の履歴を格納するため、1時間前にどのシグナルが来たか確認することが可能です。
ただ、当然のことながら好みはさまざまです。そこで上述の方法に対して試作品のようなものを作成します( SendFTP、MessageBox、SendMail 以外)。みなさんは適切なものを選ぶだけです。
アラート頻度フィルター
インディケータでアラートを利用したことがあるなら、特に小さいタイムフレームの場合、確かに過頻度をコントールしなければならなかったでしょう。この問題の解決法はいくつかあります。
- すでに形成されているバーでアラートを定義する。この方法はもっとも適切でしょう。
- 代替アラート-買いのあとに売り、またその逆(他の方法と併用できる、ひじょうに論理的な方法でもあります。)
- アラートの間にポーズを入れる(よい考えではありません)
- バーごとにアラートを1つだけ入れる(これはかなり影響を受ける制限です)
では、作業を始めます。
アラート1-インディケータの 2 本のラインの交点
上の例で出た MACD から始めます。
主なタスクはどの配列にインディケータ ラインが格納されるか見つけることです。このためのコードを見ます。
//---- indicator settings #property indicator_separate_window #property indicator_buffers 2 #property indicator_color1 Silver #property indicator_color2 Red #property indicator_width1 2 //---- indicator parameters extern int FastEMA = 12; extern int SlowEMA = 26; extern int SignalSMA = 9; //---- indicator buffers double MacdBuffer[]; double SignalBuffer[];
『インディケータ バッファ』のコメントがわれわれが今さがしているものであることに留意ください。そのような配列はたいてい直観的に複雑な名前(MacdBuffer は MACD のメインライン値バッファ、 SignalBuffer はシグナルラインのバッファ)がついていて、つねに関数 init、deinit、start の外にあります。
数多くの配列があり、そのうちのどれが必要なのか見分けるのがむつかしければ、関数 init の中を探します。チャートに表示される配列はすべて関数 SetIndexBuffer によって特定の番号にアンカーされています。
int init() { //---- drawing settings SetIndexStyle(0, DRAW_HISTOGRAM); SetIndexStyle(1, DRAW_LINE); SetIndexDrawBegin(1, SignalSMA); IndicatorDigits(Digits + 1); //---- indicator buffers mapping SetIndexBuffer(0, MacdBuffer); SetIndexBuffer(1, SignalBuffer); //---- name for DataWindow and indicator subwindow label IndicatorShortName("sMACD(" + FastEMA + "," + SlowEMA + "," + SignalSMA + ")"); SetIndexLabel(0, "sMACD"); SetIndexLabel(1, "sSignal"); //---- initialization done return(0); }
これはインディケータライン値が DataWindow で表示されるシーケンス(0~7)です。そこにある名前は関数 SetIndexLabel によってつけられます。これは第 3 の特定方法です。
これで、どこに必要なデータが格納されているのか知るとき、アラートブロックを実行し始めることができます。このために、関数 start の末尾に行きます。先行する演算子の戻りのすぐ上です。
for(i = 0; i < limit; i++) SignalBuffer[i] = iMAOnArray(MacdBuffer, Bars,S ignalSMA, 0, MODE_SMA, i); //---- done // we will add our code here return(0); } //+------------------------------------------------------------------+
どんな場合でも、アラートブロックはインディケータの計算ループに追加します。これは実行速度を遅らせ、なにも影響を与えません。
われわれの『構成』を書き始めます。
//---- Static variables where the last bar time //---- and the last alert direction are stored static int PrevSignal = 0, PrevTime = 0; //---- If the bar selected to be analyzed is not a zero bar, // there is no sense to check the alert //---- several times. If no new bar starts to be formed, quit. if(SIGNAL_BAR > 0 && Time[0] <= PrevTime ) return(0); //---- Mark that this bar was checked PrevTime = Time[0];
関数 start が実行されるときは毎回、われわれのコードも実行されます。通常の変数は、関数実行後、ゼロ設定されます。そこで、直近のアラートと計算されたバー数を格納するため、静的変数を 2 つ宣言します。
それから次は簡単なチェックです。新規バーが開始したかどうか確認します(SIGNAL_BAR が0より大きければ動作します)。
ところで、少し前に関数 init の前で変数 SIGNAL_BAR 自体を宣言しました。
double SignalBuffer[]; //---- Bar number the alert to be searched by #define SIGNAL_BAR 1 //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() {
命令に注意ください。コード全体でコンパイラーは変数 SIGNAL_BAR を与えられた値 (1) と置き換えます。
以下がアラートコードそのものです。
//---- If the preceding alert was SELL or this is the first launch (PrevSignal=0) if(PrevSignal <= 0) { //---- Check whether the lines have met in the preceding bar: if(MacdBuffer[SIGNAL_BAR] - SignalBuffer[SIGNAL_BAR] > 0 && SignalBuffer[SIGNAL_BAR+1] - MacdBuffer[SIGNAL_BAR+1] >= 0) { //---- If yes, mark that the last alert was BUY PrevSignal = 1; //---- and display information: Alert("sMACD (", Symbol(), ", ", Period(), ") - BUY!!!"); // Print("sMACD (", Symbol(), ", ", Period(), ") - BUY!!!"); // Comment("sMACD (", Symbol(), ", ", Period(), ") - BUY!!!"); // PlaySound("Alert.wav"); } }
これもひじょうに簡単です。先行のアラートが「売り」であれば、ラインの交点をチェックします。
バーNo.1の MACD メインライン値がバーNo.1のシグナルライン値を超えていて
かつ
バーNo.2 のシグナルライン値がバーNo.2 の MACD ライン値を超えている
場合、
ラインが交わりました。
最終アラートは「買い」であることをマークし、メッセージを表示します。コメントの 3 行に注意します。これらはアラートの 3 つのバリエーションです。それらはすべて非コメント化するか削除することができます。私はもっとも便利なものとしてデフォルトで Alert を残しました。
関数 PlaySound では、どの wave ファイルが再生されるかを指定します。ファイルはディレクトリ MetaTrader 4\sounds\ に入れられ、拡張 wav を持ちます。たとえば、特殊音声は「買い」アラートに割り当てることができます。そのほかには、「売り」アラート向けまたは、異なるインディケータに対しては違う音声があります、など。
「売り」アラートはまったく同じです。
//---- Completely the same for the SELL alert if(PrevSignal >= 0) { if(SignalBuffer[SIGNAL_BAR] - MacdBuffer[SIGNAL_BAR] > 0 && MacdBuffer[SIGNAL_BAR+1] - SignalBuffer[SIGNAL_BAR+1] >= 0) { PrevSignal = -1; Alert("sMACD (", Symbol(), ", ", Period(), ") - SELL!!!"); // Print("sMACD (", Symbol(), ", ", Period(), ") - SELL!!!"); // Comment("sMACD (", Symbol(), ", ", Period(), ") - SELL!!!"); // PlaySound("Alert.wav"); } }
その他のアラート
インディケータコードが解れば、他のアラートブロックを書くのは格段に易しくなります。『フォーミュラ』が変わるだけで、コードの残りはコピー&ペーストするだけです。
特定レベルに達したことを知らせるアラートは、ラインの交点についてのアラートとひじょうに似ています。私はそれをスキャスティックに追加しましたが、みなさんは似たものをほかのインディケータにお作りになれます。
if(PrevSignal <= 0) { if(MainBuffer[SIGNAL_BAR] - 30.0 > 0 && 30.0 - MainBuffer[SIGNAL_BAR+1] >= 0) { PrevSignal = 1; Alert("sStochastic (", Symbol(), ", ", Period(), ") - BUY!!!"); } } if(PrevSignal >= 0) { if(70.0 - MainBuffer[SIGNAL_BAR] > 0 && MainBuffer[SIGNAL_BAR+1] - 70.0 >= 0) { PrevSignal = -1; Alert("sStochastic (", Symbol(), ", ", Period(), ") - SELL!!!"); } }
ごらんのように、ライン %K (MainBuffer )がレベル 30 のボトムアップに交われば、インディケータは「買い」と言います。レベル70 がトップダウンに交われば「売り」と言います。
3番目のアラートは変動の方向が変わったことを伝えるものです。AC の例でそれを考察します。このインディケータではバッファが5個使用されていることに留意します。
//---- indicator buffers double ExtBuffer0[]; double ExtBuffer1[]; double ExtBuffer2[]; double ExtBuffer3[]; double ExtBuffer4[];
ExtBuffer3 および ExtBuffer4 は中間計算に使用され、ExtBuffer0 はつねにインディケータ値を格納し、ExtBuffer2 と ExtBuffer3 は列を2色に『着色』します。われわれが必要なのはインディケータ値だけなので、ExtBuffer0 を使います。
if(PrevSignal <= 0) { if(ExtBuffer0[SIGNAL_BAR] - ExtBuffer0[SIGNAL_BAR+1] > 0 && ExtBuffer0[SIGNAL_BAR+2] - ExtBuffer0[SIGNAL_BAR+1] > 0) { PrevSignal = 1; Alert("sAC (", Symbol(), ", ", Period(), ") - BUY!!!"); } } if(PrevSignal >= 0) { if(ExtBuffer0[SIGNAL_BAR+1] - ExtBuffer0[SIGNAL_BAR] > 0 && ExtBuffer0[SIGNAL_BAR+1] - ExtBuffer0[SIGNAL_BAR+2] > 0) { PrevSignal = -1; Alert("sAC (", Symbol(), ", ", Period(), ") - SELL!!!"); } }
インディケータ値が減っていき、それから増え始めると、「買い」アラートを出します。逆の場合は「売り」アラートを出します。
4番目のアラート、価格に向かうロケーションの変化を伝える、はかなり稀です。
ただ、たとえばパラボリックでときどき現れます。例としてそれを使って『式』を書きます。
if(PrevSignal <= 0) { if(Close[SIGNAL_BAR] - SarBuffer[SIGNAL_BAR] > 0) { PrevSignal = 1; Alert("sParabolic Sub (", Symbol(), ", ", Period(), ") - BUY!!!"); } } if(PrevSignal >= 0) { if(SarBuffer[SIGNAL_BAR] - Close[SIGNAL_BAR] > 0) { PrevSignal = -1; Alert("sParabolic Sub(", Symbol(), ", ", Period(), ") - SELL!!!"); } }
ここではすべてシンプルです。インディケータ値をバーのクローズ価格と比較します。SIGNAL_BAR が 0 に設定されていると、パラボリックに達するどの価格にもアラートが出ます。
最後のアラートはチャートに矢印が表示されたことを伝えます。標準的なインディケータでそれが出るのは稀ですが、カスタム『ピボットファインダー』ではかなり一般的です。この類のアラートはインディケータ Fractals (MQL4 で書かれたソースコードはコードベース:フラクタルにあります)を使って考察します。
チャートに描かれている場所では、それらは 0(または EMPTY_VALUE)ではない、ということはこれらすべてのインディケータに共通しています。他のバーはすべてそのバッファを空にします。それはバッファの値が 0 と比較するのに十分か判断するためのシグナルです。
if(PrevSignal <= 0 ) { if(ExtDownFractalsBuffer[SIGNAL_BAR] > 0) { PrevSignal = 1; Alert("sFractals (", Symbol(), ", ", Period(), ") - BUY!!!"); } } if(PrevSignal >= 0) { if(ExtUpFractalsBuffer[SIGNAL_BAR] > 0) { PrevSignal = -1; Alert("sFractals (", Symbol(), ", ", Period(), ") - SELL!!!"); } }
ただし、インディケータをそういうコードと共にチャートにアタッチすると、アラートを受信しなくなります。フラクタルには特殊な機能があります。分析するのに将来のバーを 2 本使うのです。それによって、矢印はバーNo.2 にだけ表示されます(ゼロバーからスタートした 3 番目のバー)。アラートが動作し始めるには、SIGNAL_BAR を 2 に設定する必要があります。
//---- Bar number to search an alert by #define SIGNAL_BAR 2
以上です。これでアラートが動作します。
おわりに
本稿ではインディケータに音声アラートを追加するのに使用されるさまざまなメソッドの記述を提供しています。アラート解釈メソッド(アラートタイプ)、アラート方法、 アラート頻度フィルターなどの用語が定義されています。
以下のアラートタイプが定義され実行されています。
- インディケータライン2本の交点
- インディケータラインと特定レベルの交点
- インディケータの反転
- 価格に向かうロケーション変化
- 価格レベルの上下に表示される矢印
- Comment() -通常メッセージ表示
- Print()-ログへのメッセージ表示
- Alert()-特別なウィンドウおよび音声アラートへのメッセージ表示
- PlaySound() -wave ファイルの再生
- アラートを決める際、すでに形成されているバーを使用する
- 全アラート交互表示―売りの後にだけ買い、またはその逆
私はアラートブロックを調べるために5つのアラートタイプに対応する5つのインディケータを使いました。結果として得たインディケータはダウンロードできます。それらは本稿に添付しています。
インディケータにアラートブロックを追加するのは、何もむつかしいことはない、皆ができることなのだ、とおわかりいただけることを願っています。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/1448
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索