【MT5/MQL5】インジケータからLINEに簡単通知(ソースあり)

この記事は約15分で読めます。

今回の概要

今回は、インジケータからLINEに通知するプログラムを紹介します。
MT5(MQL5)からLINEに通知する方法は、下記3通りくらいの方法があると思います。

  1. MQL5のWebRequest関数を利用する
  2. WinAPIのインターネット接続系関数(HttpSendRequestW()、等)を利用する
  3. WinAPIをシェル実行関数(ShellExecuteW)でcurlを実行する

ただ、1.に関しては公式サイトのWebRequestの説明にもある通り、インジケータから呼び出すことはできませんし、2.に関しては結構なボリュームのプログラムを書く必要が出てきてしまいますので、今回は、3.の方法でプログラムを作成していきます。

LINE通知をするための準備作業

LINE通知をするための準備として、LINE Notifyのサービスでアクセストークンを発行する必要があります。発行したアクセストークンは、MQL5のコードに設定します。

LINEのアクセストークンを発行する手順については、色々なサイトで解説しているので、当記事では説明を割愛します。こちらのサイトなどを参考に、アクセストークンを発行してください。

MQL5コード

LINE通知するMQL5コードを紹介します。今回のコードは

  • LINE通知用クラス(CNotifyLine.mqh)
  • LINE通知確認用インジケータ(IndicatorNotifyLine.mq5)

の2本になります。LINE通知関連のロジックは、インジケータ以外(EAやスクリプト)からも簡単に呼び出せるように、クラスライブラリ化しました。

LINE通知用クラス(CNotifyLine.mqh)

コード

//+------------------------------------------------------------------+
//|                                                  CNotifyLine.mqh |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

#import "shell32.dll"
int ShellExecuteW(int hWnd,string lpVerb,string lpFile,string lpParameters,string lpDirectory,int nCmdShow);
#import

//+------------------------------------------------------------------+
//|
//| [LINE通知用クラス]
//|
//+------------------------------------------------------------------+
class CNotifyLine
  {
private:

public:
   //|---------------------------------------------------------------+
   //| メンバ変数
   //|---------------------------------------------------------------+
   string            m_curl_path;
   string            m_webhook_url;
   string            m_token;

   //|---------------------------------------------------------------+
   //| コンストラクタ、デストラクタ
   //|---------------------------------------------------------------+
                     CNotifyLine();
                    ~CNotifyLine() {};

   //|---------------------------------------------------------------+
   //| メンバ関数
   //|---------------------------------------------------------------+

   //| curlの実行コマンドパス
   void              CurlPath(string sArgValue) { this.m_curl_path = sArgValue; };

   //| LINEのWebhookURL
   void              WebhookURL(string sArgValue) { this.m_webhook_url = sArgValue; };

   //| LINE Notifyのアクセストークン
   void              Token(string sArgValue) { this.m_token = sArgValue; };

   //| LINE通知実行
   void              Notify(string);

  };

//+------------------------------------------------------------------+
//| [コンストラクタ]
//+------------------------------------------------------------------+
CNotifyLine::CNotifyLine()
  {
   this.m_curl_path="c:\\Windows\\System32\\curl.exe";
   this.m_webhook_url="https://notify-api.line.me/api/notify";
   this.m_token="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  }

//+------------------------------------------------------------------+
//| [メンバ関数]
//|   LINE通知実行
//+------------------------------------------------------------------+
void CNotifyLine::Notify(string sArgMessage)
  {
   string sCommand;

   StringConcatenate(
      sCommand,
      "/c ",
      this.m_curl_path,
      " -X POST -H \"Authorization: Bearer ",
      this.m_token,
      "\" -F \"",
      "message=",
      sArgMessage,
      "\" ",
      this.m_webhook_url);

   ShellExecuteW(0,"","cmd.exe",sCommand,"",5);
  }
//+------------------------------------------------------------------+
Expand

コード解説

10~12行目

Windowsのコマンドプロンプトを叩くために必要なWindowsAPIを定義しています。

41~48行目

メンバ変数設定用の関数です。メンバ変数をpublicで定義しているので、この関数群は定義しなくても大丈夫ですが、気になる方はメンバ変数をprivateにするか、当関数群を削除しても問題ありません。

60~62行目

クラスのコンストラクタでLINE Notifyを利用する際に必要な固定値を設定しています。
60行目のcurlの実行コマンドパスは動作環境に合わせて修正してください。
62行目には、準備作業で発行したアクセストークンを設定してください。

69~86行目

LINEの通知コマンドです。LINEのインターフェース仕様に合わせてパラメータを指定して通知をしています。

LINE通知確認用インジケータ(IndicatorNotifyLine.mq5)

コード

//+------------------------------------------------------------------+
//|                                          IndicatorNotifyLine.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window

#include "CNotifyLine.mqh"

#property indicator_buffers  1
#property indicator_plots    1

#property indicator_type1    DRAW_LINE
#property indicator_style1   STYLE_SOLID
#property indicator_color1   clrRed
#property indicator_width1   1
double    bufHigh[];

CNotifyLine NotifyLine;

//+------------------------------------------------------------------+
//| 【初期化関数】
//|  ・チャートの初期表示時、または時間足変更等のチャート初期化が必要な
//|    タイミングで呼び出される。
//+------------------------------------------------------------------+
int OnInit()
  {
   ArraySetAsSeries(bufHigh, true);
   ArrayInitialize(bufHigh,  0);
   SetIndexBuffer(0,         bufHigh,          INDICATOR_DATA);
   PlotIndexSetDouble(0,     PLOT_EMPTY_VALUE, 0.0);

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| 【計算イベント関数】
//|  ・ローソク足に変化が発生する毎に呼び出される。
//+------------------------------------------------------------------+
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[])
  {

//+------------------------------------------------------------------+
//| 1. 新規チャートのインジケータ値がまだ計算されていない場合
//|   → 過去チャートのインジケータ値を計算する。
//+------------------------------------------------------------------+
   if(prev_calculated == 0)
     {
      for(int i=rates_total-1; i>=0; i--)
        {
         setBufferValue(i,false);
        }
     }

//+------------------------------------------------------------------+
//| 2. 過去チャートのインジケータ値は計算済で、
//|    前回計算済Bar数 < チャートの最大Bar数 の場合 (Liveで新規Barが発生した)
//|    → 新規Barのインジケータ値を計算する。
//+------------------------------------------------------------------+
   else
     {
      if(prev_calculated < rates_total)
        {
         setBufferValue(0,true);
        }
     }

//+------------------------------------------------------------------+
//| 3. 同Bar内でのティック変更によって呼び出された場合
//|    → インジケータ値は計算しない
//+------------------------------------------------------------------+

// NOP

//+------------------------------------------------------------------+
//| 今回の処理でインジケータ値を計算したBar数を返却する。
//|   → このreturn値は、次回OnCalculate関数が呼び出された際、
//|     引数のprev_calculatedに設定される。
//+------------------------------------------------------------------+

   return(rates_total);

  }

//+------------------------------------------------------------------+
//| 【インデックスバッファ設定関数】
//|  ・指定されたBar位置のインジケータ値を計算する。
//+------------------------------------------------------------------+
void setBufferValue(int iCurrentBar, bool bIsLiveNewBar)
  {

// 現在Bar位置に、1つ前のBarの高値をプロットする。
   bufHigh[iCurrentBar] = iHigh(Symbol(),PERIOD_CURRENT,iCurrentBar+1);

// Liveで新規Barが発生した場合のみ、LINEでインジケータ値を通知する。
// 過去チャートのインジケータ値を計算している時は通知しない。
   if(bIsLiveNewBar)
     {
      NotifyLine.Notify(DoubleToString(bufHigh[iCurrentBar],5));
     }
  }

//+------------------------------------------------------------------+
Expand

コード解説

11行目

LINE通知用クラスのクラスファイルを取り込んでいます。インジケータファイルと同階層に配置する前提のため””で括っていますが、クラスファイルをIncludeフォルダに配置した場合は、<>で括ってください。詳しくは、MQL5の公式サイトのこちらを参照してください。

22行目

LINE通知用クラスのインスタンスを定義しています。クラスの実体を作成しているため、コンストラクタがこのタイミングで動き、LINEとの接続情報がクラスのインスタンスに設定されます。

55~93行目

新規ローソク足発生時のみ計算する処理になっています。解説はこちらの記事を参照してください。

107~113行目

Liveで新規Barが発生した場合のみ、インジケータの値をLINEで通知しています。過去データのインジケータ値算出の際もLINE通知処理を呼び出してしまうと、大量にLINE通知が届いて大変な事になるので注意してください。

実行結果

「LINE通知確認用インジケータ」をチャートに設定する際、下記ダイアログが表示されるので、「DLLの使用を許可する」にチェックをしてください。

「LINE通知確認用インジケータ」を1分足チャートに設定した実行結果です。過去データのインジケータ値算出の際にはLINE通知されず、Liveで新規Barが発生した場合のみ、LINE通知されている事が分かります。

まとめ

今回は、インジケータからLINEに通知する方法を紹介しました。

メッセージングアプリの中でLINEは、世界で見るとそれほど普及率が高くないですが、日本では異様に高い普及率になっています。日本でMT5を利用している人にとっては、当記事の内容は有益だと思いますので、ぜひ活用してみてください。

コメント

  1. saru999 より:

    MT5のソースコードの公開、ありがとうございます。
    勉強させていただきます。
    MT4よりMT5は情報量が少ないので助かりました。
    感謝いたします。

  2. ゆびきたす ゆびきたす より:

    コメントありがとうございます。
    MT5の情報、本当に少ないですよね。
    記事を書きながら、実はほとんどニーズが無いのでは?
    と思っていたので、ニーズがあったようでホッとしました。

タイトルとURLをコピーしました