My EA does buy and sell automatically when I backtest it is there anyone that can help me to solve this issue?

 
Hi again, I have a problem my EA program does not buy and sell automatically when I backtest it , I can’t recognize what the problem is that this code can’t buy and sell , if anyone know , help me please. Here is the code : //+------------------------------------------------------------------+
//| Property                                                         |
//+------------------------------------------------------------------+
#property strict
//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
input int MA_Period = 50; // Period for the moving average
input double Risk_Percentage = 1.5; // Adjusted risk percentage per trade
input double Stop_Loss = 100.0; // Initial stop loss in points
input double Take_Profit = 200.0; // Take profit level in points
double LotSize; // Position size based on risk
int Digits; // Number of decimal places for the symbol
double AccountBalance = 10000.0; // Account balance in USD

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   Digits = int(SymbolInfoInteger(_Symbol, SYMBOL_DIGITS)); // Get the number of decimal places for the symbol
   LotSize = CalculatePositionSize(); // Calculate initial lot size
   
   Print("Expert Advisor initialized successfully.");
   
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Print("Expert Advisor deinitialized successfully.");
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double closePrice[]; // Declare 'closePrice' as an array

   if (Bars(_Symbol, 0) < MA_Period + 2) // Check if there is enough historical data
      return;

   if (!CopyClose(_Symbol, 0, 1, 1, closePrice))
   {
      Print("Error copying Close price: ", GetLastError());
      return;
   }

   double ma = iMA(_Symbol, 0, MA_Period, 0, MODE_SMA, PRICE_CLOSE);
   
   if (closePrice[1] < ma && closePrice[0] > ma && closePrice[1] < closePrice[0] - 10) // Add condition to check price trend and other sophisticated entry conditions
   {
      MqlTradeRequest request;
      request.action = TRADE_ACTION_DEAL;
      request.magic = 123456;
      request.symbol = _Symbol;
      request.volume = LotSize; // Use calculated lot size
      request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      request.type = ORDER_TYPE_BUY;
      request.type_filling = ORDER_FILLING_FOK;
      
      double Point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); // Define Point
      
      request.tp = NormalizeDouble(closePrice[0] + CalculateTakeProfit() * Point, Digits); // Set dynamic take profit level
      request.sl = NormalizeDouble(closePrice[0] - CalculateStopLoss() * Point, Digits); // Set dynamic stop loss level

      MqlTradeResult result;

      if (!OrderSend(request, result))
      {
         Print("Buy OrderSend error: ", GetLastError());
         return;
      }
   }
   else if (closePrice[1] > ma && closePrice[0] < ma && closePrice[1] > closePrice[0] + 10) // Add condition to check price trend and other sophisticated entry conditions
   {  
      MqlTradeRequest request;
      request.action = TRADE_ACTION_DEAL;
      request.magic = 123456;
      request.symbol = _Symbol;
      request.volume = LotSize; // Use calculated lot size
      request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      request.type = ORDER_TYPE_SELL;
      request.type_filling = ORDER_FILLING_FOK;

      double Point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); // Define Point
      
      request.tp = NormalizeDouble(closePrice[0] - CalculateTakeProfit() * Point, Digits); // Set dynamic take profit level
      request.sl = NormalizeDouble(closePrice[0] + CalculateStopLoss() * Point, Digits); // Set dynamic stop loss level

      MqlTradeResult result;

      if (!OrderSend(request, result))
      {
         Print("Sell OrderSend error: ", GetLastError());
         return;
      }
   }
}

//+------------------------------------------------------------------+
//| Calculate dynamic stop loss based on market conditions           |
//+------------------------------------------------------------------+
double CalculateStopLoss()
{
    double tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
    double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
    
    return ((AccountBalance * Risk_Percentage / (LotSize * Stop_Loss)) / (tick_value * tick_size));
}

//+------------------------------------------------------------------+
//| Calculate dynamic take profit based on market conditions         |
//+------------------------------------------------------------------+
double CalculateTakeProfit()
{
    double tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
    double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);

    return ((AccountBalance * Risk_Percentage / (LotSize * Take_Profit)) / (tick_value * tick_size));
}

//+------------------------------------------------------------------+
//| Calculate dynamic position size based on risk percentage and stop loss|
//+------------------------------------------------------------------+
double CalculatePositionSize()
{
    double tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
    double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
    
    double riskAmount = AccountBalance * Risk_Percentage;
    double maxLoss = riskAmount * LotSize * Stop_Loss;
    
    return NormalizeDouble(maxLoss / (tick_value * tick_size), 2);
}
 

iMA - Technical Indicators - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5

The iMA function returns a handle, not the moving average. Use copybuffer to read the indicator data. 

Also, the function should be in OnInit, not OnTick.

Hope this helps.

Documentation on MQL5: Technical Indicators / iMA
Documentation on MQL5: Technical Indicators / iMA
  • www.mql5.com
The function returns the handle of the Moving Average indicator. It has only one buffer. Parameters symbol [in] The symbol name of the security...
 
ceejay1962 #:

iMA - Technical Indicators - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5

The iMA function returns a handle, not the moving average. Use copybuffer to read the indicator data. 

Also, the function should be in OnInit, not OnTick.

Hope this helps.

Hi, Here is my EA, I made changes but in still can't buy and sell what should I do ?:


//+------------------------------------------------------------------+

//| Property                                                         |

//+------------------------------------------------------------------+

#property strict

//+------------------------------------------------------------------+

//| Global variables                                                 |

//+------------------------------------------------------------------+

input int MA_Period = 50; // Period for the moving average

input double Risk_Percentage = 1.5; // Adjusted risk percentage per trade

input double Stop_Loss = 100.0; // Initial stop loss in points

input double Take_Profit = 200.0; // Take profit level in points

double LotSize; // Position size based on risk

int Digits; // Number of decimal places for the symbol

double AccountBalance = 10000.0; // Account balance in USD

double maBuffer[];



//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+

int OnInit()

{

   Digits = int(SymbolInfoInteger(_Symbol, SYMBOL_DIGITS)); // Get the number of decimal places for the symbol

   LotSize = CalculatePositionSize(); // Calculate initial lot size

   ArraySetAsSeries(maBuffer, true); // Set the array as series

   

   Print("Expert Advisor initialized successfully.");

   

   EventSetTimer(1); // Start OnTick function

   

   return(INIT_SUCCEEDED);

}

//+------------------------------------------------------------------+

//| Expert deinitialization function                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

{

   Print("Expert Advisor deinitialized successfully.");

}

//+------------------------------------------------------------------+

//| Expert tick function                                             |

//+------------------------------------------------------------------+

void OnTick()

{

   if (Bars(_Symbol, 0) < MA_Period + 2) // Check if there is enough historical data

      return;



   int maHandle = iMA(_Symbol, 0, MA_Period, 0, MODE_SMA, PRICE_CLOSE);

   int copied = CopyBuffer(maHandle, 0, 0, 2, maBuffer);



   if (copied <= 0)

   {

      Print("Error copying MA buffer: ", GetLastError());

      return;

   }



   double ma = maBuffer[1]; // Use the correct value from the buffer



   double closePrice[]; // Declare 'closePrice' as an array



   if (!CopyClose(_Symbol, 0, 1, 1, closePrice))

   {

      Print("Error copying Close price: ", GetLastError());

      return;

   }

   

   if (closePrice[1] < ma && closePrice[0] > ma && closePrice[1] < closePrice[0] - 10) // Add condition to check price trend and other sophisticated entry conditions

   {

      MqlTradeRequest request;

      request.action = TRADE_ACTION_DEAL;

      request.magic = 123456;

      request.symbol = _Symbol;

      request.volume = LotSize; // Use calculated lot size

      request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

      request.type = ORDER_TYPE_BUY;

      request.type_filling = ORDER_FILLING_FOK;

      

      double Point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); // Define Point

      

      request.tp = NormalizeDouble(closePrice[0] + CalculateTakeProfit() * Point, Digits); // Set dynamic take profit level

      request.sl = NormalizeDouble(closePrice[0] - CalculateStopLoss() * Point, Digits); // Set dynamic stop loss level



      MqlTradeResult result;



      if (!OrderSend(request, result))

      {

         Print("Buy OrderSend error: ", GetLastError());

         return;

      }

   }

   else if (closePrice[1] > ma && closePrice[0] < ma && closePrice[1] > closePrice[0] + 10) // Add condition to check price trend and other sophisticated entry conditions

   {  

      MqlTradeRequest request;

      request.action = TRADE_ACTION_DEAL;

      request.magic = 123456;

      request.symbol = _Symbol;

      request.volume = LotSize; // Use calculated lot size

      request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);

      request.type = ORDER_TYPE_SELL;

      request.type_filling = ORDER_FILLING_FOK;



      double Point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); // Define Point

      

      request.tp = NormalizeDouble(closePrice[0] - CalculateTakeProfit() * Point, Digits); // Set dynamic take profit level

      request.sl = NormalizeDouble(closePrice[0] + CalculateStopLoss() * Point, Digits); // Set dynamic stop loss level



      MqlTradeResult result;



      if (!OrderSend(request, result))

      {

         Print("Sell OrderSend error: ", GetLastError());

         return;

      }

   }

}



//+------------------------------------------------------------------+

//| Calculate dynamic stop loss based on market conditions           |

//+------------------------------------------------------------------+

double CalculateStopLoss()

{

    double tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);

    double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);

    

    return ((AccountBalance * Risk_Percentage / (LotSize * Stop_Loss)) / (tick_value * tick_size));

}



//+------------------------------------------------------------------+

//| Calculate dynamic take profit based on market conditions         |

//+------------------------------------------------------------------+

double CalculateTakeProfit()

{

    double tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);

    double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);



    return ((AccountBalance * Risk_Percentage / (LotSize * Take_Profit)) / (tick_value * tick_size));

}



//+------------------------------------------------------------------+

//| Calculate dynamic position size based on risk percentage and stop loss|

//+------------------------------------------------------------------+

double CalculatePositionSize()

{

    double tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);

    double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);

    

    double riskAmount = AccountBalance * Risk_Percentage;

    double maxLoss = riskAmount * LotSize * Stop_Loss;

    

    return NormalizeDouble(maxLoss / (tick_value * tick_size), 2);

}

please help me if you can. 

 
محمد دهقانی #:
CopyClose
int maHandle = iMA(_Symbol, 0, MA_Period, 0, MODE_SMA, PRICE_CLOSE);

That is correct now, but it should really be moved to OnInit, above ArraySetAsSeries - otherwise, you are opening a new handle on every tick.

if (!CopyClose(_Symbol, 0, 1, 1, closePrice))

The above function causes a critical error when you try and access closePrice[1] because you have only loaded 1 bar. 

if (!CopyClose(_Symbol, 0, 1, 
2 , closePrice))

With that change, the EA will run, but it might not do any trades - reason being is this line, and the matching line for short trades.

if (closePrice[1] < ma && closePrice[0] > ma && closePrice[1] < closePrice[0] - 10) 

Assuming that you are trading a currency, the number 10 won't match the currency pips.