Differences in buffers between EAs and indicators

 

Hi everyone, i'm new to MQL4 and i'm working on an EA similar to an MA ribbon.

I shared both the indicator and Ea versions. I had no issue with the indicator version, but i was getting "Array out of range" error in the EA version, so i added the arraypush method as a solution.
However, i don't understand why i had to apply a different method compared to the indicator. I would appreciate it if you could clarify this for me.

I realized that Eas cannot draw on the screen like indicators. I figured this out later. Where can i access this king of informaisons? The Mql4 document didn't satisft me much.


Also, I am looking for a mentor who can help me with mql4 coding. Is there anyone who can assist?

Thanks!


Ea Code:

//+------------------------------------------------------------------+
//|                                     MilRibbonReverseStrategy.mq4 |
//|                                                         Milvetti |
//|                                         https://www.milvetti.com |
//+------------------------------------------------------------------+
#property copyright "Milvetti"
#property link      "https://www.milvetti.com"
#property version   "1.00"
#property strict


#property indicator_buffers 3
#property indicator_color1 clrYellow //1
#property indicator_color2 clrOrange //2
#property indicator_color3 clrOrangeRed //2


input int ma1Period = 9; //Ma1 Period
input int ma2Period = 15; //Ma2 Period
input int ma3Period = 20; //Ma3 Period


double ma1Buffer[];
double ma2Buffer[];
double ma3Buffer[];

#define ma1 0
#define ma2 1
#define ma3 2

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
 
   SetIndexBuffer(ma1,ma1Buffer);
   SetIndexStyle(ma1,DRAW_LINE);
   SetIndexLabel(ma1,"Band1");
    
   SetIndexBuffer(ma2,ma2Buffer);
   SetIndexStyle(ma2,DRAW_LINE);
   SetIndexLabel(ma2,"Band2");
   
   SetIndexBuffer(ma3,ma3Buffer);
   SetIndexStyle(ma3,DRAW_LINE);
   SetIndexLabel(ma3,"Band3");
   
   IndicatorDigits(Digits+1);
   string shortName = "MRS ";
   IndicatorShortName(shortName);
   
   
  
  
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+


int prev_calculated =0;


void OnTick()
  {
//---

  int rates_total = iBars(NULL,0);
  int limit = rates_total - prev_calculated;
   if (prev_calculated > 0)
      limit++;
   
   for (int i = 0; i < limit; i++)
   {
   double ma1Value = iMA(Symbol(),PERIOD_CURRENT,ma1Period,0,MODE_EMA,PRICE_CLOSE,i);
   double ma2Value = iMA(Symbol(),PERIOD_CURRENT,ma2Period,0,MODE_EMA,PRICE_CLOSE,i);
   double ma3Value = iMA(Symbol(),PERIOD_CURRENT,ma3Period,0,MODE_EMA,PRICE_CLOSE,i);
   
   ArrayPush(ma1Buffer,ma1Value);
   ArrayPush(ma1Buffer,ma2Value);
   ArrayPush(ma1Buffer,ma3Value);
   /*
   ma1Buffer[i] = ma1Value;
   ma2Buffer[i] = ma2Value;
   ma3Buffer[i] = ma3Value;
   */

   }
   prev_calculated=rates_total;
   
  }
//+------------------------------------------------------------------+
void ArrayPush(double &arr[],double inp ){

   int sz = ArrayResize(arr,ArraySize(arr)+1);
   arr[sz-1] = inp;
}


Indicator Code:

//+------------------------------------------------------------------+
//|                                    MilRibbonReverseIndicator.mq4 |
//|                                                         Milvetti |
//|                                         https://www.milvetti.com |
//+------------------------------------------------------------------+
#property copyright "Milvetti"
#property link      "https://www.milvetti.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

#property indicator_buffers 3
#property indicator_color1 clrYellow //1
#property indicator_color2 clrOrange //2
#property indicator_color3 clrOrangeRed //2


input int ma1Period = 9; //Ma1 Period
input int ma2Period = 15; //Ma2 Period
input int ma3Period = 20; //Ma3 Period


double ma1Buffer[];
double ma2Buffer[];
double ma3Buffer[];

#define ma1 0
#define ma2 1
#define ma3 2

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
  
  
  
   SetIndexBuffer(ma1,ma1Buffer);
   SetIndexStyle(ma1,DRAW_LINE);
   SetIndexLabel(ma1,"Band1");
    
   SetIndexBuffer(ma2,ma2Buffer);
   SetIndexStyle(ma2,DRAW_LINE);
   SetIndexLabel(ma2,"Band2");
   
   SetIndexBuffer(ma3,ma3Buffer);
   SetIndexStyle(ma3,DRAW_LINE);
   SetIndexLabel(ma3,"Band3");
   
   IndicatorDigits(Digits+1);
   string shortName = "MRS ";
   IndicatorShortName(shortName);
   
   
  
//--- indicator buffers mapping
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   
   
  int limit = rates_total - prev_calculated;
  if (prev_calculated > 0)
   limit++;
   
   for (int i = 0; i < limit; i++)
   {
   
   double ma1Value = iMA(Symbol(),PERIOD_CURRENT,ma1Period,0,MODE_EMA,PRICE_CLOSE,i);
   double ma2Value = iMA(Symbol(),PERIOD_CURRENT,ma2Period,0,MODE_EMA,PRICE_CLOSE,i);
   double ma3Value = iMA(Symbol(),PERIOD_CURRENT,ma3Period,0,MODE_EMA,PRICE_CLOSE,i);
   

   ma1Buffer[i] = ma1Value;
   ma2Buffer[i] = ma2Value;
   ma3Buffer[i] = ma3Value;

   }
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 

Don't try to do that. There are no buffers, no IndicatorCounted() or prev_calculated in EAs. No way to know if older bars have changed or been added (history update.)

Just get the value(s) of the indicator(s) into EA/indicator (using iCustom) and do what you want with it.
          (MT4) Detailed explanation of iCustom - MQL4 programming forum (2017)

You should encapsulate your iCustom calls to make your code self-documenting.
          take candle color hekin ashi - MQL4 and MetaTrader 4 #8-10 or #1 (2018)

 
William Roeder #:

Don't try to do that. There are no buffers, no IndicatorCounted() or prev_calculated in EAs. No way to know if older bars have changed or been added (history update.)

Just get the value(s) of the indicator(s) into EA/indicator (using iCustom) and do what you want with it.
          (MT4) Detailed explanation of iCustom - MQL4 programming forum (2017)

You should encapsulate your iCustom calls to make your code self-documenting.
          take candle color hekin ashi - MQL4 and MetaTrader 4 #8-10 or #1 (2018)

I think I need to change my sources. Because I was advised to use a method similar to this. Do you have any resource suggestions for me as a document or video. It can also be a course.