インジケーターのシグナルをメールで受け取りたい…
裁量トレードされている方はそういうことが少なからずあるはずです。
EAの売買をメールで確認したい方もいらっしゃるでしょう。(オープンは自動で、クローズは裁量も含めるといった半裁量トレードで運用される方もいると思います。)
MQL4でメール送信するプログラムを書くのは非常に簡単です。
MQL4プログラミングでメール送信
以下の様に書くだけです。
SendMail("title","text");
“title”には件名を、”text”には内容を書きます。例えば…
SendMail("Open Buy Signal","買いシグナルが発生しました。");
このように書けば、件名には「Open Buy Signal」、内容は「買いシグナルが発生しました。」というメールが送信されることになります。
それでは、前回作成した移動平均ブレイクアウトインジケーターのプログラムを改修し、アラートを表示するだけでなくメールの送信もできるようにしてみましょう。
移動平均ブレイクアウトインジケーターにメール送信機能を付加
//+------------------------------------------------------------------+ //| MovingSignal.mq4 | //| Copyright 2016, TradeAndSoftware | //| https://tasfx.net | //+------------------------------------------------------------------+ #property copyright "Copyright 2016, TradeAndSoftware" #property link "https://tasfx.net" #property version "1.00" #property strict #property indicator_chart_window #property indicator_buffers 1 #property indicator_buffers 2 #include <ErrorMessage.mqh> input int SlowEMAPeriod = 80; input int FastEMAPeriod = 25; input double HeightPercent = 0.45; input bool EnableMail = false; input bool EnableAlert = true; datetime OpenBarTime = 0; double BufferBuy[]; double BufferSell[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { SetIndexBuffer(0, BufferBuy); SetIndexStyle(0, DRAW_ARROW, STYLE_SOLID, 3, clrCyan); SetIndexArrow(0, 233); SetIndexBuffer(1, BufferSell); SetIndexStyle(1, DRAW_ARROW, STYLE_SOLID, 3, clrRed); SetIndexArrow(1, 234); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { double fastEMA = iMA(Symbol(),0,FastEMAPeriod,0,MODE_EMA,PRICE_CLOSE,0); double slowEMA = iMA(Symbol(),0,SlowEMAPeriod,0,MODE_EMA,PRICE_CLOSE,0); double barHeight = MathAbs(Close[0] - Open[0]); double percentage = (barHeight / Ask) * 100; if(percentage > HeightPercent && Time[0] != OpenBarTime) { if(Close[0] > slowEMA && slowEMA > Open[0] && Close[0] > fastEMA) { if(EnableAlert) Alert("Open Buy Signal"); if(EnableMail) SenderMail("Moving Signal : Open Buy Signal","Open Buy Signal"); BufferBuy[1] = High[1]; OpenBarTime = Time[0]; } if(Open[0] > slowEMA && slowEMA > Close[0] && fastEMA > Close[0]) { if(EnableAlert) Alert("Open Sell Signal"); if(EnableMail) SenderMail("Moving Signal : Open Sell Signal","Open Sell Signal"); BufferSell[1] = Low[1]; OpenBarTime = Time[0]; } } if(OrdersTotal() > 0) { for(int i=0; i<=OrdersTotal()-1; i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == false) break; if(OrderSymbol() != Symbol()) continue; if(OrderType() == OP_BUY && fastEMA > Ask) { if(EnableAlert) Alert("Close Buy Signal"); if(EnableMail) SenderMail("Moving Signal : Close Buy Signal","Close Buy Signal"); } else if(OrderType() == OP_SELL && Bid > fastEMA) { if(EnableAlert) Alert("Close Sell Signal"); if(EnableMail) SenderMail("Moving Signal : Close Sell Signal","Close Sell Signal"); } } } return(rates_total); } void SenderMail(string title, string text) { if(!SendMail(title,text)) { Print("SendMail Error : " + GetErrorMessage(GetLastError())); } } //+------------------------------------------------------------------+
修正点解説
まずパラメーターに
input bool EnableMail = false; input bool EnableAlert = true;
を追加してメール送信したい場合にはEnableMailにtrueを設定するようにします。ついでにAlertもON/OFFできるようにEnableAlertも追加しました。
if(EnableAlert) Alert("Open Buy Signal"); if(EnableMail) SenderMail("Moving Signal : Open Buy Signal","Open Buy Signal");
そしてAlert出力にif文を追加。EnableAlertがtrueだった場合にはAlert出力、EnableMailがtrueだった場合にはメールを送信するようにしています。
エラーロジックを1つにまとめるため、今回はSenderMailという関数を作りました。
void SenderMail(string title, string text) { if(!SendMail(title,text)) { Print("SendMail Error : " + GetErrorMessage(GetLastError())); } }
SendMailを実行し、falseが返ってきたらエラーを出力する…のですが、「実際にエラーになるように設定」して実行してもtrueが返ってきました…。(まともにエラーを取得してくれません;;)
※Printでエラー出力処理を書いていなくても、MT4がエラーメッセージを出力してくれますから特に必要ないです。どのようなエラーのときにSendMail関数がfalseを返すのかわかりませんでした…。
MT4側のメール設定(SMTPサーバー設定)
Yahooメールを使った方法を記載します。※Gmailでは現在、動かなくなっているそうです。(試していませんが仕様変更によりfaiさんの手法でもダメらしいです。素直にYahooメールか、契約しているプロバイダあればそのプロバイダを使用しましょう。)
MT4の上部メニューから、ツール>オプションを開いて「E-メール」タブを表示します。
一番上のチェックボックスにチェック(有効にする)し、SMTPサーバーにsmtp.mail.yahoo.co.jp:465と入力します。
SMTPログインIDにはYahooメールの@の前の文字を。パスワードはYahooメールにログインする際のパスワードを入力して下さい。
そして発信元はYahooメールアドレス、送信先には受け取りたい端末のメールアドレス(携帯メールアドレスなど)を入力します。
入力が終わったら「テスト(T)」ボタンをクリック。正常に終了できたら操作履歴に 「Mail:’Test message’ has been sent」と表示され、メールが届くはずです。
※記事執筆時点の設定です。変更される可能性がありますので、うまくいかない場合にはYahooメールのサーバー設定情報を確認して下さい。
※SMTPサーバー情報はYahooメールにログインして右上の「設定・その他」をクリックし、表示されたメニューから「POP/ IMAPアクセスとメール転送」を選択。「ブラウザーアクセスとPOP/IMAPアクセス」の「設定情報」をクリックすると表示されます。
送信メール(SMTP)サーバーの後ろに:を付けてポート番号を記入してください。
メール送信でエラーが出るんだけど!?
まずはMT4を再起動してみてください。設定が反映されていない可能性があります。
MT4の再起動をしても届かない場合には操作履歴のエラーメッセージを確認します。
Mail:error connecting to smtp.mail.yahooo.co.jp
とエラーが出ていた場合にはメールアドレス、ID、パスワードに誤りがないか確認してみてください。(他のエラーメッセージは出ていないのでわかりません;;)
別解 スマートフォンにプッシュ通知する
MABreakout(MovingSignal)の元ネタを提供してくれた「マネー報道」氏は、デモ口座で「EAのトレード(オープン/クローズ)」をスマートフォンにプッシュ通知することでシグナルの発生を検知して、裁量トレードできるようにしたそうです。(「メール通知の記事は後日書くよ」と伝えたのですがメールだとリアルタイムに取れない環境なのだそうで。プッシュ通知の方が都合が良いようです。)
設定方法はマネー報道氏のブログに書かれています。興味のある方はこちらを御覧ください。
以上、「MT4のインジケーターやEAのシグナルをメールで通知する方法」でした。
コメント
初めて書き込みします
メール通知設定がうまくいかず、大変申し訳ないのですが質問させていただきます。
やりたいこと
指定のプライスに触れたらメール通知(30分に1回 最大2回通知)をしたいのですが、解決せず苦慮しています。
例えば、指定のプライス(109.980 USD/JPY)だとして、プライスが下から越えたらメールが飛ぶようにコードを書いてみたのでご覧ください。
static bool alart=false;
static datetime bound;
if(TimeCurrent() > bound) {
alart=false;
}
if(Bid>=119.980 && !3alart) {
SendMail(“指定プライス”,Symbol()+DoubleToStr(Bid,Digits));
bound=TimeCurrent()+30*60;
alart=true;
問題はBidがプライスを越えていたら、30分毎にメールが来てしまう点です。
最大2回までと制限をかけたいのですが、コードがうまく書けないため、ご助力いただけたら幸いです。
これだけですとちょっとわからない部分もあるので正確なお答えはできかねますが‥
「最大通知回数が2回」なのでしたらカウンターは必須になるかと思います。
数値変数counterを宣言して0セット。
メール通知時にcounter++。
counterが3以上だったら処理しない。で良いのではないでしょうか。
int counter = 0;
int OnCalculate(‥ //Tick毎処理する関数
if(counter > 2) //カウンターが3以上だったら処理せずに終了
return(0);
‥
‥
‥
SendMail(“指定プライス”,‥
bound=TimeCurrent()+30*60;
alart=true;
counter++;
こんな感じでどうしょうか。
EAで開発している場合にはちょっと書き方は異なりますが、そのあたりは読み替えてください。