How to Determine if an EMA Crosses Previous Candles

 

Hi.

A function in my EA function should return true when EMA 13 crosses the previous two candles. The idea is to see if the EMA value was between the candle's open and close price. It doesn't work.

Here's an ASCII visual of the candles and EMA.

          ++
    ++   ++
    ++   ++   ---------
---++---++---
    ++   ++   ++
    ++   ++   ++

   P2   P1   Current Candle


void OnTick()
{
   MqlRates Rates[];
   ArraySetAsSeries(Rates, true);
   CopyRates(_Symbol, _Period, 0, 3, Rates);

   double EMA13Array[];
   int EMA13Def = iMA(_Symbol, _Period, 13, 0, MODE_EMA, PRICE_CLOSE);
   ArraySetAsSeries(EMA13Array, true);
   CopyBuffer(EMA13Def, 0 , 0, 3, EMA13Array);

   IsEMA13CrossPreviousCandles(EMA13Array, Rates);
}


bool IsEMA13CrossPreviousCandles(double &EMA13Array[], MqlRates &Rates[])
{
   bool isBetweenP1Candle = false;
   bool isBetweenP2Candle = false;

   // Is current EMA13 between previous candle (P1) open and close price
   if ((EMA13Array[1] > Rates[1].open) && (EMA13Array[1] < Rates[1].close)) {
      isBetweenP1Candle = true;
   }

   // Is current EMA13 between previous  candle (P2) open and close price 
   if ((EMA13Array[2] > Rates[2].open) && (EMA13Array[2] < Rates[2].close)) {
      isBetweenP2Candle = true;
   }

   if ( isBetweenP1Candle && isBetweenP2Candle ) {
      return true;
   }
   
   return false;
}
Documentation on MQL5: Constants, Enumerations and Structures / Indicator Constants / Price Constants
Documentation on MQL5: Constants, Enumerations and Structures / Indicator Constants / Price Constants
  • www.mql5.com
Calculations of technical indicators require price values and/or values of volumes, on which calculations will be performed. There are 7 predefined identifiers from the ENUM_APPLIED_PRICE enumeration, used to specify the desired price base for calculations. If a technical indicator uses for calculations price data, type of which is set by...
 
void OnTick()
{
   …
   int EMA13Def = iMA(_Symbol, _Period, 13, 0, MODE_EMA, PRICE_CLOSE);
   ArraySetAsSeries(EMA13Array, true);
   CopyBuffer(EMA13Def, 0 , 0, 3, EMA13Array);

Perhaps you should read the manual, especially the examples.
   How To Ask Questions The Smart Way. 2004
      How To Interpret Answers.
         RTFM and STFW: How To Tell You've Seriously Screwed Up.

They all (including iCustom) return a handle (an int). You get that in OnInit. In OnTick (after the indicator has updated its buffers,) you use the handle, shift and count to get the data.
          Technical Indicators - Reference on algorithmic/automated trading language for MetaTrader 5
          Timeseries and Indicators Access / CopyBuffer - Reference on algorithmic/automated trading language for MetaTrader 5
          How to start with MQL5 - General - MQL5 programming forum - Page 3 #22 2020.03.08
          How to start with MQL5 - MetaTrader 5 - General - MQL5 programming forum - Page 7 #61 2020.07.05
          How to call indicators in MQL5 - MQL5 Articles 12 March 2010
 

Actually

int EMA13Def = iMA(_Symbol, _Period, 13, 0, MODE_EMA, PRICE_CLOSE);

iMA returns the value depends on the index and it is double. Your last parameter is missing (the index).

Call it directly as

 ((iMA(_Symbol, _Period, 13, 0, MODE_EMA, PRICE_CLOSE, 2) > Rates[2].open) && (iMA(_Symbol, _Period, 13, 0, MODE_EMA, PRICE_CLOSE, 2) < Rates[2].close))
 
Georgi Gaydarov: Call it directly as
 ((iMA(_Symbol, _Period, 13, 0, MODE_EMA, PRICE_CLOSE, 2) > Rates[2].open) && (iMA(_Symbol, _Period, 13, 0, MODE_EMA, PRICE_CLOSE, 2) < Rates[2].close))

Are your books one column but two feet wide? No because that is unreadable. They are 6 inches, sometimes two columns, so you can read it easily. So should be your code. I'm not going to go scrolling (or moving my eyes) back and forth trying to read it. Don't copy and paste code (iMAs), write self documenting code.

double ma2         = iMA(_Symbol, _Period, 13, 0, MODE_EMA, PRICE_CLOSE, 2);
bool   openedBelow = ma2 > Rates[2].open,
       closedAbove = ma2 < Rates[2].close,
       crossedUp   = openedBelow  && closedAbove;
 
Thanks for responding. I really appreciate it. I will read the docs.