我有一个EA(即机器人),我希望人们将其安装在PC上。是否可以根据订阅条件从我的PC激活或停用它?说明:如果A先生已订阅本月,我将是从我的PC激活它的人。这意味着,即使EA在其系统上,他们也将无法激活或停用它。
您可以使用PC(需要确保您具有静态IP地址,然后启动Web应用程序)。租用VPS比较简单。然后,使用REST Web服务和管理面板创建一个简单的Web应用程序(可能使用Django(Python)或PHP)。
EA端:每个机器人都经过编译,并向客户端提供EX4文件。您的客户将http://yourwebsite.org/添加到MT4中允许的URL列表中,然后使用EA。当EA附加到图表上时,OnInit()
将调用函数,使用WebRequest()
该块内的函数让您的EA联系您的网站,并询问它是否可以工作(客户端可能会通过登录名和密码,或者帐号和经纪人名称(如果使用网络服务器会接收到该数据并进行验证。
另一个问题是如何让您的EA工作一段时间。最简单的方法是每天使用相同的验证请求调用一次Web服务器(随机时间似乎更好)。如果验证失败-EA停止工作。
最后,考虑一下如何停用EA ...可能会发生EA开出大量交易和挂单,并且如果EA杀死了自己ExpertRemove()
,这些交易将保留在MT4中。因此,最好通知客户EA不再处于活动状态,并遵循现有订单,在可能的情况下保持收支平衡,或者根据您的EA逻辑选择其他解决方案,这会更好。以下代码对某些客户有效,没有任何投诉,欢迎您使用它(使用超级管理员,密码(如果需要)和域名)。
class CLicenseOnline : public CObject
{
private:
string m_login;
string m_password;
datetime m_nextCheck;
int m_prevResult;
string m_url;
int m_strategyId;
public:
CLicenseOnline(const string login,const string password,const int id):
m_login(login),m_password(password),m_nextCheck(0),m_strategyId(id),m_prevResult(-1)
{
bool isCheckingRequired=false;
if(CLicenseOnline::isSuperAdmin(login,password))
{
printf("%i %s - Hello, SUPER ADMIN!",__LINE__,__FILE__);
isCheckingRequired=true;
}
isCheckingRequired= isCheckingRequired || IsTesting();
if(isCheckingRequired)
{
m_nextCheck=INT_MAX;
m_prevResult=1;
}
else
{
m_url=CLicenseOnline::genUrl(login,password);
}
}
~CLicenseOnline(){}
int check()
{
if(TimeCurrent()>m_nextCheck)
{
int result=this.checkMain();
switch(result)
{
case 1: m_nextCheck=this.generateNextDate(); m_prevResult=1;break;
default:
case 0: m_nextCheck=TimeCurrent()+PeriodSeconds(PERIOD_M1); m_prevResult=0;break;
case-1: m_nextCheck=TimeCurrent()+PeriodSeconds(PERIOD_H1); m_prevResult=-1;break;
}
}
return(m_prevResult);
}
static string genUrl(const string login,const string password)
{
const string http="localhost";
return(StringFormat("http://%s/verify/?Login=%s&&Password=%s&&Check=%d",http,login,password,2147483647));
}
static string getHttpResponce(const string url)
{
char data[],res[];
string cookies=NULL, headers=NULL,result;
ResetLastError();
int answer = WebRequest("GET",url,cookies,NULL,5000,data,0,res,headers);
if(answer==200)
{
result = CharArrayToString(res);
return(result);
}
//printf("%i - result=%d|%s|size=%d; %d",__LINE__,answer,result,ArraySize(res),GetLastError());
return(NULL);
}
private:
static bool isSuperAdmin(const string login,const string password)
{
static string
superAdminLogin="Admin",
superAdminPassword="password";
//ATTENTION! Edit the login and password here!
return login==superAdminLogin && password==superAdminPassword;
}
datetime generateNextDate()const
{
return(iTime(_Symbol,PERIOD_D1,0)+PeriodSeconds(PERIOD_D1)+MathRand()%PeriodSeconds(PERIOD_D1));
}
int checkMain()const
{
string respond=CLicenseOnline::getHttpResponce(m_url);
if(respond==NULL)
return(0);//try later
CJAVal js(NULL,jtUNDEF);
if(!js.Deserialize(respond))
{
printf("%i %s - failed to deserialize %s",__LINE__,__FUNCTION__,respond);
return(-1);
}
int retCode=(int)js["key"].ToInt();
switch(retCode)
{
case -1: Alert("incorrect password");return(0);
case -2: Alert("incorrect key!");return(0);
case -3: Alert("incorrect request method!");return(0);
case -4:
case -5: Alert("no such login");return(0);
default:
Alert(StringFormat("%i %s - incorrect login/password/no such user!",__LINE__,__FUNCTION__));
return(0);
case 200:
{
CJAVal *valueJs=js["value"];
if(!this.checkStatus(valueJs["Status"].ToStr()))
return(-1);
if(!this.checkAccount(
(int)valueJs["Allow_account_1"].ToInt(),(int)valueJs["Allow_account_2"].ToInt(),(int)valueJs["Allow_account_3"].ToInt()))
return -1;
bool strategyX=(bool)valueJs["Allow_strategy_"+(string)m_strategyId].ToBool();
if(!stategyX)
{
return(-1);
}
return(1);
}
}
return(-1);
}
bool checkStatus(const string status)const
{ //printf("%i %s - status = |%s|%d",__LINE__,__FUNCTION__,status,IsDemo());
if(status=="demo")
{
if(!IsDemo())
{
string message=StringFormat("your login %s is allowed to trade on Demo accounts only!",m_login);
Alert(message);
printf("%i %s - %s",__LINE__,__FILE__,message);
return(false);
}
return(true);
}
if(status!="active")
{
string message=StringFormat("status of your login [%s] is [%s] so not allowed to trade!",m_login,status);
Alert(message);
printf("%i %s - %s",__LINE__,__FILE__,message);
return(false);
}
return(true);
}
bool checkAccount(const int acc1,const int acc2,const int acc3)const
{
if(acc1==0 && acc2==0 && acc3==0)
return(true);
int currentAccount=AccountNumber();
if(acc1==currentAccount || acc2==currentAccount || acc3==currentAccount)
return(true);
string message=StringFormat("allowed accounts are only %d, %d and %d, your account %d is not allowed!",acc1,acc2,acc3,currentAccount);
Alert(message);
printf("%i %s - %s",__LINE__,__FUNCTION__,message);
return(false);
}
};
非常感谢Daniel