当你投入了大量心血,终于开发出一款能稳定盈利的EA时,你可能会考虑将它商业化,或者至少,希望能安全地分享给朋友测试。这时,我们就必须为EA加上一把“锁”,以确保它不会被随意复制和滥用。
今天,我们就来学习如何为我们的EA打造一套简单而有效的授权机制。
授权第一步:在“大门口”安检 —— OnInit()
函数
我们所有的授权检查,都应该放在OnInit()
函数的最开始部分。
OnInit()
是EA的“大门口保安”,是EA加载时第一个执行的函数。在这里进行验证,如果“访客”(当前账户)身份不符,保安可以直接“拒绝入内”(return(INIT_FAILED)
),EA的核心逻辑OnTick()
将永远没有机会被执行。这是最高效、最安全的做法。
“锁”的类型一:免费“试驾版”—— IsDemo()
如果你想提供一个功能齐全的演示版,让潜在客户在模拟账户上“试驾”,IsDemo()
函数是你最好的朋友。它会检测当前账户是否为模拟盘。
我们可以设定规则:本EA只允许在模拟账户上运行。
// 在 OnInit()函数的早期进行检查
if (IsDemo() == false) // 如果当前不是模拟账户
{
Alert("重要提示:此 EA 版本仅限在模拟账户上使用!");
// ExpertRemove(); // 可以选择直接移除EA
return(INIT_FAILED); // 推荐返回 INIT_FAILED 阻止EA加载
// MQL4 中可以在 init() 返回非0值,或在 start() 中 return(0)
}
这样,当用户尝试将它加载到真实账户时,EA会弹窗警告并拒绝启动。
“锁”的类型二:指定用户授权 —— 基于账户信息
这是最主流的商业授权方式,相当于给客户一张“专属门禁卡”,这张卡只能打开他自己那一个账户的门。
最常用、最可靠的“卡号”就是账户ID (AccountNumber()
)。
// 假设您为客户 123456 授权
long authorizedAccount = 123456; // 将客户账号硬编码或通过其他安全方式获取
if (AccountNumber() != authorizedAccount)
{
Alert("授权失败:当前账户 (", AccountNumber(), ") 未被授权使用此 EA!");
// ExpertRemove();
return(INIT_FAILED); // 或其他终止方式
}
当你为客户交付EA时,只需将他的交易账号写入代码,然后编译一个专属版本发给他即可。
其他验证信息:
AccountName()
: 账户持有人姓名。AccountBroker()
: 经纪商服务器名称。
学长建议:尽量使用AccountNumber()
作为唯一的授权凭证。因为账户名可能存在多种写法(比如大小写、缩写),经纪商的服务器名也可能变更,只有账户ID是独一无二且固定不变的。
学长忠告:关于MQL4代码安全的残酷现实
在你决定将EA商业化时,必须清醒地认识到一个事实:不存在100%无法破解的MQL4程序。
你交付给客户的.ex4
文件虽然是编译后的可执行文件,但市面上始终存在“反编译”工具,有决心、有技术的破解者,有可能将你的.ex4
文件逆向工程,还原成一份虽然混乱但逻辑可读的源代码。
我们设置授权的目的,不是为了打造一个绝对无法攻破的保险库,而是增加破解的难度和成本,让破解行为变得得不偿失。对于99%的普通用户和场景而言,我们上面提到的基于AccountNumber()
的授权方式,已经足够有效。
如果你真的要构建非常严肃的商业级产品,更专业的做法是,将你EA最核心的“独门秘籍”(例如交易算法),封装到一个外部的.dll
动态链接库中,让EA在运行时去调用它。这样,破解者需要同时具备MQL4和C++(或其它语言)的逆向工程能力,门槛会高出几个数量级。但对于我们大多数开发者而言,从一个简单可靠的账户授权开始,是完全足够且最务实的选择。