【コピペでOK】MT4のチャートから飛ばすURLをソースコードを編集せずに、MQLAuthの管理画面から変えられるようにする

MQL実装例
yuki
yuki
今回は、MQLAuthの機能を使った応用編です!お手本としていくつかの機能を実装していますが、特にチャートから飛べるURLを、インジのコードを書き換えずにMQLAuthの管理画面から簡単に変更できる機能は後々役に立つので参考にしてください!
カオチャイ
カオチャイ
今回はMQLAuthの一斉メッセージ機能に対応させていますが、もちろん個別メッセージ機能にもそのまま応用していただけますよ
yuki
yuki
この機能は無料でご利用できますが、MQLAuth.mqhのバージョン1.01以上がインストールされている必要がございますので、まだ準備ができていない方は下記の記事を参考にしてくださいね!
MQLAuth準備編
MQLAuthシステムを利用するための事前準備 MQLAuthを使うための準備 MQLAuthシステムを使う前提条件として「インジケーターをMT4の口座番号やパスワードで縛って管...

メッセージのURL変更を簡単に

MT4のチャート今回の内容で、このリンク先URLをMQLAuth管理ページから変更できるようになります

 

今回書いていくコードには下記の5つを実装しています

EA起動時と、日付が変わるときに口座番号認証を行う

・バックテスト開始時に口座番号認証を行う

一斉配信メッセージをチャート上に表示する

・一斉配信メッセージをクリックすると、指定したサイトが開く

・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);
   }
}
//+------------------------------------------------------------------+

 

yuki
yuki
ソースコードはこちらからダウンロードできます。そのままEAで利用するためには下記の部分を書き換える必要がありますのでご注意くださいね!

#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時間の日付が変わるたびに認証が行われます。

 

EAの口座認証機能
口座番号認証をつけてMQLAuthサーバーで管理できるようにする手順 https://interactivebrokers.work/start_mqlauth/ 口座番号認証でインジケーターを個...

 

バックテスト開始時に口座番号認証を行うコード

//+------------------------------------------------------------------+
//|  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関数を実行しブラウザが開くようにします。シャープがない場合は全体をメッセージとして表示します。

カオチャイ
カオチャイ
上記のコードを実装すれば、MT4から開くサイトのURLは、ソースコードを編集しなくてもMQLAuthの管理画面から編集ができるようになります!
yuki
yuki
管理画面の操作方法は次を御覧くださいね

 

MQLAuth管理画面よりURLの変更

カオチャイ
カオチャイ
URLの変更を行うには、MQLAuth【ユーザー管理】画面にEAを登録した状態でEAの名前の右側にある【編集】をクリックします

 

インジケーター設定画面【ユーザー管理】→登録してあるEAの【編集】をクリック

 

リンク

この画面でメッセージを設定し、シャープの後にURLを書くと、チャート上のテキスト(ラベル)がリンクに変わります。

URLを変えたいときはここで編集すればよいので、いちいちソースコードをコンパイルして配布しなおす必要はありません。

 

yuki
yuki
他のMQLAuth応用編の記事は下記に用意していますので、ぜひ参考にしてくださいね
MQL実装例
【コピペでOK】RSIのEAに口座認証や一括メッセージ機能を実装してみました https://interactivebrokers.work/start_mqlauth/ 個人でEAを販売する際につけてお...
MQL実装例
【コピペでOK】バイナリーオプションサインツールに体験版機能を機能を実装してみました https://interactivebrokers.work/start_mqlauth/ 体験版機能付きのBO用サインツー...