EA License Coding Experiment

 

//+------------------------------------------------------------------+
//|                                              Moving Averages.mq5 |
//|                             Copyright 2000-2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Trade\Trade.mqh>

input double MaximumRisk        = 0.02;    // Maximum Risk in percentage
input double DecreaseFactor     = 3;       // Descrease factor
input int    MovingPeriod       = 12;      // Moving Average period
input int    MovingShift        = 6;       // Moving Average shift

//---
int    ExtHandle=0;
bool   ExtHedging=false;
CTrade ExtTrade;

#define MA_MAGIC 1234501
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double TradeSizeOptimized(void)
  {
   double price=0.0;
   double margin=0.0;
//--- select lot size
   if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price))
      return(0.0);
   if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin))
      return(0.0);
   if(margin<=0.0)
      return(0.0);

   double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE)*MaximumRisk/margin,2);
//--- calculate number of losses orders without a break
   if(DecreaseFactor>0)
     {
      //--- select history for access
      HistorySelect(0,TimeCurrent());
      //---
      int    orders=HistoryDealsTotal();  // total history deals
      int    losses=0;                    // number of losses orders without a break

      for(int i=orders-1;i>=0;i--)
        {
         ulong ticket=HistoryDealGetTicket(i);
         if(ticket==0)
           {
            Print("HistoryDealGetTicket failed, no trade history");
            break;
           }
         //--- check symbol
         if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol)
            continue;
         //--- check Expert Magic number
         if(HistoryDealGetInteger(ticket,DEAL_MAGIC)!=MA_MAGIC)
            continue;
         //--- check profit
         double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
         if(profit>0.0)
            break;
         if(profit<0.0)
            losses++;
        }
      //---
      if(losses>1)
         lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
     }
//--- normalize and check limits
   double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lot=stepvol*NormalizeDouble(lot/stepvol,0);

   double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   if(lot<minvol)
      lot=minvol;

   double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
   if(lot>maxvol)
      lot=maxvol;
//--- return trading volume
   return(lot);
  }
//+------------------------------------------------------------------+
//| Check for open position conditions                               |
//+------------------------------------------------------------------+
void CheckForOpen(void)
  {
   MqlRates rt[2];
//--- go trading only for first ticks of new bar
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
   if(rt[1].tick_volume>1)
      return;
//--- get current Moving Average 
   double   ma[1];
   if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
     {
      Print("CopyBuffer from iMA failed, no data");
      return;
     }
//--- check signals
   ENUM_ORDER_TYPE signal=WRONG_VALUE;

   if(rt[0].open>ma[0] && rt[0].close<ma[0])
      signal=ORDER_TYPE_SELL;    // sell conditions
   else
     {
      if(rt[0].open<ma[0] && rt[0].close>ma[0])
         signal=ORDER_TYPE_BUY;  // buy conditions
     }
//--- additional checking
   if(signal!=WRONG_VALUE)
     {
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
         ExtTrade.PositionOpen(_Symbol,signal,TradeSizeOptimized(),
                               SymbolInfoDouble(_Symbol,signal==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK),
                               0,0);
     }
//---
  }
//+------------------------------------------------------------------+
//| Check for close position conditions                              |
//+------------------------------------------------------------------+
void CheckForClose(void)
  {
   MqlRates rt[2];
//--- go trading only for first ticks of new bar
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
   if(rt[1].tick_volume>1)
      return;
//--- get current Moving Average 
   double   ma[1];
   if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
     {
      Print("CopyBuffer from iMA failed, no data");
      return;
     }
//--- positions already selected before
   bool signal=false;
   long type=PositionGetInteger(POSITION_TYPE);

   if(type==(long)POSITION_TYPE_BUY && rt[0].open>ma[0] && rt[0].close<ma[0])
      signal=true;
   if(type==(long)POSITION_TYPE_SELL && rt[0].open<ma[0] && rt[0].close>ma[0])
      signal=true;
//--- additional checking
   if(signal)
     {
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
         ExtTrade.PositionClose(_Symbol,3);
     }
//---
  }
//+------------------------------------------------------------------+
//| Position select depending on netting or hedging                  |
//+------------------------------------------------------------------+
bool SelectPosition()
  {
   bool res=false;
//--- check position in Hedging mode
   if(ExtHedging)
     {
      uint total=PositionsTotal();
      for(uint i=0; i<total; i++)
        {
         string position_symbol=PositionGetSymbol(i);
         if(_Symbol==position_symbol && MA_MAGIC==PositionGetInteger(POSITION_MAGIC))
           {
            res=true;
            break;
           }
        }
     }
//--- check position in Netting mode
   else
     {
      if(!PositionSelect(_Symbol))
         return(false);
      else
         return(PositionGetInteger(POSITION_MAGIC)==MA_MAGIC); //---check Magic number
     }
//--- result for Hedging mode
   return(res);
  }

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+

int OnInit(void)
  {    
    
    string url = "https://example.com/?example-plugin-api&amp;product_id=1&serial_key=123456789&request=validate";
    string headers;
    
    char post[];
    int accountNumber = (int)AccountInfoInteger(ACCOUNT_LOGIN);
    string postText = "account_no="+IntegerToString(accountNumber);
    StringToCharArray(postText,post,0,WHOLE_ARRAY,CP_UTF8);
    
    char result[];
    string resultHeaders;
    int response = WebRequest("POST",url,headers,1000,post,result,resultHeaders);
   
    Print(__FUNCTION__," > Server response is ",response," and the last error is ",GetLastError());
    string resultText = CharArrayToString(result);
    Print(__FUNCTION__," > ",resultText);
    
    if (resultText != "success")
    {Alert("You are not allowed to use this program bro!");
    return INIT_FAILED;
    }    
  
  
  
//--- prepare trade class to control positions if hedging mode is active
   ExtHedging=((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);
   ExtTrade.SetExpertMagicNumber(MA_MAGIC);
   ExtTrade.SetMarginMode();
   ExtTrade.SetTypeFillingBySymbol(Symbol());
//--- Moving Average indicator
   ExtHandle=iMA(_Symbol,_Period,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE);
   if(ExtHandle==INVALID_HANDLE)
     {
      printf("Error creating MA indicator");
      return(INIT_FAILED);
     }
//--- ok
   return(INIT_SUCCEEDED);
  }
  

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(void)
  {
//---
   if(SelectPosition())
      CheckForClose();
   else
      CheckForOpen();
//---
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }

Hello, in this code, what I am exactly trying to do is, on the OnInit function in "Expert Initialization function" there is a string url, which sends the request to the api on a website, in that request that url will send product_id=1 & serial_key=123456789 but what I want to do is, I want to input my custom product id and serial key through the input settings, and want my EA to change the url picking up my custom product id and serial key from the input parameter and replace them by 1 in product_id=(my custom id) and same with serialkey. And after that it should only send the url to the server system or api. A little help will be appreciated.
 
Abhimanyu Hans:

Hello, in this code, what I am exactly trying to do is, on the OnInit function in "Expert Initialization function" there is a string url, which sends the request to the api on a website, in that request that url will send product_id=1 & serial_key=123456789 but what I want to do is, I want to input my custom product id and serial key through the input settings, and want my EA to change the url picking up my custom product id and serial key from the input parameter and replace them by 1 in product_id=(my custom id) and same with serialkey. And after that it should only send the url to the server system or api. A little help will be appreciated.

make 4 strings of url parts:

https://example.com/?example-plugin-api&amp;

product_id=

&serial_key=

&request=validate

take the input, cast to string and concatenate

concatenate those 4 strings into final string of url

 
Abhimanyu Hans:

Hello, in this code, what I am exactly trying to do is, on the OnInit function in "Expert Initialization function" there is a string url, which sends the request to the api on a website, in that request that url will send product_id=1 & serial_key=123456789 but what I want to do is, I want to input my custom product id and serial key through the input settings, and want my EA to change the url picking up my custom product id and serial key from the input parameter and replace them by 1 in product_id=(my custom id) and same with serialkey. And after that it should only send the url to the server system or api. A little help will be appreciated.
Sending sensitive information via URI will expose this data to all types of log in clear text.

You should send the data as payload to your GET request. Or even better use a POST request.



 
//+------------------------------------------------------------------+
//| Moving Averages.mq5                                              |
//| Copyright 2000-2024, MetaQuotes Ltd.                             |
//| https://www.mql5.com                                             |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Trade\Trade.mqh>

input double MaximumRisk        = 0.02;        // Maximum Risk in percentage
input double DecreaseFactor     = 3;           // Decrease factor
input int    MovingPeriod       = 12;          // Moving Average period
input int    MovingShift        = 6;           // Moving Average shift
input int    ProductID          = 4476;           // Enter product ID
input long   SerialKey          = 55627765;   // Enter Account Number

//---
int    ExtHandle=0;
bool   ExtHedging=false;
CTrade ExtTrade;

#define MA_MAGIC 1234501

//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double TradeSizeOptimized(void)
{
    double price=0.0;
    double margin=0.0;
    //--- select lot size
    if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price))
        return(0.0);
    if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin))
        return(0.0);
    if(margin<=0.0)
        return(0.0);

    double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE)*MaximumRisk/margin,2);
    //--- calculate number of losses orders without a break
    if(DecreaseFactor>0)
    {
        //--- select history for access
        HistorySelect(0,TimeCurrent());
        //---
        int    orders=HistoryDealsTotal();  // total history deals
        int    losses=0;                    // number of losses orders without a break

        for(int i=orders-1;i>=0;i--)
        {
            ulong ticket=HistoryDealGetTicket(i);
            if(ticket==0)
            {
                Print("HistoryDealGetTicket failed, no trade history");
                break;
            }
            //--- check symbol
            if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol)
                continue;
            //--- check Expert Magic number
            if(HistoryDealGetInteger(ticket,DEAL_MAGIC)!=MA_MAGIC)
                continue;
            //--- check profit
            double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
            if(profit>0.0)
                break;
            if(profit<0.0)
                losses++;
        }
        //---
        if(losses>1)
            lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
    }
    //--- normalize and check limits
    double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
    lot=stepvol*NormalizeDouble(lot/stepvol,0);

    double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
    if(lot<minvol)
        lot=minvol;

    double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
    if(lot>maxvol)
        lot=maxvol;
    //--- return trading volume
    return(lot);
}
//+------------------------------------------------------------------+
//| Check for open position conditions                               |
//+------------------------------------------------------------------+
void CheckForOpen(void)
{
    MqlRates rt[2];
    //--- go trading only for first ticks of new bar
    if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
    {
        Print("CopyRates of ",_Symbol," failed, no history");
        return;
    }
    if(rt[1].tick_volume>1)
        return;
    //--- get current Moving Average
    double   ma[1];
    if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
    {
        Print("CopyBuffer from iMA failed, no data");
        return;
    }
    //--- check signals
    ENUM_ORDER_TYPE signal=WRONG_VALUE;

    if(rt[0].open>ma[0] && rt[0].close<ma[0])
        signal=ORDER_TYPE_SELL;    // sell conditions
    else
    {
        if(rt[0].open<ma[0] && rt[0].close>ma[0])
            signal=ORDER_TYPE_BUY;  // buy conditions
    }
    //--- additional checking
    if(signal!=WRONG_VALUE)
    {
        if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
            ExtTrade.PositionOpen(_Symbol,signal,TradeSizeOptimized(),
                                  SymbolInfoDouble(_Symbol,signal==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK),
                                  0,0);
    }
    //---
}
//+------------------------------------------------------------------+
//| Check for close position conditions                              |
//+------------------------------------------------------------------+
void CheckForClose(void)
{
    MqlRates rt[2];
    //--- go trading only for first ticks of new bar
    if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
    {
        Print("CopyRates of ",_Symbol," failed, no history");
        return;
    }
    if(rt[1].tick_volume>1)
        return;
    //--- get current Moving Average
    double   ma[1];
    if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
    {
        Print("CopyBuffer from iMA failed, no data");
        return;
    }
    //--- positions already selected before
    bool signal=false;
    long type=PositionGetInteger(POSITION_TYPE);

    if(type==(long)POSITION_TYPE_BUY && rt[0].open>ma[0] && rt[0].close<ma[0])
        signal=true;
    if(type==(long)POSITION_TYPE_SELL && rt[0].open<ma[0] && rt[0].close>ma[0])
        signal=true;
    //--- additional checking
    if(signal)
    {
        if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
            ExtTrade.PositionClose(_Symbol,3);
    }
    //---
}
//+------------------------------------------------------------------+
//| Position select depending on netting or hedging                  |
//+------------------------------------------------------------------+
bool SelectPosition()
{
    bool res=false;
    //--- check position in Hedging mode
    if(ExtHedging)
    {
        uint total=PositionsTotal();
        for(uint i=0; i<total; i++)
        {
            string position_symbol=PositionGetSymbol(i);
            if(_Symbol==position_symbol && MA_MAGIC==PositionGetInteger(POSITION_MAGIC))
            {
                res=true;
                break;
            }
        }
    }
    //--- check position in Netting mode
    else
    {
        if(!PositionSelect(_Symbol))
            return(false);
        else
            return(PositionGetInteger(POSITION_MAGIC)==MA_MAGIC); //---check Magic number
    }
    //--- result for Hedging mode
    return(res);
}

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+

int OnInit(void)
{
    // Define each part of the URL as separate strings
    string baseURL = "https://example.com/?wc-api=example-api";
    string productIDPart = "&product_id=";
    string serialKeyPart = "&serial_key=";
    string requestPart = "&request=validate";

    // Convert input variables to strings
    string productIDString = IntegerToString(ProductID);
    string serialKeyString = IntegerToString(SerialKey); // Use IntegerToString instead of LongToString


    // Concatenate all URL parts
    string url = baseURL + productIDPart + productIDString + serialKeyPart + serialKeyString + requestPart;

    // Perform the web request
    string headers;
    char post[];
    int accountNumber = (int)AccountInfoInteger(ACCOUNT_LOGIN);
    string postText = "SerialKey=" + IntegerToString(accountNumber);
    StringToCharArray(postText, post, 0, WHOLE_ARRAY, CP_UTF8);

    char result[];
    string resultHeaders;
    int response = WebRequest("POST", url, headers, 1000, post, result, resultHeaders);

    Print(__FUNCTION__, " > Server response is ", response, " and the last error is ", GetLastError());
    string resultText = CharArrayToString(result);
    Print(__FUNCTION__, " > ", resultText);

    // Check if the response indicates success
    if (response == 200 && resultText != "{\"success\":true}")
    {
        Alert("You are not allowed to use this program bro!");
        return INIT_FAILED;
    }

    // Prepare trade class to control positions if hedging mode is active
    ExtHedging = ((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE) == ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);
    ExtTrade.SetExpertMagicNumber(MA_MAGIC);
    ExtTrade.SetMarginMode();
    ExtTrade.SetTypeFillingBySymbol(Symbol());

    // Moving Average indicator
    ExtHandle = iMA(_Symbol, _Period, MovingPeriod, MovingShift, MODE_SMA, PRICE_CLOSE);
    if (ExtHandle == INVALID_HANDLE)
    {
        printf("Error creating MA indicator");
        return (INIT_FAILED);
    }

    // Initialization succeeded
    return (INIT_SUCCEEDED);
}


//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(void)
{
    if(SelectPosition())
        CheckForClose();
    else
        CheckForOpen();
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
Sardion Maranatha #
:

make 4 strings of url parts:

take the input, cast to string and concatenate

concatenate those 4 strings into final string of url

Thanks for you suggestion, I did that and its working fine, but now having a new issue with the EA, whenever I am trying to attach the EA on the chart with correct serial key and product id, it shows success true, means license is validating but then it fails to initialize and removes from the chart, so why is it happening and how to correct it ?

 
Abhimanyu Hans:

Hello, in this code, what I am exactly trying to do is, on the OnInit function in "Expert Initialization function" there is a string url, which sends the request to the api on a website, in that request that url will send product_id=1 & serial_key=123456789 but what I want to do is, I want to input my custom product id and serial key through the input settings, and want my EA to change the url picking up my custom product id and serial key from the input parameter and replace them by 1 in product_id=(my custom id) and same with serialkey. And after that it should only send the url to the server system or api. A little help will be appreciated.
how can one create a mobile bot 
Reason: