Bom dia!!
investeo, 2014.02.20 15:12
A maioria dos desenvolvedores precisa ter seu código protegido. Este artigo apresentará alguns meios diferentes para proteger o software MQL5 - ele apresenta métodos para fornecer recursos de licenciamento para Scripts do MQL5, Exper Advisors e Indicadores. Ele cobre a proteção de senha, geradores de chave, licença de conta, avaliação de limite de tempo e proteção remota usando chamadas MQL5-RPC.Veja também o seguinte antigo post do forum em Inglês ...
Forum on trading, automated trading systems and testing trading strategies
Fernando Carreiro, 2017.09.10 22:17
Here is a sample of my own code that I use, but it is up to you to implement properly. I'm not offering any support on it. It is up to you to do the necessary research and learning.
//+------------------------------------------------------------------------------------+ // Initialisation Event Function //+------------------------------------------------------------------------------------+ int OnInit() { // Check Licensing Restrictions if( boolRestrictOnInit() ) return( INIT_FAILED ); // ... return( INIT_SUCCEEDED ); // Initialisation complete } //+------------------------------------------------------------------------------------+ // Tick Event Function //+------------------------------------------------------------------------------------+ void OnTick() { // Check Licensing Restrictions if( boolRestrictOnTick() ) return; /// ... } //+------------------------------------------------------------------------------------+ // Function to Test Restrictions during Initialisation //+------------------------------------------------------------------------------------+ bool boolRestrictOnInit() { boolRestrictions = boolRestrictExpiration || boolRestrictAccountNumber || boolRestrictAccountName || boolRestrictAccountServer || boolRestrictAccountCompany || boolRestrictDemoAccount || boolRestrictSymbols; if( boolRestrictions ) { boolRestrictionsUnverified = true; if( (bool) TerminalInfoInteger( TERMINAL_CONNECTED ) ) { long longAccountNumber = AccountInfoInteger( ACCOUNT_LOGIN ); if( longAccountNumber > 0 ) { if( boolRestrictAccountNumber ) { if( longAccountNumber != longRestrictAccountNumber ) { return( boolRestrictAlert() ); } } if( boolRestrictAccountName ) { if( AccountInfoString( ACCOUNT_NAME ) != strRestrictAccountName ) { return( boolRestrictAlert() ); } } if( boolRestrictAccountServer ) { if( AccountInfoString( ACCOUNT_SERVER ) != strRestrictAccountServer ) { return( boolRestrictAlert() ); } } if( boolRestrictAccountCompany ) { if( AccountInfoString( ACCOUNT_COMPANY ) != strRestrictAccountCompany ) { return( boolRestrictAlert() ); } } if( boolRestrictDemoAccount ) { if( AccountInfoInteger( ACCOUNT_TRADE_MODE ) != ACCOUNT_TRADE_MODE_DEMO ) { return( boolRestrictAlert() ); } } if( boolRestrictSymbols() ) { return( boolRestrictAlert() ); } boolRestrictionsUnverified = false; } } } return( false ); } //+------------------------------------------------------------------------------------+ // Function to Test Variations of Restricted Symbols //+------------------------------------------------------------------------------------+ bool boolRestrictSymbols() { if( boolRestrictSymbols ) { int intSymbolCount = ArraySize( strRestrictSymbols ); if( intSymbolCount == 0 ) return( false ); for( int i = 0; i < intSymbolCount; i++ ) { if( StringFind( _Symbol, strRestrictSymbols[i] ) != WRONG_VALUE ) return( false ); int intLen = StringLen( strRestrictSymbols[i] ), intHalf = intLen / 2; string strLeft = StringSubstr( strRestrictSymbols[i], 0, intHalf ), strRight = StringSubstr( strRestrictSymbols[i], intHalf, intLen - intHalf ); if( ( StringFind( _Symbol, strLeft ) != WRONG_VALUE ) && ( StringFind( _Symbol, strRight ) != WRONG_VALUE ) ) return( false ); } return( true ); } return( false ); } //+------------------------------------------------------------------------------------+ // Function to Test Expiration during Tick Events //+------------------------------------------------------------------------------------+ bool boolRestrictOnTick() { if( boolRestrictions ) { if( boolRestrictionsUnverified ) return( boolRestrictOnInit() ); if( boolRestrictExpiration && ( TimeCurrent() >= dtRestrictExpiration ) ) return( boolRestrictAlert() ); } return( false ); } // Function to Alert User of Licensing Restrictions and Remove Code from Execution bool boolRestrictAlert() { if( boolRestrictAlert ) MessageBox( strRestrictAlertMessage, strRestrictAlertCaption, MB_ICONERROR ); ExpertRemove(); return( true ); } //+------------------------------------------------------------------------------------+ // Variables for Handling of Licensing Restrictions //+------------------------------------------------------------------------------------+ bool boolRestrictExpiration = false, // Set to true, to use an Experation Date boolRestrictAccountNumber = false, // Set to true for Restricting by Account Number boolRestrictAccountName = false, // Set to true for Restricting by Account Name boolRestrictAccountServer = false, // Set to true for Restricting by Account Server boolRestrictAccountCompany = false, // Set to true for Restricting by Account Company boolRestrictDemoAccount = false, // Set to true, to only allow Demo Accounts boolRestrictSymbols = false, // Set to true, to only allow certain Symbols boolRestrictAlert = true, // Display Alert Message when Restrictions apply boolRestrictionsUnverified = false, // DO NOT CHANGE. For internal use only! boolRestrictions = false; // DO NOT CHANGE. For internal use only! datetime dtRestrictExpiration = D'2017.03.31'; // Restricted by Expration Date long longRestrictAccountNumber = 123456789; // Restricted by Account Number string strRestrictAccountName = "Client Name", // Restricted by Account Name strRestrictAccountServer = "Server Name", // Restricted by Account Server strRestrictAccountCompany = "Company Name", // Restricted by Account Company strRestrictSymbols[] = { "EURUSD", "GBPJPY", "NZDCAD" }, // Restricted Symbols strRestrictAlertCaption = "Restrictions", // Alert Message Box Caption strRestrictAlertMessage = "ATTENTION! Due to Licensing Restrictions, code execution has been blocked!"; // Message to be used when Restrictions have been detected //+------------------------------------------------------------------------------------+
Tem várias formas de fazer isso online, sem por a venda no marketplace daqui (que tambem é uma forma). Uma bem simples é um gerador de serial, baseado no nome registrado na conta e no login, que você passaria ao cliente.
Uma solução online é a leitura de uma pagina pelo EA (não serve com indicadores) você pode colocar o login na pagina e a EA ler e dar acesso, entre outras soluções dessa forma. E existe ainda as mais elabolaradas, como acesso pelo telegram ou mesmo por banco de dados via metodo post
Tem várias formas de fazer isso online, sem por a venda no marketplace daqui (que tambem é uma forma). Uma bem simples é um gerador de serial, baseado no nome registrado na conta e no login, que você passaria ao cliente.
Uma solução online é a leitura de uma pagina pelo EA (não serve com indicadores) você pode colocar o login na pagina e a EA ler e dar acesso, entre outras soluções dessa forma. E existe ainda as mais elabolaradas, como acesso pelo telegram ou mesmo por banco de dados via metodo post
Ops, o pessoal respondeu enquanto eu escrevia. Otimo artigo, por sinal. Boa solução.
Tem várias formas de fazer isso online, sem por a venda no marketplace daqui (que tambem é uma forma). Uma bem simples é um gerador de serial, baseado no nome registrado na conta e no login, que você passaria ao cliente.
Uma solução online é a leitura de uma pagina pelo EA (não serve com indicadores) você pode colocar o login na pagina e a EA ler e dar acesso, entre outras soluções dessa forma. E existe ainda as mais elabolaradas, como acesso pelo telegram ou mesmo por banco de dados via metodo post
Boa ideia também, obrigado
Erro na criação da Licença Remota
Boa tarde, há um tempo atrás eu estava com dúvidas de como implementar o código de licensa remota para o meu EA, me indicaram o seguinte artigo
https://www.mql5.com/pt/articles/359
Implementei o seguinte código abaixo de acordo com o artigo, codigo para Criar um servidor Localmente, se vocês testarem o código abaixo em Python funciona perfeitamente cria o servidor e adiciona as 2 licenças fictícia
from xmlrpc.server import SimpleXMLRPCServer from xmlrpc.server import SimpleXMLRPCRequestHandler class RequestHandler( SimpleXMLRPCRequestHandler ): rpc_path = ( '/RPC2', ) class RemoteLicenseExample(SimpleXMLRPCServer): def __init__(self): SimpleXMLRPCServer.__init__( self, (localhost:8000), requestHandler=RequestHandler, logRequests = False) self.register_introspection_functions() self.register_function( self.xmlrpc_isValid, "isValid" ) self.licenses = {} def addLicense(self, ea_name, broker_name, account_number): if ea_name in self.licenses: self.licenses[ea_name].append({ 'broker_name': broker_name, 'account_number' : account_number }) else: self.licenses[ea_name] = [ { 'broker_name': broker_name, 'account_number' : account_number } ] def listLicenses(self): print (self.licenses) def xmlrpc_isValid(self, ea_name, broker_name, account_number): isValidLicense = False ea_name = str(ea_name) broker_name = str(broker_name) print ("Request for license", ea_name, broker_name, account_number) try: account_number = int(account_number) except ValueError as error: return isValidLicense if ea_name in self.licenses: for license in self.licenses[ea_name]: if license['broker_name'] == broker_name and license['account_number'] == account_number: isValidLicense = True break print ("License valid:", isValidLicense) return isValidLicense if __name__ == '__main__': server = RemoteLicenseExample() server.addLicense("RemoteProtectedEA", "MetaQuotes Software Corp.", 1024221) server.addLicense("RemoteProtectedEA", "MetaQuotes Software Corp.", 1024223) server.listLicenses() server.serve_forever()
Até aqui tudo bem, executei o código MQL5 abaixo para testar a licensa
Código que cria o EA para fazer o teste das licensas(CODIGO DO ARTIGO)
//+------------------------------------------------------------------+ //| RemoteProtectedEA.mq5 | //| Copyright 2012, Investeo.pl | //| http://www.investeo.pl | //+------------------------------------------------------------------+ #property copyright "Copyright 2012, Investeo.pl" #property link "http://www.investeo.pl" #property version "1.00" #include <MQL5-RPC.mqh> #include <Arrays\ArrayObj.mqh> #include <Arrays\ArrayInt.mqh> #include <Arrays\ArrayString.mqh> #include <Arrays\ArrayBool.mqh> bool license_status=false; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- /* License proxy server */ CXMLRPCServerProxy s("localhost:8000"); if(s.isConnected()==true) { CXMLRPCResult *result; /* Get account data */ string broker= AccountInfoString(ACCOUNT_COMPANY); long account = AccountInfoInteger(ACCOUNT_LOGIN); printf("The name of the broker = %s",broker); printf("Account number = %d",account); /* Get remote license status */ CArrayObj* params= new CArrayObj; CArrayString* ea = new CArrayString; CArrayString* br = new CArrayString; CArrayInt *ac=new CArrayInt; ea.Add("RemoteProtectedEA"); br.Add(broker); ac.Add((int)account); params.Add(ea); params.Add(br); params.Add(ac); CXMLRPCQuery query("isValid",params); result=s.execute(query); CArrayObj *resultArray=result.getResults(); if(resultArray!=NULL && resultArray.At(0).Type()==TYPE_BOOL) { CArrayBool *stats=resultArray.At(0); license_status=stats.At(0); } else license_status=false; if(license_status==true) printf("License valid."); else printf("License invalid."); delete params; delete result; } else Print("License server not connected."); //--- return(0); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- if(license_status==true) { // license valid } } //+------------------------------------------------------------------+
Após a execução do código acima acontece o seguinte erro
'INT_MAX' - expression not boolean ArrayBool.mqh 357 46
Abrir o arquivo ArrayBool.mqh na linha informada
bool CArrayBool::At(int index) const { //--- checking if(index<0 || index>=m_data_total) return(INT_MAX); //--- return(m_data[index]); }
Modifiquei o return(INT_MAX); para return(0); o codigo parou de acontecer o erro. Voltei a executar o código do MQL5(EA) que verifica a licensa ativa mas ele sempre cai no ELSE
Print("License server not connected.");
Como se não encontra-se o servidor, mas quando eu executo o codigo do servidor ele conectar e adiciona as licensas normalmente Por fim não sei como resolve, Novamente deixo o link do artigo, se alguem tiver alguma luz ou ideia diferente compartilhe por favor. Observação: Só tenho interesse em licensa online, não quero recompilar codigo, não quero colocar no mercado do MQL5. https://www.mql5.com/pt/articles/359
- www.mql5.com
@JhonyTygas, por favor não incluir texto livre dentro de secções de código. Torna-se difícil de ler em dispositivos móveis. Já editei o seu comentário para corrigir a situação.
Boa ideia também, obrigado
Erro na criação da Licença Remota
Boa tarde, há um tempo atrás eu estava com dúvidas de como implementar o código de licensa remota para o meu EA, me indicaram o seguinte artigo
https://www.mql5.com/pt/articles/359
Implementei o seguinte código abaixo de acordo com o artigo, codigo para Criar um servidor Localmente, se vocês testarem o código abaixo em Python funciona perfeitamente cria o servidor e adiciona as 2 licenças fictícia
Até aqui tudo bem, executei o código MQL5 abaixo para testar a licensa
Código que cria o EA para fazer o teste das licensas(CODIGO DO ARTIGO)
Após a execução do código acima acontece o seguinte erro
Abrir o arquivo ArrayBool.mqh na linha informada
Modifiquei o return(INT_MAX); para return(0); o codigo parou de acontecer o erro. Voltei a executar o código do MQL5(EA) que verifica a licensa ativa mas ele sempre cai no ELSE
Como se não encontra-se o servidor, mas quando eu executo o codigo do servidor ele conectar e adiciona as licensas normalmente Por fim não sei como resolve, Novamente deixo o link do artigo, se alguem tiver alguma luz ou ideia diferente compartilhe por favor. Observação: Só tenho interesse em licensa online, não quero recompilar codigo, não quero colocar no mercado do MQL5. https://www.mql5.com/pt/articles/359
Falaria pra voltar a modificação do ArrayBool.mqh e corrigir seu codigo pra suportar essa informação, INT_MAX tá lhe dizendo que é invalido porque o array veio vazio ou foi pedido um valor negativo no indice. Fora isso, verifica se o valor indo pros parametros é os mesmo que voce inseriu na hora de criar a licença, se for pode ser erro na classe CXMLRPCQuery que pode estar fazendo o envio errado dos dados por exemplo na hora de converter para envio colocou um byte a mais (mesmo zerado).
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Boa noite pessoal, tenho uma dúvida que acredito que muitos devem ter aqui.
Existe algum tutorial ou artigo que ensine a criar alguma função para podemos limitar o acesso ou copia do nosso expert
Eu tenho esse simples codigo que verifica se uma conta é permitida para usar o EA, mas para cada novo usuário eu tenho que recompilar o codigo com a conta permitida
entretanto gostaria de saber se tem alguma forma de fazer isso Online, por banco de dados ou até mesmo a leitura
de um arquivo txt que esteja hospedado na web.