EMA cross not working

 

Hi all, I am new to coding and created a simple script for an EMA cross with periods 3 and 26.

The EA is not catching all cross events , only some of them. Can somebody see what is wrong?

I added print statemts so in the EA journal you can see the events not being captured as the change from "GreaterThan" to "LessThan".

Files:
EMAcross.mq5  10 kb
 

Hello

You had these errors :


1.if (iMA09_1 < iMA26_1 && iMA09_2 < iMA26_2)

2. the buffers copy should start from zero if you are polling [1] vs [2]

3. the price for the trading signals was never sent down to the SLTP functions

//+------------------------------------------------------------------+
//|                                                    garytest3.mq5 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Garret Dee"
#property version   "1.0"

//+------------------------------------------------------------------+
//| 01 Setup - Include , Inputs, Variables                                                         |
//+------------------------------------------------------------------+

#include <Trade/Trade.mqh>

//--- Inputs for EA
static input int EXPERT_MAGIC = 100009;                         // MagicNumber of the expert

input group "Indicator Settings, MA"
input int                  ma1_period=9;                  // Period of MA1
input ENUM_MA_METHOD       ma1_method=MODE_EMA;           // Smoothing of MA1 
input ENUM_APPLIED_PRICE   ma1_applied_price=PRICE_CLOSE;    // Price of MA1
input int                  ma2_period=26;                  // Period of MA2
input ENUM_MA_METHOD       ma2_method=MODE_EMA;           // Smoothing of MA2 
input ENUM_APPLIED_PRICE   ma2_applied_price=PRICE_CLOSE;    // Price of MA2
        
input group "Trade Settings"
input double Lots = 0.01;
input int LimitDistance = 50;                            //Limit Distance in Points
input int TpPoints = 100;                                // Take-Profit in Points
input int SlPoints = 100;                                //Stop-Loss in Points
input bool UseTrailingSL = true;                         //Use Trailing Stop Loss
input string Commentary = "EMA(9,26) cross";

// --- setup tables and variables

double iMA09_Array[], iMA26_Array[];                                  // Creates data table to store SMA values

int iMA09_handle, iMA26_handle;

double iMA09_1, iMA09_2, iMA26_1, iMA26_2;

CTrade trade;
//+------------------------------------------------------------------+
//| 02 Initialization function of the expert                            |
//+------------------------------------------------------------------+
int OnInit()
   {
   
   trade.SetExpertMagicNumber(EXPERT_MAGIC);
   
   ArraySetAsSeries(iMA09_Array,true);  // Ensures latest SMA data is indexed from shift 0
   ArraySetAsSeries(iMA26_Array,true);  
   iMA09_handle = iMA(Symbol(), PERIOD_CURRENT, ma1_period, 0, ma1_method, ma1_applied_price); // Getting the Control Panel/Handle for SMA
   iMA26_handle = iMA(Symbol(), PERIOD_CURRENT, ma2_period, 0, ma2_method, ma2_applied_price); // Getting the Control Panel/Handle for SMA
   
  return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 03 Deinitialization function of the expert                          |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   
   IndicatorRelease(iMA09_handle); //Release the iMA indicator
   ChartIndicatorDelete(0,0,ChartIndicatorName(0,0,0)); //iterate to remove several charts
   ArrayFree(iMA09_Array); // free the dynamic array of data
   
   IndicatorRelease(iMA26_handle); //Release the iMA indicator
   ChartIndicatorDelete(0,0,ChartIndicatorName(0,0,1)); //iterate to remove several charts
   ArrayFree(iMA26_Array); // free the dynamic array of data
   
  }
//+------------------------------------------------------------------+
//| 04 "Tick" event handler function                                    |
//+------------------------------------------------------------------+
void OnTick()
   {
   
//--- User Function to stop code from here untill new bar, No extra brace needed
   if(!is_new_bar()){return;}    
   
   
   int iMA09_err = CopyBuffer(iMA09_handle, 0,0, 3, iMA09_Array); //  Collects data of the 0th line (if more then one) from shift 0 to shift 3
   int iMA26_err = CopyBuffer(iMA26_handle, 0,0, 3, iMA26_Array); //  Collects data of the 0th line (if more then one) from shift 0 to shift 3
   if(iMA09_err<0 || iMA26_err<0)                                    //in case of errors
   {
      Print("Failed to copy data from the indicator buffer or price chart buffer");  //then print the relevant error message into the log file
      return;    //and exit the function
   } 
   
   ChartIndicatorAdd(0,0,iMA09_handle); ChartIndicatorAdd(0,0,iMA26_handle);   

//--- calculations for EMA  crossover
   iMA09_1 = iMA09_Array[1]; iMA09_1 = NormalizeDouble(iMA09_1,3);
   iMA09_2 = iMA09_Array[2]; iMA09_2 = NormalizeDouble(iMA09_2,3);
   iMA26_1 = iMA26_Array[1]; iMA26_1 = NormalizeDouble(iMA26_1,3);
   iMA26_2 = iMA26_Array[2]; iMA26_2 = NormalizeDouble(iMA26_2,3);
   

    if (iMA09_1 < iMA26_1 && iMA09_2 < iMA26_2)
    {Print("GreaterThan = sma9 = ", iMA09_1, ", sam26 = ", iMA26_1, "= 2sma9 = ", iMA09_2, ", 2sam26 = ", iMA26_2); return;}
      
   if (iMA09_1 > iMA26_1 && iMA09_2 > iMA26_2)
   {Print("LessThan = sma9 = ", iMA09_1, ", sam26 = ", iMA26_1, "= 2sma9 = ", iMA09_2, ", 2sam26 = ", iMA26_2); return;}
   

//+-------------preparation for Trades processing, assignment of price to be used

double sl, tp, price; ulong posTicket;

//--- Close Current Position 
      positionDelete(posTicket);
      trade.PositionClose(posTicket);
   Print("xx = sma9 = ", iMA09_1, ", sam26 = ", iMA26_1);     

if (iMA09_1 > iMA26_1) // buy
   {
   price=(double)SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   SLTPpriceBuy (price, sl, tp);
   if (LimitDistance == 0) trade.Buy(Lots,NULL,0,sl,tp,"gary1"); // then long
   if (LimitDistance != 0) trade.BuyLimit(Lots,price,NULL,sl,tp,0,0,"gary1");
   Print("yy = sma9 = ", iMA09_1, ", sam26 = ", iMA26_1);
   }

if (iMA09_1 < iMA26_1) // sell
   {
   price=(double)SymbolInfoDouble(_Symbol,SYMBOL_BID);
   SLTPpriceSell (price, sl, tp);
   if (LimitDistance == 0) trade.Sell(Lots,NULL,0,sl,tp,"gary2"); // then short
   if (LimitDistance != 0) trade.SellLimit(Lots,price,NULL,sl,tp,0,0,"gary2"); 
   Print("zz = sma9 = ", iMA09_1, ", sam26 = ", iMA26_1);
   }

}

//+------------------------------------------------------------------+
//| 05 Expert UserDefined function                                             |
//+------------------------------------------------------------------+

void SLTPpriceBuy (double &price, double &sl, double &tp)
{
   double limitPrice = price - LimitDistance*Point();
   if (LimitDistance == 0){price = price;}else if (LimitDistance != 0){price = limitPrice;}
   if (TpPoints == 0){tp = 0;} else {tp = price + TpPoints*Point();}; 
   tp = NormalizeDouble(tp,Digits());
   if (SlPoints == 0){sl = 0;} else {sl = price - SlPoints*Point();}; 
   sl = NormalizeDouble(sl,Digits()); 
   price = NormalizeDouble(price,Digits());
   return;
}

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

void SLTPpriceSell (double &price, double &sl, double &tp)
{
   double limitPrice = price + LimitDistance*Point();
   if (LimitDistance == 0){price = price;}else if (LimitDistance != 0){price = limitPrice;} 
   if (TpPoints == 0){tp = 0;} else {tp = price - TpPoints*Point();}; 
   tp = NormalizeDouble(tp,Digits());
   if (SlPoints == 0){sl = 0;} else {sl = price + SlPoints*Point();}; 
   sl = NormalizeDouble(sl,Digits()); 
   price = NormalizeDouble(price,Digits());
   return;
}

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

bool SLTPpriceModify (ulong &posTicket, double &sl, double &tp)
{  
   if (UseTrailingSL == false){return true;} //Check if using Trailing Stop Loss
   // Modifies SL of position to maintain SL, only when movement in profit direction.
   for(int i = 0; i < PositionsTotal(); i++)
   {
      posTicket = PositionGetTicket(i); // Scans all open positions
      if (PositionGetSymbol(POSITION_SYMBOL) != Symbol()) continue; // Scan Checks if Open Position if of correct symbol
      if (PositionGetInteger(POSITION_MAGIC) != EXPERT_MAGIC) continue; // Scan Checks if Open Position if of correct Magic Number
      
      if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) // Modifies buy positions
      {
         if (PositionGetDouble(POSITION_SL) < SymbolInfoDouble(Symbol(),SYMBOL_BID) - SlPoints*Point())
         {
         sl = SymbolInfoDouble(Symbol(),SYMBOL_BID) - SlPoints*Point();
         sl = NormalizeDouble(sl, Digits());
         tp = SymbolInfoDouble(Symbol(),SYMBOL_BID) + TpPoints*Point();
         tp = NormalizeDouble(tp, Digits());
         return false;  
         }
      }
      else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) // Modifies sell positions
      {
         if (PositionGetDouble(POSITION_SL) > SymbolInfoDouble(Symbol(), SYMBOL_ASK) + SlPoints*Point())
         {
         sl = SymbolInfoDouble(Symbol(), SYMBOL_ASK) + SlPoints*Point();
         sl = NormalizeDouble(sl, Digits());
         tp = SymbolInfoDouble(Symbol(), SYMBOL_ASK) - TpPoints*Point();
         tp = NormalizeDouble(tp, Digits());
         return false;           
         }
      }
   }
   return true;
}


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

void positionDelete (ulong &posTicket)
{
   for(int i = 0; i < PositionsTotal(); i++){posTicket = PositionGetTicket(i);} // Scans all open orders
}

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

//--- User Function to stop code untill new bar, No extra brace needed
bool is_new_bar()
{
   static datetime last_time = 0;
   datetime curr_time = (datetime)SeriesInfoInteger(Symbol(), PERIOD_CURRENT, SERIES_LASTBAR_DATE);
   if(last_time == curr_time) return false;
   last_time = curr_time;
   return true;
}

 
Lorentzos Roussos #:

Hello

You had these errors :

Thank you so much.


i cant believe i missed point 1 above --- 1.if (iMA09_1 < iMA26_1 && iMA09_2 < iMA26_2)

I understand the filling of the buffers better now.

I was aware of the price issue, i had set the LimitDistance to 0 for the test but forgot to put it back in for posting here....

Long road ahead of me.. 

It is working now... Thank you

 
gardee005 #:

Thank you so much.


i cant believe i missed point 1 above --- 1.if (iMA09_1 < iMA26_1 && iMA09_2 < iMA26_2)

I understand the filling of the buffers better now.

I was aware of the price issue, i had set the LimitDistance to 0 for the test but forgot to put it back in for posting here....

Long road ahead of me.. 

It is working now... Thank you

yeah it happens

as you progress in coding you will notice the errors are more like #1 there 

You are welcome ,cheers

☕️