口座番号認証はパスワードよりも安全
口座番号認証はパスワードに比べてセキュリティが強固なのでおすすめです。
パスワードはパスの管理が必要ですが、口座番号認証はパスワードのような入力の必要がありませんし、MQLAuthを使えばお客さんが自由に口座番号の変更もできますので手間もありません。
パスワードによる利用制限は、期限付きの体験版のような使い方をすると良いかもしれません。
2020年末まで利用できる体験版EAの実装例です。TimeLocal()やTimeGMT()を使うとパソコンの時刻を変更するという荒業で回避されることもあるので、TimeCurrent()を使う方が良いです。 pic.twitter.com/kjYziXNovg— EA認証サービス「MQLAuth」 (@MQLAuth) September 24, 2020
また、パスワード認証はEAの作り方によっては力技で突破されることもありますが、口座番号認証の場合は口座自体を乗っ取るという方法でもしない限り、第三者が利用することが出来ないので安心です。
MetaEditorでインジケーターの.mq4を作ります
新規作成でファイルを作ります(画像はクリックで拡大できます)
ファイルはお好きな名前をつけてください。
EAの認証にはOnTimerを利用しましたが、BO用のサインインジケーターではOnTimerは使いません。一番上のOnCalculateにのみマークし、「次へ」をクリックします。
これでMetaEditorで自動生成されるインジケーターのテンプレートが表示されました。
実際にコードを書き込んでいきます
#define MQLAUTH_ID "" // 追加した行
#define APPLICATION_NAME "" // 追加した行
#property copyright "©2020 MT4ツール製作【シストレファクトリー】"
#property link "https://interactivebrokers.work/"
#property version "1.00"
#property strict
#property indicator_chart_window
まずはMQLAUTH_IDとAPPLICATION_NAMEをdefineで宣言します。
MQLAUTH_IDにはご自身のMQLAuthIDを、APPLICATION_NAMEには登録してあるインジケーター名を入れてくださいね。
#define MQLAUTH_ID "ed3d8eed-3806-4934-bafa-e25e434341f0"
#define APPLICATION_NAME "SampleIndicator"
#include <MQLAuth.mqh> // 追加した行
#property copyright "©2020 MT4ツール製作【シストレファクトリー】"
#property link "https://interactivebrokers.work/"
#property version "1.00"
#property strict
MQLAuthのインクルードファイルをインクルードします。
口座認証部分を実装していきます
bool _isConfirmed = false; // 認証が済んだかどうかを示す。true:認証済み/false:未認証
bool _isAuthorized = false; // 認証が成功したかどうかを示す。true:認証成功/false:認証失敗
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[])
{
return(rates_total);
}
BO用のサインインジケーターの認証は、OnCalculate内で行います。
OnCalculateはティック毎に実行されますが、毎回認証を行うとティック毎の処理が遅くなるため、初めてのときのみ認証を実行するようにしましょう。
まずは認証が済んだかどうかを示すグローバル変数と、認証が成功したかどうかを示すグローバル変数を用意します。
bool _isConfirmed = false; // 認証が済んだかどうかを示す。true:認証済み/false:未認証
bool _isAuthorized = false; // 認証が成功したかどうかを示す。true:認証成功/false:認証失敗
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[]) {
if(!_isConfirmed && AccountInfoInteger(ACCOUNT_LOGIN) != 0) { // 追加した行
_isConfirmed = true; // 追加した行
} // 追加した行
return(rates_total);
}
認証が済んでおらず(_isConfirmed == false)、かつ口座番号が取得できる状態になったら(AccountInfoInteger(ACCOUNT_LOGIN) != 0)、認証を行うようにします。
一度認証したら再度行わないように、_isConfirmedにtrueを入れておきます。
bool _isConfirmed = false; // 認証が済んだかどうかを示す。true:認証済み/false:未認証
bool _isAuthorized = false; // 認証が成功したかどうかを示す。true:認証成功/false:認証失敗
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[]) {
if(!_isConfirmed && AccountInfoInteger(ACCOUNT_LOGIN) != 0) {
_isConfirmed = true;
// ここから追加
if(AuthByAccountNumber_ReturnBool(MQLAUTH_ID, APPLICATION_NAME)) {
_isAuthorized = true;
Print("口座認証に成功しました。");
} else {
_isAuthorized = false;
Alert("口座認証に失敗しました。利用期限が過ぎているか、この口座番号では利用できません。");
}
// 追加ここまで
}
return(rates_total);
}
MQLAuthの認証を書きます。認証が成功したら_isAuthorizedをtrueに、失敗したらfalseをいれて、さらにアラートで警告します。
アラートの警告はラベルにしてチャート上に表示するのもよくあるやり方です。
bool _isConfirmed = false; // 認証が済んだかどうかを示す。true:認証済み/false:未認証
bool _isAuthorized = false; // 認証が成功したかどうかを示す。true:認証成功/false:認証失敗
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[]) {
if(!_isConfirmed && AccountInfoInteger(ACCOUNT_LOGIN) != 0) {
_isConfirmed = true;
if(AuthByAccountNumber_ReturnBool(MQLAUTH_ID, APPLICATION_NAME)) {
_isAuthorized = true;
Print("口座認証に成功しました。");
} else {
_isAuthorized = false;
Alert("口座認証に失敗しました。利用期限が過ぎているか、この口座番号では利用できません。");
}
}
if(!_isAuthorized) return(0); // この行を追加
return(rates_total);
}
認証に失敗したら、OnCalculateを実行しないようreturnします。
このとき、rates_totalに0を入れるために、return(0)とします。
bool _isConfirmed = false; // 認証が済んだかどうかを示す。true:認証済み/false:未認証
bool _isAuthorized = false; // 認証が成功したかどうかを示す。true:認証成功/false:認証失敗
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[]) {
if(!_isConfirmed && AccountInfoInteger(ACCOUNT_LOGIN) != 0) {
_isConfirmed = true;
if(AuthByAccountNumber_ReturnBool(MQLAUTH_ID, APPLICATION_NAME)) {
_isAuthorized = true;
Print("口座認証に成功しました。");
} else {
_isAuthorized = false;
Alert("口座認証に失敗しました。利用期限が過ぎているか、この口座番号では利用できません。");
}
}
if(!_isAuthorized) return(0);
/// ここから追加
int limit;
if (prev_calculated == 0)
limit = rates_total - 1;
else
limit = rates_total - prev_calculated;
for(int i = limit; i >= 0; i--) {
// インジケーターの処理
}
// 追加ここまで
return(rates_total);
}
あとはインジケーターの処理部分を追加して、認証の実装は完了です。
for文の書き方は0からインクリメントしたりBarsの未計算部分からデクリメントしたりと、好みの書き方がありますが、書き方によってはarray out of rangeエラーの原因になったり、計算されないローソク足が出たりと難しい部分でもあります。
シストレファクトリーのスタッフがいろいろ試した結果、このサンプルの書き方が一番不具合を起こしにくい書き方でしたので、よくわからない方はこのままコピーするといいでしょう。
今回作成したコード
//+------------------------------------------------------------------+
//| BOIndicatorAuthSample.mq4 |
//| ©2020 MT4ツール製作【シストレファクトリー】 |
//| https://interactivebrokers.work/ |
//+------------------------------------------------------------------+
#define MQLAUTH_ID ""
#define APPLICATION_NAME ""
#include <MQLAuth.mqh>
#property copyright "©2020 MT4ツール製作【シストレファクトリー】"
#property link "https://interactivebrokers.work/"
#property version "1.00"
#property strict
#property indicator_chart_window
int OnInit() {
return(INIT_SUCCEEDED);
}
bool _isConfirmed = false; // 認証が済んだかどうかを示す。true:認証済み/false:未認証
bool _isAuthorized = false; // 認証が成功したかどうかを示す。true:認証成功/false:認証失敗
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[]) {
if(!_isConfirmed && AccountInfoInteger(ACCOUNT_LOGIN) != 0) {
_isConfirmed = true;
if(AuthByAccountNumber_ReturnBool(MQLAUTH_ID, APPLICATION_NAME)) {
_isAuthorized = true;
Print("口座認証に成功しました。");
} else {
_isAuthorized = false;
Alert("口座認証に失敗しました。利用期限が過ぎているか、この口座番号では利用できません。");
}
}
if(!_isAuthorized) return(0);
int limit;
if (prev_calculated == 0)
limit = rates_total - 1;
else
limit = rates_total - prev_calculated;
for(int i = limit; i >= 0; i--) {
// インジケーターの処理
}
return(rates_total);
}
#define MQLAUTH_ID “” //””内に自分のMQLAUTH_IDを記入する
#define APPLICATION_NAME “” // “”内に自分の登録したEA・インジケーター名に書き換える(※ユーザー名ではないので注意)