自動売買ソフトの取引結果が気になってしょうがない人に朗報です。
取引の結果をリアルタイムでLINEに飛ばせばいちいちVPSを確認するのが面倒くさいと思ったので
取引結果を通知するEAを作ってみます。
LINE Notifyとは、LINEと外部サービスを連携することで、
トークルームにメッセージを受け取れるサービスです。
LINE Notifyを使用する為に、LINE NotifyというWebサイトにアクセスします。
LINEにログインし、マイページに移動します。
トークンを発行します。
トークン名の入力と通知を受け取るトークルームを選択します。
LINE Notifyで発行したトークンは後で必要なので、コピーしておきます。
LINEのトークルームを見ると、LINE Notifyから、トークンを発行しました。とメッセージが来ていればOKです。
ツール→オプション→エキスパートアドバイザの設定で、
WebRequestを許可するURLリストにチェックを入れます。
URLリストにLINE Notifyにアクセスする為のURLを設定します。
https://notify-api.line.me/api/notify
新規作成をクリック。
string LINE_TOKEN = "";//LINEのアクセストークン
string ENTRY_MESSAGE ="エントリーしました";//LINEに送るメッセージ
string EXIT_MESSAGE ="全ての注文を決済しました";//LINEに送るメッセージ
int NOTIFY_COUNT = 0;//通知する回数を制御
MQL4言語のWebRequest()という関数を使い、メッセージデータをPOST送信します。
LINEのURLとトークンを使用しURLへアクセスします。
WebRequest()を使いPOST送信する為にheadersに下記の情報をセットしましょう。
Authorization: Bearerとは、認証方法の一つでアクセストークンを用いて、WebRequestするよという意味です。
//変数の定義
char data[], result[];
//headersの変数にコンテンツタイプを使用した単純なフォームを入れます。
string headers = "Content-Type: application/x-www-form-urlencoded" + "\r\n" + "Authorization: Bearer " + LINE_TOKEN + "\r\n";
//配列のサイズを変更
ArrayResize(data, StringToCharArray("message=" + Massage, data, 0, WHOLE_ARRAY, CP_UTF8) - 1);
//WebRequestでLINEへアクセス
int res = WebRequest("POST", "https://notify-api.line.me/api/notify", headers, 0, data, data, headers);
resにはWebRequestの結果が返ってきます。-1が返ってきた場合はエラーなので、エラー処理を記述します。
if(res == -1) //ErrorCheak
{
Print("Error in WebRequest. Error code =", GetLastError());
MessageBox("Add the address 'https://notify-api.line.me' in the list of allowed URLs on tab 'Expert Advisors'", "Error", MB_ICONINFORMATION);
}
NotifyToLine関数全体です。
Messageを切り替えられるように、引数にMessageを定義しています。
void NotifyToLine(string Massage)
{
char data[], result[];
string headers = "Content-Type: application/x-www-form-urlencoded" + "\r\n" + "Authorization: Bearer " + LINE_TOKEN + "\r\n";
ArrayResize(data, StringToCharArray("message=" + Massage, data, 0, WHOLE_ARRAY, CP_UTF8) - 1);
int res = WebRequest("POST", "https://notify-api.line.me/api/notify", headers, 0, data, data, headers);
if(res == -1) //ErrorCheak
{
Print("Error in WebRequest. Error code =", GetLastError());
MessageBox("Add the address 'https://notify-api.line.me' in the list of allowed URLs on tab 'Expert Advisors'", "Error", MB_ICONINFORMATION);
}
}
”EAの取引時”という条件が分かる為のOrderedCount()という関数を作ります。
OrderedCount()という関数は現在約定されている注文数の結果を返してくれる関数です。
OrdersTotal関数を使ってfor文を使い数を数えているのですが、
OrdersTotal関数だけ使うと指値などの待機注文も数に数えてしまう為、
OrderSelect(),OrderType()関数を使い実際に注文が約定されている数のみカウントします。
double OrderedCount()
{
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true)
{
if(OrderType() == OP_BUY || OrderType() == OP_SELL)
{
count++;
}
}
}
return(count);
}
リアルタイムでエントリーが入った事をお知らせしたいのでOnTick()関数に記述します。
NOTIFY_COUNTを設定することで、ローソク足が動く度に通知が行かないように制御しています。
void OnTick()
{
//---
if(OrderedCount() >= 1 && NOTIFY_COUNT == 0){
NotifyToLine(ENTRY_MESSAGE);//注文が入った事を知らせる
NOTIFY_COUNT = 1;
}else if(OrderedCount() == 0 && NOTIFY_COUNT == 1){
NotifyToLine(EXIT_MESSAGE);//保有ポジションが全て無くなった事を知らせる
NOTIFY_COUNT = 0;
}
}
//+------------------------------------------------------------------+
//| LINE_Notify_EA.mq4 |
//| Copyright 2020, MetaQuotes Software Corp. |
//| https://www.iandi.site/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link "https://www.iandi.site/"
#property version "1.00"
#property strict
string LINE_TOKEN = "";//LINEのアクセストークン
string ENTRY_MESSAGE ="エントリーしました";//LINEに送るメッセージ
string EXIT_MESSAGE ="全ての注文を決済しました";//LINEに送るメッセージ
int NOTIFY_COUNT = 0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
void NotifyToLine(string Massage)
{
char data[], result[];
string headers = "Content-Type: application/x-www-form-urlencoded" + "\r\n" + "Authorization: Bearer " + LINE_TOKEN + "\r\n";
ArrayResize(data, StringToCharArray("message=" + Massage, data, 0, WHOLE_ARRAY, CP_UTF8) - 1);
int res = WebRequest("POST", "https://notify-api.line.me/api/notify", headers, 0, data, data, headers);
if(res == -1) //ErrorCheak
{
Print("Error in WebRequest. Error code =", GetLastError());
MessageBox("Add the address 'https://notify-api.line.me' in the list of allowed URLs on tab 'Expert Advisors'", "Error", MB_ICONINFORMATION);
}
}
double OrderedCount()
{
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true)
{
if(OrderType() == OP_BUY || OrderType() == OP_SELL)
{
count++;
}
}
}
return(count);
}
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
if(OrderedCount() >= 1 && NOTIFY_COUNT == 0){
NotifyToLine(ENTRY_MESSAGE);//注文が入った事を知らせる
NOTIFY_COUNT = 1;
}else if(OrderedCount() == 0 && NOTIFY_COUNT == 1){
NotifyToLine(EXIT_MESSAGE);//保有ポジションが全て無くなった事を知らせる
NOTIFY_COUNT = 0;
}
}
//+------------------------------------------------------------------+
LINE_Notify_EA.ex4をチャートに導入し、新規注文時の通知を確認してみましょう!
しっかりとLINEにメッセージが来ましたね。
決済も行ってみます。
こちらも正常にLINEに通知が来ました。
今回の確認は、手動で新規注文を行いましたが、
既にあなたが入れているEAが取引した時も、LINE_Notify_EA.ex4を導入すれば
取引のタイミングで通知を行ってくれます。
今回はOrderType() を用い、通知をするようにしましたが
選択した注文のロット数や注文価格も取得する事も可能です。
必要に応じて使い分けてみてください。