EA based on crossing EMAs, opens operations contrary to the defined strategy.

 

Good afternoon, I have a problem with this EA, which should activate buy orders when the EMA5 is above the EMA21, and sell orders if it is the other way around. However, I have noticed that even though the EMA5 is above the EMA21, sell orders are still opened sometimes. The same thing happens when the EMA5 is below the EMA21, activating buy orders. T

//+------------------------------------------------------------------+
//|                                                  mar 23 iv.mq5 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <Trade\Trade.mqh>
CTrade trade;

// Datos operacion

input double Lots = 0.01;
input int StopLoss = 300;
input int TakeProfit = 300;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);
    double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);

    double EmaRapida = iMA(_Symbol, 0, 5, 0, MODE_EMA, PRICE_CLOSE);
    double EmaLenta =  iMA(_Symbol, 0, 21, 0, MODE_EMA, PRICE_CLOSE);

    double buffer = 0.010; // Adjust this buffer value as per your preference

    if(EmaRapida > EmaLenta && PositionsTotal() == 0) 
    {
        trade.Buy(Lots, _Symbol, Ask, (Ask - (StopLoss * _Point)), (Ask + (TakeProfit * _Point)), "Buy Operation");
    }

    if(EmaRapida < EmaLenta && PositionsTotal() == 0) 
    {
        trade.Sell(Lots, _Symbol, Bid, (Bid + (StopLoss * _Point)), (Bid - (TakeProfit * _Point)), "Sell Operation");
    }
}


//+------------------------------------------------------------------+
Thank you very much!

Files:
 

This code would require too many adjustments to be rewritten here. From what I can tell, it was written using ChatGPT - AI is still not good to write  MQL5 code. You will have way more trouble correcting wrong code than writing the full code itself. However, here are a few of the problems I detected:


1 - the function iMA returns a handle to the indicator, not the data itself. iMA, iBands, iRSI, etc., should all be called on the OnInit function - thus, only once. After getting the handle to the indicator, then you would call the function CopyBuffer on the OnTick function to fetch the indicator data. The data obtained by the CopyBuffer function is the real data you want to compare. The issue you are having is because the indicator handle is just an integer value that represents the loaded indicator. If you compare EmaRapida > EmaLenta, you are just comparing these handles, not the real indicator value.  

2 - since you usually want the most recent data, the array to which the data is copied should be a series array, which can be set like this using the function ArraySetAsSeries function.

3 - the buffer variable doesn't do anything and should be removed to make the code cleaner.

4 - if the amount of opened positions doesn't change in the same OnTick call, you should call PositionsTotal() only once and store its result in a variable. Function calls are usually costly to the computer and everytime you can access data directly from a variable speeds up your code.

5 - if you have two or more conditions that are completely opposite from each other (i.e., the fast MA can only be above or below the slow MA; only one of these conditions may be true, never both of them), use an if else statement to avoid executing both if statements. That is, if the first 'if' block results true, the second is skipped, increasing the code speed. 


Many of these tweaks do not represent a significative improvement on a single run, but if you consider that a candle may have thousands of ticks and that you may backtest your strategy on thousands of bars, the difference will surely be noticiable.

 
cayenne:

Good afternoon, I have a problem with this EA, which should activate buy orders when the EMA5 is above the EMA21, and sell orders if it is the other way around. However, I have noticed that even though the EMA5 is above the EMA21, sell orders are still opened sometimes. The same thing happens when the EMA5 is below the EMA21, activating buy orders. T

Thank you very much!

Sorry, we can not assist if you did not code it yourself, your code is incorrect. Learn to code or create a job in the freelance section. Too many mistakes, we will have to write everything over again. It is not worth our time, as you showed no effort in doing it yourself. We can see if the code was hand written or if you used generators and AI, this logic is way off. You need to learn to do this, it is the ONLY way you will be able to test your ideas.

Reason: