「仕事中に気づかずに資金が飛んでしまった」
「資金が飛ぶ前に取引状況を知りたい!」
取引結果を見る為にいちいちVPSを確認するのが面倒くさいと思ったので
証拠金維持率をLINEに通知するEAを作ってみます。
見ないうちに資金が全部溶けてしまった。後少し気づくのが早ければ…
LINEに今エントリーしているポジションが危ないことをお知らせしたい
今回の内容は証拠金維持率のプログラミングの書き方について解説します。
LINE Nitifyの使い方や通知の設定方法については、下記の記事を参考にしてみてください。
証拠金に関する情報はメタクォーツ社が用意している関数を利用する事で
簡単に取得する事が出来ます。
AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);
AccountInfoDoubleは証拠金に関する関数で、
引数に以下の対応する値を入れる事で各々の値を取得する事が出来ます。
証拠金に関する情報を取得する関数AccountInfoDoubleの引数は以下の通りです。
必要な情報をピックアップしてLINEに通知してみましょう。
AccountInfoDouble(ACCOUNT_BALANCE ); //口座残高
AccountInfoDouble(ACCOUNT_CREDIT ); //クレジット
AccountInfoDouble(ACCOUNT_PROFIT ); //評価損益
AccountInfoDouble(ACCOUNT_EQUITY ); //有効証拠金
AccountInfoDouble(ACCOUNT_MARGIN ); //必要証拠金
AccountInfoDouble(ACCOUNT_FREEMARGIN ); //余剰証拠金
AccountInfoDouble(ACCOUNT_MARGIN_LEVEL ); //証拠金維持率(%)
AccountInfoDouble(ACCOUNT_MARGIN_SO_CALL); //マージンコールレベル
AccountInfoDouble(ACCOUNT_MARGIN_SO_SO ); //マージンストップレベル
LINEに通知する条件は任意です。
私の場合は現在注文を1つ以上保有している状態で尚且つ、証拠金維持率が600%を下回る時に
LINEに通知させています。
bef_accountInfoFlagは、600%未満になった時に何度もLINE通知が
来てしまう事を防ぐために、600%以下になる毎に
1回だけLINE通知する為にフラグを設定しています。
if(OrderedCount() >= 1 && bef_accountInfoFlag == 0 && AccountInfoDouble(ACCOUNT_MARGIN_LEVEL) < 600){
bef_accountInfoFlag = 1;
MARGIN_MESSAGE = "証拠金維持率が" + DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN_LEVEL),3) + "%です。";
NotifyToLine(MARGIN_MESSAGE);
}
if(bef_accountInfoFlag == 1 && AccountInfoDouble(ACCOUNT_MARGIN_LEVEL) >= 600){
bef_accountInfoFlag = 0;
}
OrderedCount()関数とNotifyToLine()関数は自作の関数です。
この2つの関数の書き方については、下記の記事を参考にしてください。
試しに手動でエントリーしてみました。
そうするとLINEに通知が来ましたね。
何度も通知してしまうのを止める為には、
通知する条件文にフラグを立てたりするのがいいと思います。
全ソースコードはこちらです。(コピペOK)
但し、トークンIDはご自身の物をお使いください。
//+------------------------------------------------------------------+
//| 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のアクセストークン
input string ENTRY_MESSAGE ="エントリーしました";//LINEに送るメッセージ
input string EXIT_MESSAGE ="全ての注文を決済しました";//LINEに送るメッセージ
string MARGIN_MESSAGE = "";
int NOTIFY_COUNT = 0;
int bef_accountInfoFlag = 0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
void NotifyToLine(string Massage)
{
Print("Massage:",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;
}
if(OrderedCount() >= 1 && bef_accountInfoFlag == 0 && AccountInfoDouble(ACCOUNT_MARGIN_LEVEL) < 600){
bef_accountInfoFlag = 1;
MARGIN_MESSAGE = "証拠金維持率が" + DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN_LEVEL),3) + "%です。";
NotifyToLine(MARGIN_MESSAGE);
}
if(bef_accountInfoFlag == 1 && AccountInfoDouble(ACCOUNT_MARGIN_LEVEL) >= 600){
bef_accountInfoFlag = 0;
}
}
//+------------------------------------------------------------------+
今回の確認は、手動で新規注文を行いましたが、
既にあなたが入れているEAが取引した時も、LINE_Notify_EA.ex4を導入すれば
取引のタイミングで通知を行ってくれます。
約定されている新規注文の数を数える関数についての質問は下記の記事にて解説していますので、
合わせてみてみてください。
こんにちわ
初コメント宜しくお願いいたします。
早速、に
LINE_Notify_EA.ex4
を作成してみました。
無事に稼働しましたが
証拠金維持率が600%以下になったら
沢山のLINE_Notifyが来て困っています、、、。
何か?対策はありますでしょうか?
証拠金維持率が600%以下の時
から
証拠金維持率が600%以下にクロスした時
みたいな、、、。
なにとぞ、ご指導ご鞭撻御願い致します。
コメントありがとうございます!
記事更新しますね。
見て頂くと分かるように、
bef_accountInfoFlagというフラグを一時的に用意してみました。
600%未満の時に通知を1回する。
証拠金維持率が600%以上に戻った後に、再度600%未満になったら通知を1回する。
これをする為にこのフラグを用意しました。
よろしくお願いします。
うわぁ~(^_-)-☆
早々に記事更新有難うございます(*^-^*)
記事更新が無茶苦茶、速くて、
無茶苦茶びっくり嬉しかったです。
本当に有難うございます_(._.)_
初めまして。コメント失礼します。
海外FXのMT5版に自分で改良して使わせていただいています。証拠金維持率の通知の書き方なのですが、1000%未満になったら通知して、更に500%切ったら再度通知したいのですが、如何せん初心者なもので、どのように書けばいいのか分かりません。。ご教授頂ければ幸いです。よろしくお願いいたします。
すみません、遅くなりました!
以下のような形で行けるかと思います…!参考にご自身で書いてみてください。
if(OrderedCount() >= 1 && bef_accountInfoFlag == 0 && AccountInfoDouble(ACCOUNT_MARGIN_LEVEL) < 1000){ bef_accountInfoFlag = 1; MARGIN_MESSAGE = "証拠金維持率が" + DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN_LEVEL),3) + "%です。"; NotifyToLine(MARGIN_MESSAGE); } if(OrderedCount() >= 1 && bef_accountInfoFlag == 1 && AccountInfoDouble(ACCOUNT_MARGIN_LEVEL) < 500){ bef_accountInfoFlag = 2; MARGIN_MESSAGE = "証拠金維持率が" + DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN_LEVEL),3) + "%です。"; NotifyToLine(MARGIN_MESSAGE); } if(bef_accountInfoFlag == 1 && AccountInfoDouble(ACCOUNT_MARGIN_LEVEL) >= 1000){
bef_accountInfoFlag = 0;
}
if(bef_accountInfoFlag == 2 && AccountInfoDouble(ACCOUNT_MARGIN_LEVEL) >= 500){
bef_accountInfoFlag = 1;
}