Protecting Indicators and EA's

 

Hi guys!

I would like to sell Indicators (and perhaps EA's) in the META MARKET and directly too (outside the MARKET).

I'm reading about how to effectively protect an Indicator (or an EA) for EVALUATION PURPOSES (for the bought versions I can provide a good scheme based on the user account).

I had read about GlobalVariables schemes (eg. creating a FirstUseDate and save it) and I think it is too easy for any user delete it and restart the evaluation term. At the same time, I read about the "MQL5 Cloud Protection" but I'm afraid it is specifically to protect the code against disassembly. Also, I don't want any WEB service to provide a reliable SQLITE database (or something like that) to check online evaluation users and also, I guess it is not so secure for advanced users.

I read the following article (https://www.mql5.com/en/articles/359) but I didn't see a valid scheme to control the users in EVALUATION.

Do you have any idea to provide a good security on this?

I appreciate any tip or article.

Securing MQL5 code: Password Protection, Key Generators, Time-limits, Remote Licenses and Advanced EA License Key Encryption Techniques
Securing MQL5 code: Password Protection, Key Generators, Time-limits, Remote Licenses and Advanced EA License Key Encryption Techniques
  • www.mql5.com
Most developers need to have their code secured. This article will present a few different ways to protect MQL5 software - it presents methods to provide licensing capabilities to MQL5 Scripts, Expert Advisors and Indicators. It covers password protection, key generators, account license, time-limit evaluation and remote protection using MQL5-RPC calls.
 

Maybe this will help ...

It's is old code but should still work, on both MQL4 and MQL5.

Forum on trading, automated trading systems and testing trading strategies

EA limit code

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
//+------------------------------------------------------------------------------------+
 
Fernando Carreiro #:

Maybe this will help ...

It's is old code but should still work, on both MQL4 and MQL5.

Thank you very much Fernando, but my problem is related to the time/clients under EVALUATION.

I mean, I would like to have an automated mechanism to provide a good evaluation term scheme, without the need for constant updates due to "expiration time". Also, I could utilize a DLL to perform this job (better to handle my needs), but doing so I will be restricted to users that operate in a "local" environment only (VPS does not accept DLL).

But, the idea of allowing the usage on DEMO-ACCOUNT mode only is really good, although I know people that, in the case of INDICATORS, would utilize them in another MT5 instance as a "signaler" for all the time.
 
AliceRioBR #: Thank you very much Fernando, but my problem is related to the time/clients under EVALUATION. I mean, I would like to have an automated mechanism to provide a good evaluation term scheme, without the need for constant updates due to "expiration time". Also, I could utilize a DLL to perform this job (better to handle my needs), but doing so I will be restricted to users that operate in a "local" environment only (VPS does not accept DLL).

If you will not be using a web licensing (or something equivalent via DLL), then there is no other option except to "hard code" the evaluation time and other restrictions in the code at compile time.

One possible solution, is to create an automated compilation procedure, by calling MetaEditor via the command prompt to compile the code with different evaluation options, such as evaluation time and account restrictions.

EDIT: This is why selling via the "Market", is the easier option.

 
AliceRioBR:

Hi guys!

I would like to sell Indicators (and perhaps EA's) in the META MARKET and directly too (outside the MARKET).

I'm reading about how to effectively protect an Indicator (or an EA) for EVALUATION PURPOSES (for the bought versions I can provide a good scheme based on the user account).

I had read about GlobalVariables schemes (eg. creating a FirstUseDate and save it) and I think it is too easy for any user delete it and restart the evaluation term. At the same time, I read about the "MQL5 Cloud Protection" but I'm afraid it is specifically to protect the code against disassembly. Also, I don't want any WEB service to provide a reliable SQLITE database (or something like that) to check online evaluation users and also, I guess it is not so secure for advanced users.

I read the following article (https://www.mql5.com/en/articles/359) but I didn't see a valid scheme to control the users in EVALUATION.

Do you have any idea to provide a good security on this?

I appreciate any tip or article.

You could go with a server and a registration on your site , but then the issue is that you would have to be relying on the registrations being legit . That would result in needing an external "entity" for validation , i.e. only accept registrations via facebook as it would require more steps to create a fake account there etc.

This is why so many trial versions usually require a valid credit card number up front even if the trial is free .

The demo idea is your best option at this level , or , if the demo was just a limited showcase of past signals . For instance i've seen a demo of a patterns scanner given out for free but it scans up to one month ago , you can't see the trading in action however .

You could also limit by symbol and timeframe .

EDIT : If you go with the server solution , you could offer one symbol for free completely (a specific one not a user's choice) and charge for packs for additional ones . From a personal experience to something similar as a client , in a side project with football , we were looking for a data vendor and there was one who offered a small league for free completely , and another one who was the usual "contact us for a demo" . We chose what we could test . (a bit off-topic but this is how your clients will feel) 

 
Fernando Carreiro #:

If you will not be using a web licensing (or something equivalent via DLL), then there is no other option except to "hard code" the evaluation time and other restrictions in the code at compile time.

One possible solution, is to create an automated compilation procedure, by calling MetaEditor via the command prompt to compile the code with different evaluation options, such as evaluation time and account restrictions.

EDIT: This is why selling via the "Market", is the easier option.

Fernando, 

Is the Market ready for an evaluation scheme independently of our code or "GlobalVariables"?

I appreciate your whole time and help.

 
Lorentzos Roussos #:

You could go with a server and a registration on your site , but then the issue is that you would have to be relying on the registrations being legit . That would result in needing an external "entity" for validation , i.e. only accept registrations via facebook as it would require more steps to create a fake account there etc.

This is why so many trial versions usually require a valid credit card number up front even if the trial is free .

The demo idea is your best option at this level , or , if the demo was just a limited showcase of past signals . For instance i've seen a demo of a patterns scanner given out for free but it scans up to one month ago , you can't see the trading in action however .

You could also limit by symbol and timeframe .

EDIT : If you go with the server solution , you could offer one symbol for free completely (a specific one not a user's choice) and charge for packs for additional ones . From a personal experience to something similar as a client , in a side project with football , we were looking for a data vendor and there was one who offered a small league for free completely , and another one who was the usual "contact us for a demo" . We chose what we could test . (a bit off-topic but this is how your clients will feel) 

Thank you Lorentzos, your ideas and feeling about the code availability are really valid.

I'll consider it in my analysis.

 
AliceRioBR #:Fernando, Is the Market ready for an evaluation scheme independently of our code or "GlobalVariables"?

I appreciate your whole time and help.

What do you mean?

The Market products cannot have any imposed limitations?

And what does "Global Variables" have to do with it?

 
Fernando Carreiro #:

What do you mean?

The Market products cannot have any imposed limitations?

And what does "Global Variables" have to do with it?

I mean that I saw recommendations for using "GlobalVariablesSet" as a kind of time-scheme, in case of Evaluation period. This way, you save the "Start-Date" in GlobalVariable and can check the past days.

My question is about what kind of mechanisms the Meta Market offers to us to control the evaluation time, if applicable, or if we need to control all aspects of these limitations in our code.

 
AliceRioBR #: I mean that I saw recommendations for using "GlobalVariablesSet" as a kind of time-scheme, in case of Evaluation period. This way, you save the "Start-Date" in GlobalVariable and can check the past days.

My question is about what kind of mechanisms the Meta Market offers to us to control the evaluation time, if applicable, or if we need to control all aspects of these limitations in our code.

You can't set "Evaluation" periods in Market products. It is against the rules.

There must be no limitations on Market products because licensing is managed by the MetaQuotes mechanism.

 
I think the straight forward way of achieving this is to use MQL5 licensing or otherwise you hard-code the restriction in your code yourself using the above-mentioned code or some variation of it. Otherwise, you gonna have to incorporate DLLs or online servers' activation which its assistance is provided by some other forums that deals with licensing and encryptions. 
Reason: