EA - WRONG COMMENTS

 

When I use the backtest strategy on MT5 i just want the results of TP AND SL. It is giving me SO 27.77% AND END OF TEST ALL FOR THE SAME DATE AND TIME? The number should never be able to be that high either with the sl at atr x 2 and the tp at 20 pips. How do I sort this ? Thanks


Below is the code.




#include <Trade\Trade.mqh>


#define BUYSIGNAL "Buy now"
#define SELLSIGNAL "Sell now"


input group "<---- EA SETTINGS ---->"
input string          EA_Comment = "ema crossover index"; //Order Comment
input ulong           Magic      = 49206;           //Magic Number
input ENUM_TIMEFRAMES timeframe = PERIOD_H1;       //Timeframe

input group "<---- TRADE SETTINGS ---->"
input int    max_trades    = 1;        //Max Trades at a time
input double index_lots  = 0.8;     //Lots
input int    index_tp    = 40;      //TP



input group  "<---- EMA SETTINGS ---->";
input int                fast_ema_period = 10; //Fast EMA Period
input int                slow_ema_period = 50; //Slow EMA Period
input int                ema_shift       = 0;  //Shift
input ENUM_MA_METHOD     ma_method       = MODE_EMA; //MA Method
input ENUM_APPLIED_PRICE ma_price        = PRICE_CLOSE; //Price Close

input group "<---- ADX WILDER SETTINGS ---->"
input bool   use_adx         = true; //Use ADX
input int    adx_period      = 14; //ADX Period
input double adx_level       = 0; //ADX Level

input group "<---- CHOPPINESS INDEX ---->"
input bool   use_choppines   = true; //Use Choppiness Index
input int    inpChoPeriod    = 14;   // Choppiness Index Period
input double choppi_level    = 50;   //Level

// Define input parameters

input group "<---- RSI ---->"
input bool use_rsi = true;
input int RSI_Period = 14;
input double rsi_level = 50;

input group "<---- ATR SETTINGS ---->"
input bool   use_atr         = true; // Use ATR for SL
input int    atr_period      = 14;   // ATR Period
input double atr_multiplier  = 2.0;  // ATR Multiplier




//--
int Deviation = 10;

int ErrCode;
//--

int fast_ma_handle;
double fast_ma_buffer[];

int slow_ma_handle;
double slow_ma_buffer[];

int adx_handle;
double adx_buffer[];

int choppi_handle;
double choppi_buffer[];

int rsi_handle;
double rsi_buffer[];

int atr_handle;
double atr_buffer[];

//+------------------------------------------------------------------+
struct trades_data
   {
      int positions;

      double bid;
      double ask;
      long stoplevel;
      long spread;
      double _point;
      int _digits;
   };
   



//+------------------------------------------------------------------+
int OnInit()
  {      
      ChartSetInteger(0,CHART_SHOW_GRID,false);
      ChartSetInteger(0,CHART_MODE,CHART_CANDLES);
      
      
      fast_ma_handle = iMA(Symbol(),timeframe,fast_ema_period,ema_shift,ma_method,ma_price);
      slow_ma_handle = iMA(Symbol(),timeframe,slow_ema_period,ema_shift,ma_method,ma_price);
      adx_handle = iADXWilder(Symbol(),timeframe,adx_period);
      choppi_handle = iCustom(Symbol(),timeframe,"Choppiness index",inpChoPeriod);
      rsi_handle = iRSI(Symbol(), timeframe, RSI_Period, PRICE_CLOSE);
      atr_handle = iATR(Symbol(), timeframe, atr_period);
    
   

      
      return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   
}

      
//+------------------------------------------------------------------+
void OnTick()
{
    Trade();  // Call the Trade() function to execute trades
    
    // Rest of your OnTick() code (if any)
}


//+------------------------------------------------------------------+
void Trade()
{
    if (!New_Bar()) return;

    string pair = Symbol();
    trades_data data = GetData(pair);

    ArraySetAsSeries(fast_ma_buffer, true);
    ArrayFree(fast_ma_buffer);
    CopyBuffer(fast_ma_handle, 0, 0, 5, fast_ma_buffer);

    ArraySetAsSeries(slow_ma_buffer, true);
    ArrayFree(slow_ma_buffer);
    CopyBuffer(slow_ma_handle, 0, 0, 5, slow_ma_buffer);

    ArraySetAsSeries(adx_buffer, true);
    ArrayFree(adx_buffer);
    CopyBuffer(adx_handle, 0, 0, 5, adx_buffer);

    ArraySetAsSeries(choppi_buffer, true);
    ArrayFree(choppi_buffer);
    CopyBuffer(choppi_handle, 0, 0, 5, choppi_buffer);

    ArraySetAsSeries(rsi_buffer, true);
    ArrayFree(rsi_buffer);
    CopyBuffer(rsi_handle, 0, 0, 5, rsi_buffer);
    
    ArraySetAsSeries(atr_buffer, true);
    CopyBuffer(atr_handle, 0, 0, 5, atr_buffer);
    
    double rsi_value = rsi_buffer[1];

    // Buy
    if (fast_ma_buffer[2] < slow_ma_buffer[2] && fast_ma_buffer[1] > slow_ma_buffer[1] && rsi_value > rsi_level)
    {
        double atr_value = atr_buffer[1] * atr_multiplier;
        double stopLoss = data.bid - (atr_value * 20);
        double takeProfit = data.ask + (20 * Pips(pair)); // Set TP to 20 points
        BUY(pair, data._point, data._digits, data.stoplevel, data.ask, data.bid, int(atr_value), 20, index_lots);
    }

    // Sell
    if (fast_ma_buffer[2] > slow_ma_buffer[2] && fast_ma_buffer[1] < slow_ma_buffer[1] && rsi_value < rsi_level)
    {
        double atr_value = atr_buffer[1] * atr_multiplier;
        double stopLoss = data.ask + (atr_value * 20);
        double takeProfit = data.bid - (20 * Pips(pair)); // Set TP to 20 points
        SELL(pair, data._point, data._digits, data.stoplevel, data.ask, data.bid, int(atr_value), 20, index_lots);
    }
}


//+------------------------------------------------------------------+
void ClosePosition(string pair,int type)
  {
   CPositionInfo *m_current_position = new CPositionInfo;
   CTrade* myClose = new CTrade;
   
   int total=PositionsTotal()-1;
   for(int i=total; i>=0; i--)
     {
      if(!m_current_position.SelectByIndex(i))continue;
      if(m_current_position.Symbol() != pair)continue;
      if(m_current_position.Magic() != Magic)continue;
      
      myClose.SetExpertMagicNumber(Magic);
      if(m_current_position.PositionType() == type)
         {
             myClose.PositionClose(m_current_position.Ticket());
         }
     }
     
   delete m_current_position;
   delete myClose;
  }
  
//+------------------------------------------------------------------+
bool New_Bar()
   {
      datetime time = iTime(Symbol(),timeframe,0);
      
      static datetime New_Time = 0;
      
      if(New_Time != time)
         {
            New_Time = time;
            return true;
         }
         
      return false;
   }
   
  

  
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void BUY(string pair, double points, int digits, long stoplevel, double ask, double bid, int stoploss, int takeprofit, double lot)
{
    double SL = 0;
    double TP = 0;

    if (stoploss > 0)
    {
        double atr_value = atr_buffer[1] * atr_multiplier; // Calculate ATR value
        SL = bid - (atr_value * Pips(pair)); // Calculate SL based on ATR

        if (bid - SL <= stoplevel * points) SL = bid - ((stoplevel + 2) * points);

        SL = NormalizeDouble(SL, digits);
    }

    if (takeprofit > 0)
    {
        TP = ask + (takeprofit * Pips(pair));

        if (TP - ask <= stoplevel * points) TP = ask + ((stoplevel + 2) * points);

        TP = NormalizeDouble(TP, digits);
    }
    MqlTradeRequest request;
    MqlTradeResult result;

    ZeroMemory(request);
    ZeroMemory(result);

    request.action = TRADE_ACTION_DEAL;
    request.symbol = pair;
    request.volume = LotOptimised(pair, lot);
    request.type = ORDER_TYPE_BUY;
    request.price = ask;
    request.sl = SL;
    request.tp = TP;
    request.deviation = Deviation;
    request.magic = Magic;
    request.comment = EA_Comment;
    request.type_filling = GetFilling(pair);

    if (OrderSend(request, result))
    {
        ErrCode = GetLastError();
        Print("Unable to open buy position, error - ", ErrCode);
    }
}
   
//+------------------------------------------------------------------+
void SELL(string pair, double points, int digits, long stoplevel, double ask, double bid, int stoploss, int takeprofit, double lot)
{
    double SL = 0;
    double TP = 0;

    if (stoploss > 0)
    {
        double atr_value = atr_buffer[1] * atr_multiplier; // Calculate ATR value
        SL = ask + (atr_value * Pips(pair)); // Calculate SL based on ATR

        if (SL - ask <= stoplevel * points) SL = ask + ((stoplevel + 2) * points);

        SL = NormalizeDouble(SL, digits);
    }

    if (takeprofit > 0)
    {
        TP = bid - (takeprofit * Pips(pair));

        if (bid - TP <= stoplevel * points) TP = bid - ((stoplevel + 2) * points);

        TP = NormalizeDouble(TP, digits);
    }

    MqlTradeRequest request;
    MqlTradeResult result;

    ZeroMemory(request);
    ZeroMemory(result);

    request.action = TRADE_ACTION_DEAL;
    request.symbol = pair;
    request.volume = LotOptimised(pair, lot);
    request.type = ORDER_TYPE_SELL;
    request.price = bid;
    request.sl = SL;
    request.tp = TP;
    request.deviation = Deviation;
    request.magic = Magic;
    request.comment = EA_Comment;
    request.type_filling = GetFilling(pair);

    if (OrderSend(request, result))
    {
        ErrCode = GetLastError();
        Print("Unable to open sell position, error - ", ErrCode);
    }
}
//+------------------------------------------------------------------+
double LotOptimised(string pair,double lots)
   {
      double Lot = lots;
      
      double minLot  = SymbolInfoDouble(pair,SYMBOL_VOLUME_MIN);
      double maxLot  = SymbolInfoDouble(pair,SYMBOL_VOLUME_MAX);
      double LotStep = SymbolInfoDouble(pair,SYMBOL_VOLUME_STEP);
      
      Lot = MathRound(Lot/LotStep) * LotStep;
      
      Lot = MathMin(MathMax(Lot,minLot),maxLot);
         
      return Lot;
   }
   
//+------------------------------------------------------------------+
ENUM_ORDER_TYPE_FILLING GetFilling(const string Symb, const uint Type = ORDER_FILLING_FOK)
{
    const ENUM_SYMBOL_TRADE_EXECUTION ExeMode = (ENUM_SYMBOL_TRADE_EXECUTION)::SymbolInfoInteger(Symb, SYMBOL_TRADE_EXEMODE);
    const int FillingMode = (int)::SymbolInfoInteger(Symb, SYMBOL_FILLING_MODE);

    return((FillingMode == 0 || (Type >= ORDER_FILLING_RETURN) || ((FillingMode & (Type + 1)) != Type + 1)) ?
            (((ExeMode == SYMBOL_TRADE_EXECUTION_EXCHANGE) || (ExeMode == SYMBOL_TRADE_EXECUTION_INSTANT)) ?
              ORDER_FILLING_RETURN : ((FillingMode == SYMBOL_FILLING_IOC) ? ORDER_FILLING_IOC : ORDER_FILLING_FOK)) :
             (ENUM_ORDER_TYPE_FILLING)Type);
}
//+------------------------------------------------------------------+     
double Pips(string symbol)  
   {  
      string sym = symbol;
      
      double bid = SymbolInfoDouble(sym,SYMBOL_BID);
      int digits = (int)SymbolInfoInteger(sym,SYMBOL_DIGITS);
      
      double _points = SymbolInfoDouble(sym,SYMBOL_POINT);
      
      if(digits <= 1) _points = 1; //CFD & Indexes  
      if(digits == 4 || digits == 5) _points = 0.0001; 
      if((digits == 2 || digits == 3) && bid > 1000) _points = 1;
      if((digits == 2 || digits == 3) && bid < 1000) _points = 0.01;
      if(StringFind(sym,"XAU") >- 1 || StringFind(sym,"xau") >- 1 || StringFind(sym,"GOLD") >- 1) _points = 0.1;//Gold
      
      return(_points);
   }
   
//+------------------------------------------------------------------+
trades_data GetData(string pair)
   {
      trades_data o_data;
      
      int pos = 0,orders = 0;
      
      for(int i = 0; i < PositionsTotal(); i++)
         {
            ulong  position_ticket = PositionGetTicket(i);
            if(!PositionSelectByTicket(position_ticket))break;
            if(PositionGetSymbol(i) != pair)continue;
            if(PositionGetInteger(POSITION_MAGIC) != Magic)continue;
            
            pos++;
            
         }
      
      o_data.positions = pos;
      
      o_data.ask = SymbolInfoDouble(pair,SYMBOL_ASK);
      o_data.bid = SymbolInfoDouble(pair,SYMBOL_BID);
      o_data.stoplevel = SymbolInfoInteger(pair,SYMBOL_TRADE_STOPS_LEVEL);
      o_data.spread = SymbolInfoInteger(pair,SYMBOL_SPREAD);
      o_data._point = SymbolInfoDouble(pair,SYMBOL_POINT);
      o_data._digits = (int)SymbolInfoInteger(pair,SYMBOL_DIGITS);
      
      
      return o_data;
   }