「良いEAができたので誰かに配布・販売したいけど、
そのままだとコピーされて勝手に使われてしまう」——そんな悩みを解決するのが口座縛りです。
この記事では、MQL4でEAやインジケーターに口座縛りをかける3つの方法を、
実際にMetaEditorでコンパイルできるコード付きで解説します。
ネットでよく見かける口座縛りのサンプルコードは、
`OnTick()`(相場が動くたびに呼ばれる関数)の中でパスワード判定をしており、
判定に失敗した際の`return`の書き方を誤って、
そのままではコンパイルが通らないものが少なくありません。
この記事のコードは、判定をEA起動時に一度だけ実行される`OnInit()`に移し、
実際にコンパイルが通る形に整えています。
・なぜ口座縛りが必要なのか
・OnInit()で判定するべき理由(OnTick()判定の問題点)
・3つの口座縛り方法のコードと使い分け
口座縛りが必要な理由(配布・販売時のコピー対策)
良いEAができた場合、誰かに渡す際に何かしらの制限をかけておかないと、
コピーされる可能性があります。
EAに制限をかける必要性
ですので、EAに制限をかける必要があります。
この記事で紹介する3つの方法
EAの制限を掛ける方法は
- 固定のパスワードで制限する方法
- コンパイル時に口座縛りする方法
- 口座番号からパスワードを作って口座縛りをかける
それぞれの方法は一長一短があるので使い分けて活用することをオススメします。
OnInit()で判定すべき理由(OnTick()判定の問題点)
いずれの方法も共通して、
**判定はOnTick()ではなくOnInit()で1回だけ行う**ように修正しています。
OnTick()で判定する場合の問題点
OnTick()は相場が動くたびに何度も呼ばれる関数のため、
毎回パスワード判定を実行するのは無駄が多いうえ、
判定に失敗した場合の`return`の書き方を誤ると、
コンパイルエラーの原因になります(元記事で実際に起きていた問題です)。
OnInit()が適している理由
OnInit()はEA起動時に一度だけ呼ばれる関数で、
失敗時に`INIT_FAILED`を返すとEA自体が起動しないため、
口座縛りの目的にも合っています。
・OnTick(): 相場が動くたびに何度も呼ばれる関数
・OnInit(): EA起動時に一度だけ呼ばれる関数
・INIT_FAILED: OnInit()がこれを返すとEAが起動しない
固定のパスワードで制限する方法
3つの方法の1つ目、固定パスワードによる制限方法を見ていきます。
固定のパスワードで制限する方法は簡単です。
これは比較的に簡単ですが、ソースコード内に適当にパスワードを作成して、
パラメーターで認証させる方法です。
しかし、EAとパスワードが流出するとすぐにバレてしまうのでセキュリティは低いです。
**正解のパスワードは、利用者が入力するinput変数とは別に、
ソースコード側に埋め込んでおく**必要があります。
元のコードは正解パスワードと利用者入力のデフォルト値が同じ文字列になっており、
パラメーターを一切変更しなくてもそのまま通ってしまう(縛りとして機能しない)状態でした。
#define SECRET_PASSWORD "SetYourOwnPassword123"//配布者が決める正解のパスワード(ソースコード側に埋め込む)
input string Password = "";//利用者がここにパスワードを入力する
int OnInit()
{
if(Password != SECRET_PASSWORD)
{
Alert("Passwordが違います。EAを起動できません。");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
void OnTick()
{
/*メインコード*/
}
`SECRET_PASSWORD`は配布前に自分だけの文字列に書き換えてコンパイルし、
購入者にはコンパイル済みの.ex4ファイルと一緒にパスワードだけを別途伝えます。
ソースコード自体を渡すとパスワードも見えてしまうので、
配布時はコンパイル後のファイルのみを渡してください。
コンパイル時に口座番号・口座名義で縛る方法
2つ目の方法、ユーザーごとにコンパイルし直して縛る方法を見ていきます。
コンパイル時に口座縛りする方法は非常に簡単です。
ソースコードに
- 口座番号
- FX業者
- ユーザー名
などを指定し、組合せ以外にユーザーはEAが稼働しないようにします。
多くの口座縛りはこの方法を活用していることが多いです。
しかし、ソースコードを編集してユーザー毎にコンパイルする必要があります。
input int AllowedAccountNumber = 1234567;//許可する口座番号
input string AllowedAccountName = "Taro Yamada";//許可する口座名義
int OnInit()
{
if(AccountNumber() != AllowedAccountNumber || AccountName() != AllowedAccountName)
{
Alert("使用許可していないユーザーです。EAを起動できません。");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
void OnTick()
{
/*メインコード*/
}
`AllowedAccountNumber`と`AllowedAccountName`は、
ユーザーごとに実際の口座番号・口座名義に書き換えてからコンパイルしてください。
口座番号からパスワードを作って口座縛りをかける方法
3つ目の方法、口座番号から計算したパスワードで縛る方法を見ていきます。
例えば、口座番号が123456789だったとします。
その場合、(一桁目の数字)*4+(二桁目の数字)*3+(3桁目の数字)*2の
答えである1*4+2*3+3*2=16をパスワードにして、
パラメータ設定でこの数値を入力しないとEAが稼働しないようにします。
口座番号からパスワードを作るメリットとしては、
- EAを毎回コンパイルしなくて良い
- EAを先にばらまいてからパスワードを発行できる
という点です。
input int Password = 16;//パスコード(口座番号の上3桁から計算)
int OnInit()
{
int generatedPass = StringToInteger(StringSubstr(IntegerToString(AccountNumber()),0,1))*4
+ StringToInteger(StringSubstr(IntegerToString(AccountNumber()),1,1))*3
+ StringToInteger(StringSubstr(IntegerToString(AccountNumber()),2,1))*2;
if(Password != generatedPass)
{
Alert("Passwordが違います。EAを起動できません。");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
void OnTick()
{
/*メインコード*/
}
実際に配布する際は、購入者から口座番号を教えてもらい、
上記の計算式でパスワードを計算して伝えてください。
よくある質問
口座縛りについて、よくある疑問に回答します。
・いずれの方法もソースコードを渡すとパスワードや判定条件が見えてしまう
・配布はコンパイル後の.ex4ファイルのみにする
・絶対に破られない方法ではなく、簡易的な抑止策である
3つの方法はどう選べばいいですか?
手軽さを重視するなら固定パスワード、
セキュリティを少しでも上げたいなら口座番号・口座名義での縛り、
コンパイルの手間を省きたいなら口座番号からパスワードを生成する方法が向いています。
この方法だけで販売用EAとして十分ですか?
この記事の方法は簡易的な抑止策です。
本格的に販売する場合は、より強固な保護方法も併用することを検討してください。
【MT4】MQLでEAやインジケーターの口座縛りの作り方:まとめ
今回は様々な口座縛りの方法をご紹介しました。
もっと強力な口座を縛る方法などもあるのですが、簡易的なものをお伝えしました。
もし、有料で販売する際や配布する際にこうしたソースコードを活用してみてください。
コメント