メッセージのURL変更を簡単に
今回の内容で、このリンク先URLをMQLAuth管理ページから変更できるようになります
・バックテスト開始時に口座番号認証を行う
・一斉配信メッセージをクリックすると、指定したサイトが開く
・MT4のチャートから開くサイトURLを、ソースコードを編集せずに、MQLAuthの管理画面から変えられるようにする
まずはコードの全体像(コピペ用)
//+------------------------------------------------------------------+
//| ©2020 MT4ツール製作【シストレファクトリー】 |
//| https://interactivebrokers.work/ |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 設定必須項目[MQLAUTH_ID] [APPLICATION_NAME] |
//+------------------------------------------------------------------+
#define MQLAUTH_ID ""
#define APPLICATION_NAME ""
#define HTTP_QUERY_FLAG -2147483648
#include <MQLAuth.mqh>
#property copyright "©2020 MT4ツール製作【シストレファクトリー】"
#property link "https://interactivebrokers.work/"
#property version "1.01"
#property strict
string _openurl; // メッセージに含まれるURLを格納する変数
string _labelName = "appMessage"; // メッセージを表示するラベル名
//+------------------------------------------------------------------+
//| OnInit |
//+------------------------------------------------------------------+
int OnInit() {
//--- ストラテジーテスターを使う場合の認証 ---
if(IsTesting()) {
if(AuthByAccountNumber_ReturnBool(MQLAUTH_ID, APPLICATION_NAME)) {
_isAuthorized = true;
Print("口座認証に成功しました。");
} else {
_isAuthorized = false;
Print("口座認証に失敗しました。利用期限が過ぎているか、この口座番号では利用できません。");
}
}
//--- ストラテジーテスターを使う場合の認証 ---
//--- メッセージを表示するラベルの作成 ---
ObjectCreate(ChartID(), _labelName, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_COLOR, clrWhite);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_BACK, true);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_SELECTABLE, false);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_SELECTED, false);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_HIDDEN, true);
ObjectSetString(ChartID(), _labelName, OBJPROP_FONT, "Meiryo");
ObjectSetInteger(ChartID(), _labelName, OBJPROP_FONTSIZE, 14);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_XDISTANCE, 250);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_YDISTANCE, 50);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_ANCHOR, ANCHOR_LEFT_LOWER);
//--- メッセージを表示するラベルの作成 ---
//--- タイマー ---
EventSetTimer(1);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| OnDeinit |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
//--- タイマー削除 ---
EventKillTimer();
//--- メッセージラベル削除
ObjectsDeleteAll(ChartID(), _labelName, EMPTY, EMPTY);
}
//+------------------------------------------------------------------+
//| OnTick |
//+------------------------------------------------------------------+
void OnTick() {
if(!_isAuthorized) return;
// EAの処理
}
datetime _date;
bool _isAuthorized = false;
int _receiveMessageHour;
//+------------------------------------------------------------------+
//| OnTimer |
//+------------------------------------------------------------------+
void OnTimer() {
if(AccountInfoInteger(ACCOUNT_LOGIN) != 0) {
if(TimeDay(TimeLocal()) != TimeDay(_date)) {
_date = TimeLocal();
if(AuthByAccountNumber_ReturnBool(MQLAUTH_ID, APPLICATION_NAME)) {
_isAuthorized = true;
Print("口座認証に成功しました。");
} else {
_isAuthorized = false;
Alert("口座認証に失敗しました。利用期限が過ぎているか、この口座番号では利用できません。");
ExpertRemove();
}
}
}
if(TimeHour(TimeLocal()) != _receiveMessageHour) {
_receiveMessageHour = TimeHour(TimeLocal());
string message = Auth_GetApplicationMessage(MQLAUTH_ID, APPLICATION_NAME);
if(message != "") {
if(StringFind(message, "#", 0) >= 0) {
string result[];
StringSplit(message, '#', result);
ObjectSetText(_labelName, result[0], 18, "MS ゴシック", clrWhite);
_openurl = result[1];
} else {
ObjectSetText(_labelName, message, 18, "MS ゴシック", clrWhite);
_openurl = "";
}
}
}
}
//+------------------------------------------------------------------+
//| OnChartEvent |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam) {
if(id == CHARTEVENT_OBJECT_CLICK) {
if(sparam == _labelName)
if(_openurl != "")
bool result = Auth_OpenURL(_openurl);
}
}
//+------------------------------------------------------------------+
#define MQLAUTH_ID “” //””内に自分のMQLAUTH_IDを記入する
#define APPLICATION_NAME “” // “”内に自分の登録したEA・インジケーター名に書き換える
EA起動時と、日付が変わるときに口座番号認証を行う
//+------------------------------------------------------------------+
//| OnInit |
//+------------------------------------------------------------------+
int OnInit() {
//--- タイマー ---
EventSetTimer(1);
return(INIT_SUCCEEDED);
}
datetime _date;
bool _isAuthorized = false;
//+------------------------------------------------------------------+
//| OnTimer |
//+------------------------------------------------------------------+
void OnTimer() {
if(AccountInfoInteger(ACCOUNT_LOGIN) != 0) {
if(TimeDay(TimeLocal()) != TimeDay(_date)) {
_date = TimeLocal();
if(AuthByAccountNumber_ReturnBool(MQLAUTH_ID, APPLICATION_NAME)) {
_isAuthorized = true;
Print("口座認証に成功しました。");
} else {
_isAuthorized = false;
Alert("口座認証に失敗しました。利用期限が過ぎているか、この口座番号では利用できません。");
ExpertRemove();
}
}
}
}
ここでは、認証を行った日時を記録するグローバル変数_dateを用意し、日付が変わったら認証が行われるようにしています。
EA起動時は_dateにdatetime型の初期値である1970/01/01が格納されるので、EA起動時に認証が行われ、それ以後はMT4時間の日付が変わるたびに認証が行われます。
バックテスト開始時に口座番号認証を行うコード
//+------------------------------------------------------------------+
//| OnInit |
//+------------------------------------------------------------------+
int OnInit() {
//--- ストラテジーテスターを使う場合の認証 ---
if(IsTesting()) {
if(AuthByAccountNumber_ReturnBool(MQLAUTH_ID, APPLICATION_NAME)) {
_isAuthorized = true;
Print("口座認証に成功しました。");
} else {
_isAuthorized = false;
Print("口座認証に失敗しました。利用期限が過ぎているか、この口座番号では利用できません。");
}
}
//--- ストラテジーテスターを使う場合の認証 ---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| OnTick |
//+------------------------------------------------------------------+
void OnTick() {
if(!_isAuthorized) return;
// EAの処理
}
バックテスト時はOnTimer関数が動かないので、先ほどのソースコードだけではバックテスト時に認証が行われず、口座番号が違っていてもバックテストができてしまいます。
それを防ぐために、OnInit関数内で、バックテスト時にも認証を行うようにし、認証失敗したらOnTick関数の中身を実行しないようにします。
一斉配信メッセージをチャート上に表示し、クリックすると指定したサイトが開くコード
string _openurl; // メッセージに含まれるURLを格納する変数
string _labelName = "appMessage"; // メッセージを表示するラベル名
//+------------------------------------------------------------------+
//| OnInit |
//+------------------------------------------------------------------+
int OnInit() {
//--- メッセージを表示するラベルの作成 ---
ObjectCreate(ChartID(), _labelName, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_COLOR, clrWhite);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_BACK, true);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_SELECTABLE, false);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_SELECTED, false);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_HIDDEN, true);
ObjectSetString(ChartID(), _labelName, OBJPROP_FONT, "Meiryo");
ObjectSetInteger(ChartID(), _labelName, OBJPROP_FONTSIZE, 14);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_XDISTANCE, 250);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_YDISTANCE, 50);
ObjectSetInteger(ChartID(), _labelName, OBJPROP_ANCHOR, ANCHOR_LEFT_LOWER);
//--- メッセージを表示するラベルの作成 ---
return(INIT_SUCCEEDED);
}
int _receiveMessageHour;
//+------------------------------------------------------------------+
//| OnTimer |
//+------------------------------------------------------------------+
void OnTimer() {
if(TimeHour(TimeLocal()) != _receiveMessageHour) {
_receiveMessageHour = TimeHour(TimeLocal());
string message = Auth_GetApplicationMessage(MQLAUTH_ID, APPLICATION_NAME);
if(message != "") {
if(StringFind(message, "#", 0) >= 0) {
string result[];
StringSplit(message, '#', result);
ObjectSetText(_labelName, result[0], 18, "MS ゴシック", clrWhite);
_openurl = result[1];
} else {
ObjectSetText(_labelName, message, 18, "MS ゴシック", clrWhite);
_openurl = "";
}
}
}
}
//+------------------------------------------------------------------+
//| OnChartEvent |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam) {
if(id == CHARTEVENT_OBJECT_CLICK) {
if(sparam == _labelName)
if(_openurl != "")
bool result = Auth_OpenURL(_openurl);
}
}
OnInit関数内でラベルを作成し、そこにメッセージを表示するようにしています。
メッセージの更新日時を保存する_receiveMessageHourを用意し、1時間ごとにメッセージを更新しています。
メッセージ内に#(シャープ)がある場合は、文字列を前と後ろに切り分け、前半をメッセージ、後半をクリック時に開くサイトのURLにします。
URLはグローバル変数_openurlに格納し、ラベルをクリックするとOnChartEvent関数を実行しブラウザが開くようにします。シャープがない場合は全体をメッセージとして表示します。
MQLAuth管理画面よりURLの変更
この画面でメッセージを設定し、シャープの後にURLを書くと、チャート上のテキスト(ラベル)がリンクに変わります。
URLを変えたいときはここで編集すればよいので、いちいちソースコードをコンパイルして配布しなおす必要はありません。