ホーム » FX自動売買基礎と応用 » MT5で水平線タッチ時にアラート・メール・プッシュ通知を実行するツールを作成する【MQLプログラミングの基礎】

MT5で水平線タッチ時にアラート・メール・プッシュ通知を実行するツールを作成する【MQLプログラミングの基礎】

1.ファイルの新規作成

この記事では、手動で引いた水平線へローソク足(現在価格)がタッチしたときに、各種通知(アラート・メール・プッシュ通知)を実行するツールを作成します。

※この記事はMQL5の内容です。MQL4に対応した類似記事は以下を参照してください。

ラインタッチでアラート通知するツールを作成する方法

MetaEditorの「新規作成」アイコンをクリックしてMQLウィザードを開始します。

MQLウィザード新規作成

「カスタムインディケータ」を選択して「次へ」をクリック。

一般プロパティ

ファイル名を「LineTouchAlert.mq5」とします。
パラメーターの「追加」ボタンを押して「ALERT」「MAIL」「PUSH」を追加し、各パラメーターのタイプは「bool」、初期値は「true」とした後に「次へ」をクリック。

イベントハンドラ

イベントハンドラは一番上のOnCalculateのみを選択して「次へ」をクリック。

描画プロパティ

「カスタムインディケータの描画プロパティ」では、特に何も追加せず「完了」をクリックすれば、ファイルのベースが作成されます。

今回のファイルでは、インジケーターバッファを利用しないので、「#property indicator_chart_window」の行の下へ、下記を追加します。


#property indicator_buffers 0
#property indicator_plots   0

2.チャート上にある水平線の検出

OnCalculate関数内に下記のfor文を追加し、チャート上の水平線を検出します。


   for (int i = 0; i < ObjectsTotal(0, 0, OBJ_HLINE); i++) {
      string name = ObjectName(0, i, 0, OBJ_HLINE); 
      
   }

ObjectsTotal関数は、チャート上のオブジェクトの数を出力します。
引数は、ObjectsTotal(チャートID, ウィンドウ番号, オブジェクトの種類)を示しており、上記for文の指定であれば、チャートのメインウィンドウにある水平線の数が返されます。
ObjectName関数にて、全ての水平線の名称を順に取得しています。

3.水平線への価格タッチ判定

for文内(nameを定義した次の行)に下記を追加し、各水平線の価格情報を取得します。


      double price = ObjectGetDouble(0, name, OBJPROP_PRICE, 0);

OnCalculateで定義されている価格情報の配列close[]を、最新足を0番目の足として扱うために、下記の行をfor文の前に追加します。


   ArraySetAsSeries(close, true);

for文内(priceを定義した次の行)にタッチ判定の式を追加します。


      bool touchUp = close[0] >= price && close[1] < price;
      bool touchDown = close[0] <= price && close[1] > price;

touchUpが水平線の下から上への価格タッチ、touchDownは水平線の上から下への価格タッチを判定しています。
close[0]は最新価格、close[1]は最新未確定足より1本前の確定足の終値です。
タッチ判定が成立したときのみ処理を実行するよう、下記のif文を追加します。


      if (touchUp || touchDown) {
         
      }

4.各種通知の実行

タッチ判定成立のif文内に、通知する文字列を定義します。


         string text = _Symbol + " : Line Touch " + (touchUp ? "Up" : "Down");

例えば、米ドル/円チャートで水平線の下から上へタッチした場合、「USDJPY : Line Touch Up」と通知されます。
上から下へのタッチの場合、Upの文字がDownになります。
水平線の価格情報も通知に加えるため、下記の行を追加します。


         text += " (" + DoubleToString(price, _Digits) + ")";

アラート通知を実行するために、下記の式を追加します。


         if (ALERT) Alert(text);

メール通知を実行するために、下記の式を追加します。
メールの件名は、本ツールのファイル名称(MQLInfoString(MQL_PROGRAM_NAME))としています。


         if (MAIL) SendMail(MQLInfoString(MQL_PROGRAM_NAME), text);

プッシュ通知を実行するために、下記の式を追加します。


         if (PUSH) SendNotification(text);

5.1本のローソク足での通知を1回のみに制限

OnCalculateで定義されている価格情報の配列time[]を、最新足を0番目の足として扱うために、下記の行をfor文の前に追加します。


   ArraySetAsSeries(time, true);

通知を実行したときの最新足の時間を、文字情報として水平線に入力するため、下記の式をif文内に追加します(オブジェクトのプロパティ「共有」タブの「説明」欄に時間情報の文字列が記憶されます)。


         ObjectSetString(0, name, OBJPROP_TEXT, TimeToString(time[0], TIME_DATE | TIME_MINUTES));

水平線から通知時間情報を取得し、現在のローソク足の時間以下の場合は、通知判定を実行しないよう、下記の式をfor文内のnameを定義した行の次へ追加します。


      string textTime = ObjectGetString(0, name, OBJPROP_TEXT);
      if (time[0] <= StringToTime(textTime)) continue;

上記までの作業にて、水平線への価格タッチで通知するツールの完成です。

水平線へのタッチ通知

6.ソースコード

今回、作成したソースコードは下記の通りです。


//+------------------------------------------------------------------+
//|                                               LineTouchAlert.mq5 |
//|                                  Copyright 2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0
//--- input parameters
input bool     ALERT=true;
input bool     MAIL=true;
input bool     PUSH=true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int32_t rates_total,
                const int32_t 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 int32_t &spread[])
  {
   ArraySetAsSeries(close, true);
   ArraySetAsSeries(time, true);
//---
   for (int i = 0; i < ObjectsTotal(0, 0, OBJ_HLINE); i++) {
      string name = ObjectName(0, i, 0, OBJ_HLINE);
      string textTime = ObjectGetString(0, name, OBJPROP_TEXT);
      if (time[0] <= StringToTime(textTime)) continue;
      double price = ObjectGetDouble(0, name, OBJPROP_PRICE, 0);
      bool touchUp = close[0] >= price && close[1] < price;
      bool touchDown = close[0] <= price && close[1] > price;
      if (touchUp || touchDown) {
         string text = _Symbol + " : Line Touch " + (touchUp ? "Up" : "Down");
         text += " (" + DoubleToString(price, _Digits) + ")";
         if (ALERT) Alert(text);
         if (MAIL) SendMail(MQLInfoString(MQL_PROGRAM_NAME), text);
         if (PUSH) SendNotification(text);
         ObjectSetString(0, name, OBJPROP_TEXT, TimeToString(time[0], TIME_DATE | TIME_MINUTES));
      }
   }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

本記事の監修者・HT FX

2013年にFXを開始し、その後専業トレーダーへ。2014年からMT4/MT5のカスタムインジケーターの開発に取り組む。ブログでは100本を超えるインジケーターを無料公開。投資スタイルは自作の秒足インジケーターを利用したスキャルピング。

EA(自動売買)を学びたい方へオススメコンテンツ

EA運用の注意点

OANDAではEA(自動売買)を稼働するプラットフォームMT4/MT5の基本的な使い方について、画像や動画付きで詳しく解説しています。MT4/MT5のインストールからEAの設定方法までを詳しく解説しているので、初心者の方でもスムーズにEA運用を始めることが可能です。またOANDAの口座をお持ちであれば、独自開発したオリジナルインジケーターを無料で利用することもできます。EA運用をお考えであれば、ぜひ口座開設をご検討ください。


本ホームページに掲載されている事項は、投資判断の参考となる情報の提供を目的としたものであり、投資の勧誘を目的としたものではありません。投資方針、投資タイミング等は、ご自身の責任において判断してください。本サービスの情報に基づいて行った取引のいかなる損失についても、当社は一切の責を負いかねますのでご了承ください。また、当社は、当該情報の正確性および完全性を保証または約束するものでなく、今後、予告なしに内容を変更または廃止する場合があります。なお、当該情報の欠落・誤謬等につきましてもその責を負いかねますのでご了承ください。

この記事をシェアする