
MetaTrader4で検知したシグナルなどを、LINE@に自動でメッセージを送信するプログラムをご紹介します。
LINE@で会員向けに情報発信をされている方には、自動化ツールになるんではないでしょうか?
今回の記事は、コメントをいただいた方のご要望に答えて作ってみました!
全体の仕様
まずはざっくりとした全体概要を説明します。
- LINE@オーナーのPCのMetaTrader4でEAを実行
- EAから送信されたシグナルをGoogle Apps Scriptで受信
- Google Apps ScriptでLINE Message APIを叩く
- LINE@のメッセージが表示
手書きのいい加減なイメージ図で恐縮ですが、上図のようなイメージで、MT4からLINE@のユーザーにメッセージが届きます。
MT4からGoogle Apps Scriptへのアクセスは「WebRequest関数」、Google Apps ScriptからLINE@へのメッセージ送信には、「LINE Messaging API」を使います。
今回紹介するプログラムは、図の網掛けになっている「LineBotTest.mq4」と「コード.gs」の部分です。
また、LINE@の設定方法などもご紹介します。
必要なもの
まず以下の2つのアカウントを準備してください。
- Googleアカウント
- LINEアカウント
Googleアカウント
Google Apps Scriptを動作させるために、Gメールのアカウントが必要です。
今後Google Apps Scriptで作ったアプリを外部に公開しても、アカウント名やGメールのアドレスが知られることはありません。
普段使っているGメールのアカウントでも、ほとんど影響がないと思いますが、気になるようでしたら新たにアカウントを作成してください。
LINEアカウント
LINE@の開設や、LINE Developerの開設に必要になります。
LINEは電話番号などとひもづくため、別途アカウントを作る・・というのが簡単にはできないのですが、
LINE@を開設したりやLINE Developerアカウントに登録したり、メッセージを配信などを行っても、普段使っているプライベートなアカウントが表示されたりすることは無いので安心してください。
EAのプログラム
MetaTrader4上で動作するEAのプログラムです。
下記のソースコードを「EA(エキスパートアドバイザー)」としてコンパイル・実行してください。
インジケーターとして保存しても動きません。理由は、「WebRequest関数」がEAでしか動かないためです。
ここは、MetaTraderの仕様なので、きっぱりあきらめましょう。
なお、下記のプログラムのまま実行すると、OnTickが呼ばれる度にメッセージを送信してしまうので、適切に書き換えて実行してください。
また、GASURLにGoogle Apps ScriptのURLを設定してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
//+------------------------------------------------------------------+ //| LineBotTest.mq4 | //| Copyright 2018, しゃかりきFX | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "しゃかりきFX" #property link "https://fx-shakariki.com/" #property version "1.00" #property strict input string GASURL = "https://script.google.com/macros/s/????????/exec"; // Google Apps ScriptのURL // ------------------------------------------------------------------ int OnInit() { return(INIT_SUCCEEDED); } // ------------------------------------------------------------------ // ------------------------------------------------------------------ void OnDeinit(const int reason) { } // ------------------------------------------------------------------ // String型文字列をUTF8に変換して、URLエンコードする // ------------------------------------------------------------------ string URLEncode(string str) { string ret = ""; uchar utf8[]; int len = StringToCharArray(str, utf8, 0, -1, CP_UTF8); for (int i = 0; i < len - 1; i++) { ret += StringFormat("%%%02x", utf8[i]); } return ret; } // ------------------------------------------------------------------ // ------------------------------------------------------------------ void OnTick() { // do something char post[], result[]; string cookie, headers; string msg = URLEncode("テストメッセージです"); string str = "&action=push&msg=" + msg; string url = GASURL; StringToCharArray( str, post ); int ret = WebRequest( "POST", url, cookie, NULL, 10000, post, 0, result, headers); } |
次にソースのポイントを解説していきます。
51~60行目:Google Apps ScriptにPOSTする
このプログラムには、ポイントが2つあります。
その1つ目が、51行目以降のWebRequest関数を使ってGoogle Apps ScriptにPOSTリクエストを送信する部分です。
1 2 3 4 5 6 7 8 9 10 |
char post[], result[]; string cookie, headers; string msg = URLEncode("テストメッセージです"); string str = "&action=push&msg=" + msg; string url = GASURL; StringToCharArray( str, post ); int ret = WebRequest( "POST", url, cookie, NULL, 10000, post, 0, result, headers); |
いつ見てもわかりづらい引数の「WebRequest関数」です。
1 2 3 4 5 6 7 8 9 10 11 |
int WebRequest( const string method, // HTTP method const string url, // URL const string cookie, // cookie const string referer, // referer int timeout, // timeout const char &data[], // the array of the HTTP message body int data_size, // data[] array size in bytes char &result[], // an array containing server response data string &result_headers // headers of server response ); |
重要な引数は、method、url、dataの3つだけです。
methodは”POST”
method引数は”GET””POST”のいずれも指定できますし、Google Apps ScriptもGET、POSTいずれでも受け取ることができます。
私がいろいろと試したのですが、GETの引数にメッセージなどの日本語文字列を指定するとLINE側で文字化けしてしまうので、GETは断念しPOSTにしました。
いろいろと試したのですが、うまくいきませんでした。GETパラメーターは、あまり長くないほうがよいといった意見もネット上では散見されますので、おとなしくPOSTを使います。
urlはGoogle Apps ScriptのURL
urlは、Google Apps Scriptで「公開」-「ウェブアプリケーションとして導入」で「現在のウェブ アプリケーション」の URLを設定してください。
“https://script.google.com”から始まり、”/exec”までです。
プログラム中でURLは、EA起動時に指定できるパラメーターにしていますが、頻繁に変わるものでもないので、プログラム中に埋め込んでしまったほうがよいかもしれません。
dataはPOSTのパラメーター
POSTのパラメーターは”¶m1=abc¶m2=def・・・・”という書式をchar型、つまりASCIIコードにして送ります。
LINE@にメッセージを通知するだけなので、メッセージを引数として送ればよいのですが、今後の拡張なども考えて次のように定義しました。
“&action=push&msg=メッセージ”
actionにリクエストの挙動(push)、msgにメッセージ内容(メッセージ)です。
これをStringToCharArray関数を使って、String型からchar型(ASCII)に変換しています。
が、ここでもう1つのポイントです。
30~41行目:日本語はURLエンコードする
Webプログラミングでは当たり前ですが、日本語などのマルチバイト文字列をパラメーターとしておくるには、URLエンコードが必要です。
また、Google Apps Scritpで取り扱う符号化方式は「UTF-8」ですので、符号化方式の変換をしてURLエンコードをします。
ややこしいですが、
String型(普通の文字列) → uchar型(UTF-8) → String型(URLエンコードされた文字列)
という処理を行います。
ちなみに「テスト」という文字列は、URLエンコードされると「%e3%83%86%e3%82%b9%e3%83%88」という%と16進数を文字化されたモノの羅列になります。
30 31 32 33 34 35 36 37 38 39 40 41 |
string URLEncode(string str) { string ret = ""; uchar utf8[]; int len = StringToCharArray(str, utf8, 0, -1, CP_UTF8); for (int i = 0; i < len - 1; i++) { ret += StringFormat("%%%02x", utf8[i]); } return ret; } |
以上でMetaTrader側のプログラムのポイント解説は終了です。
あとは、OnTickハンドラの中などで、適切な条件が成立した場合にメッセージを送るようにしてください。
Google Apps Scriptのプログラム
次に、Google Apps Scriptで実行するプログラムです。
プログラムを保存したら「公開」-「ウェブアプリケーションとして導入」で「アプリケーションにアクセスできるユーザー」を「全員(匿名ユーザーを含む)」に設定しておきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
//-------------------------------------------------------------------------- // LINEのMessageAPIを利用して、LINE@などにメッセージを送信する //-------------------------------------------------------------------------- var gChanneID = "<あなたのチャネルID>"; var gChannelToken = "<あなたのチャネルトークン>"; var gUserID = "<あなたのユーザーID>"; //-------------------------------------------------------------------------- function doPost(e) { if (e.parameter != undefined) { if (e.parameter.action == "push") { pushLineMsg(e.parameter.msg); } } } function pushLineMsg(msg) { var postData = { "to": gUserID, "messages": [ {"type": "text", "text": msg} ] }; var options = { "method": "post", "headers": { "Content-Type": "application/json", "Authorization": "Bearer " + gChannelToken }, "payload": JSON.stringify(postData) }; var response = UrlFetchApp.fetch( "https://api.line.me/v2/bot/message/push", options ); } |
Google Apps Script側は、プログラム的に特に難しいところはありません。
チャンネルID、チャンネルトークン、ユーザーの3つのパラメーターをLINE developersの管理画面から取得して入力してください。
(執筆中)
大変勉強になりました。全編読ませていただきました。
「RSI基準値より超えたらLINE」みたいな事できるんですか?
パソコン疎くて変な質問でしたらすいません。
うりうりさん
コメントありがとうございます。
RSI基準値より超えたらLINEを送信することも可能です。
1つ1つのインジケーターを個別にLINEを送るように作成するのも、みなさんの要望に応えづらいので、
汎用的にLINEを送ることができるようなソフトを現在開発中です。
乞うご期待!!
それは凄い!楽しみです!
ストキャスのコレと、RSIのコレが超えたら、みたいな多重条件など出来たら、、、と、期待を込めてコメントきてみます(^^)
うりうりさん
LINEを送るための、汎用的なツールのベータ版を作成してみました。
MetaTrader4のメール送信機能に対応しているインジケーターであれば、
LINEを送ることができるようになります。
もし、差し支えなければ、開発中の試用版をお送りしますので、
使えるかどうかデバッグにご協力いただけませんか?
(コメントを入れていただいたときのメアドにお送りします)
はじめまして!
私も特定のRSI数値をLINEやLINE@で配信できるツールを探していました。
プログラムなどは本当に初心者で、書いてある通りに書き換えることしかできないのですが、
試用版を試させていただけないでしょうか。
また、
>なお、下記のプログラムのまま実行すると、OnTickが呼ばれる度にメッセージを送信してしまうので、適切に書き換えて実行してください。
という、「適切に書き換えて」という所が分かりません(そんなレベルです;)
どのように書き換えるのか、お聞きしてもいいでしょうか?
どうぞよろしくお願い致します。
試用版に興味をもっていただきありがとうございます。
準備ができましたら、メールアドレスにご連絡しますね。
OnTickは、チャートの値が動くと呼び出されます。
値動きが激しいときは、短時間に複数回呼び出されます。
ですので、ここではご自身がやりたいこと、たとえばUSDJPYが110円を超えたらLINE送りたいな・・・と思った場合、
以下のように記述すれば、動作すると思います。
(実際に、コンパイルして動作確認しておりませんが・・・あしからず。。。)
if (Bid > 110) {
char post[], result[];
string cookie, headers;
string msg = URLEncode(“テストメッセージです”);
string str = “&action=push&msg=” + msg;
string url = GASURL;
StringToCharArray( str, post );
int ret = WebRequest(
“POST”, url, cookie, NULL, 10000, post, 0, result, headers);
}
ありがとうございます!
やってみます。
準備できましたら、お知らせしますね
はにゅうさん
その後、進捗はいかがですか??
具体的にご要望があれば、インジケーター作成の記事を書きますのご連絡くださいね。
Hello,
let me introduce myself. my name is one.
I read your blog via google translate ==> https://translate.google.co.th/translate?hl=th&sl=auto&tl=en&u=https%3A%2F%2Ffx-shakariki.com%2Flineat_auto1%2F
Then I try to code EA to send message to LINE , and I have question about “Google script URL”.
I write the script ==> https://script.google.com/d/1JtIKkYo6RfjNcx8Kc6rbKQaEqTIdJlXAYdi-u2yZEQFzcFfz3IAWcn_m/edit?usp=sharing
I don’t Know how to get the correct URL ( GASURL ) for putting in EA code.
Please help me.
Hi, One.
Could you try following.
1.Open Google App Script(Code.gs)
2.Select “Menu – Publish – Deploy as web app”
3.Maybe you can see “Current web app URL:”
Hi,
I have tried your code, but webrequest retun the error code 401 in MT4. Did you have this issue before?
Hi, Bill
Maybe you created the project as “INDICATOR”.
I recomend you will try to create a project as “Expert Advisor”.
YOUさん
LINEの話ではありますが、1点教えてください。
MT4からLINE@に配信をしたく思い、
YOUさんの記事に従って作成をしたのですが、LINE@側の構成がよくわかりません。
PUSH_MESSAGEを使用すると思いますので、LINE developersで
プロバイダー、Channel、Messaging APIを作成しました。
PushするためにはDevelopperTrialプランだと思い、こちらで作成しましたが、追加可能友達は50人のBotになりますが、こちらでよろしかったでしょうか?
上手くいかなかったため、LINE@のアカウントを作成し、
Messaging APIの設定で、さきほど作成したプロバイダーを選択してみましたが、
その場合にはREPLY_MESSAGEのみ利用可能となります。
どちらも試してみましたが、GoogleAppsScriptsから先の動作が上手く行っておりません。
突然の質問で申し訳ありませんが、ご教授いただければ幸いです。
宜しくお願い致します。
もしかして、LINE@側はPushAPIが使用可能なプロ(API)の月額32,400円が前提のお話になりますでしょうか?
教えて下さい。
https://api.line.me のリクエストに失敗しました(エラー: 401)。サーバー応答の一部: {“message”:”Authentication failed due to the following reason: invalid token. Confirm that the access token in the authorization header is valid.”}(応答の全文を見るには muteHttpExceptions オプションを使用してください)(行 37、ファイル「コード」)
これはどういう意味ですか?