problem with iCustom

 

hi 

here I have a custom indicator , But when I use it in my expert 's backtest, I only receve maximum one signal !

 and in the back test  I  only have maximum 1 trade (depending on start time of backtest ) !!

here I have deleted the SendOrder to minimize code size , i only receive one print


#property copyright "Copyright 2024,04, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(IsNewCandle())
     {
      if(buy())
        {


        }

      if(sell())
        {


        }
     }   // -----------------End of NewCandle Block-------------
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double buy_v=0;
bool buy()
  {
   buy_v=iCustom(NULL,0,"MACD_his_Brout_V00",0,1);
   if(buy_v>0)
     {
      printf(buy_v+"  signal  Buy " +TimeToString(iTime(NULL,0,0)));
      return true;
     }
   return false;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double sell_v=0;
bool sell()
  {
   sell_v=iCustom(NULL,0,"MACD_his_Brout_V00",1,1);
   if(sell_v>0)
     {
      printf(sell_v+"signal  Sell " +iTime(NULL,0,0));
      return true;
     }
   return false;
  }
//+------------------------------------------------------------------+
bool IsNewCandle()
  {
   static datetime lasttime=0;
   if(iTime(NULL,0,0)==lasttime)
      return false;
   else
      lasttime=iTime(NULL,0,0);
   return true;
  }

But in this case (below) I have correct nonzero return from indicator 

#property copyright "Copyright 2024,02, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   for(int i=0; i<300; i++)
     {
        if(iCustom(NULL,0,"MACD_his_Brout_V00",0,i)>0)
        {
         printf(iCustom(NULL,0,"MACD_his_Brout_V00",0,i)+" signal  Buy "+ iTime(NULL,0,i));
        }

      if(iCustom(NULL,0,"MACD_his_Brout_V00",1,i)>0)
        {
         printf(iCustom(NULL,0,"MACD_his_Brout_V00",1,i)+" signal  Sell "+iTime(NULL,0,i));
        }
     }

   return(INIT_SUCCEEDED);
  }
Files:
 
Mehrdad Sarrafi: here I have a custom indicator , But when I use it in my expert 's backtest, I only receve maximum one signal !

Do you really expect an answer? There are no mind readers here and our crystal balls are cracked, so we can't see your machine.
     How To Ask Questions The Smart Way. (2004)
          Be precise and informative about your problem

We can't see your broken code.

Always post all relevant code (using Code button) or attach the source file.

Your problem is with your broken indicator, which we can't see. Or it is with your lack of history (current timeframe and all lower ones) which we can't see.

 
William Roeder #:

Do you really expect an answer? There are no mind readers here and our crystal balls are cracked, so we can't see your machine.
     How To Ask Questions The Smart Way. (2004)
          Be precise and informative about your problem

We can't see your broken code.

Always post all relevant code (using Code button) or attach the source file.

Your problem is with your broken indicator, which we can't see. Or it is with your lack of history (current timeframe and all lower ones) which we can't see.

the indicator file is attached as MACD_his_Brout_V00.mq4,

but as i said  I have deleted the SendOrder and tp sl asignments to minimize code size ,

i only receive one print in the expert tab  output 

 
Your buffers and loop are as-series (bar zero is most recent).
MacdBuffer[i]=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i)-//InpFastEMA
              iMA(NULL,0,26,0,MODE_EMA,PRICE_CLOSE,i);//InpSlowEMA
Then you access them into the future (non-series). What happens when limit equals one (second tick)?
for(int j=limit-1; j>0; j--){
 ⋮
   if(MacdBuffer[j]>0 && MacdBuffer[j-1]<0)  // cross down 
You don't set the arrays to as-series before access.

To determine the indexing direction of time[], open[], high[], low[], close[], tick_volume[], volume[] and spread[], call ArrayGetAsSeries(). In order not to depend on default values, you should unconditionally call the ArraySetAsSeries() function for those arrays, which are expected to work with.
          Event Handling Functions - Functions - Language Basics - MQL4 Reference

             BufferBuy[j]=close[j];
 
William Roeder #:
Your buffers and loop are as-series (bar zero is most recent).
Then you access them into the future (non-series). What happens when limit equals one (second tick)?
You don't set the arrays to as-series before access.

thank you ,i did some corrections and attached the file again but the expert still doesn't work.

if(limit==rates_total)
   limit--;

   for( j=limit-1; j>=0; j--)
     {
///....
      if(MacdBuffer[j+1]>0 && MacdBuffer[j]<0)  // cross down
        {
        }
   }

1.Should I set indicators buffers as series? Or they are as-series by default. I set three Buffers as series, but it doesn't affect anything !

2.I indexed seccond loop as non-series because I want to design a machine state that decides based on previouse state , but in first loop I don't need to do so

3.I wonder how the indicator shows buy and sell signals on chart but it doesn't work when called by iCustom in expert!

4. Do experts calculate all indexes of indicator  each time  indicator 's called  (prev_calculated = 0 ),or just calculates last candles (limit=1) , like when indicator is attached to the chart. (I assume each time indicator is called, calculation is done with prev_calculated = 0  in backtest and when expert is attached to a chart(live test)).

I usually use bars2proccess as an input to indicator to minimize calculations in calling indicator in experts. Is it require ?

Files:
 
Mehrdad Sarrafi #:

thank you ,i did some corrections and attached the file again but the expert still doesn't work.

1.Should I set indicators buffers as series? Or they are as-series by default. I set three Buffers as series, but it doesn't affect anything !

2.I indexed seccond loop as non-series because I want to design a machine state that decides based on previouse state , but in first loop I don't need to do so

3.I wonder how the indicator shows buy and sell signals on chart but it doesn't work when called by iCustom in expert!

4. Do experts calculate all indexes of indicator  each time  indicator 's called  (prev_calculated = 0 ),or just calculates last candles (limit=1) , like when indicator is attached to the chart. (I assume each time indicator is called, calculation is done with prev_calculated = 0  in backtest and when expert is attached to a chart(live test)).

I usually use bars2proccess as an input to indicator to minimize calculations in calling indicator in experts. Is it require ?

No body help me ?!? 

MQL Company 's specialists do not check these posts ?!!?

in servise desk has written  any technical questions related to MQL should written in forum !!


why this indicator that i have written work on chart but does not responses in expert backtest??!!


thanks in advance

 
Mehrdad Sarrafi #:

No body help me ?!? 

MQL Company 's specialists do not check these posts ?!!?

People usually check posts and respond based on their interest. William pointed a few good instructions to make your code better. But making it work is not peoples' responsibility.

 
Yashar Seyyedin #:

People usually check posts and respond based on their interest. William pointed a few good instructions to make your code better. But making it work is not peoples' responsibility.

Dear yashar ,  I do some correction based on william 's notices

I will insert my code to see .

but I think there are some main problem !!

as I asked , but nobody answered 

" ...3.I wonder how the indicator shows buy and sell signals on chart but it doesn't work when called by iCustom in expert!

4. Do experts calculate all indexes of indicator , each time  indicator is called  (prev_calculated = 0 ),or just calculates last candles (limit=1) , like when indicator is attached to the chart.

(I assume each time indicator is called, calculation is done with prev_calculated = 0  ,  in backtest and live test ( when expert is attached to a chart) ).  "

 
William Roeder #:
Your buffers and loop are as-series (bar zero is most recent).
Then you access them into the future (non-series). What happens when limit equals one (second tick)?
You don't set the arrays to as-series before access.

I do some correction

in simple indicator written below , expert works correctly

//+------------------------------------------------------------------+
//|                                              MACD_cz_test.mq4      |
//|                          Copyright 2024,02, Mehrdad Sarrafi |
//|                                https://www.te.com/m_sarrafi |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024,04, Mehrdad Sarrafi"
#property link      "https://www.te.com/m_sarrafi"
#property version   "1.00"
#property strict
#property indicator_chart_window

#property indicator_buffers 3
#property indicator_plots   2
//--- plot
#property indicator_label1 "Buy"
#property indicator_label2  "Sell"



//--- indicator buffers
double         MacdBuffer[],BufferBuy[],BufferSell[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferBuy,INDICATOR_DATA);
   SetIndexBuffer(1,BufferSell,INDICATOR_DATA);
   SetIndexBuffer(2,MacdBuffer,INDICATOR_CALCULATIONS);
//---- drawing settings
   SetIndexStyle(0,DRAW_ARROW,STYLE_SOLID,4,clrGreen);   //Blue ,clrLightBlue,
   SetIndexStyle(1,DRAW_ARROW,STYLE_SOLID,4,clrRed);     //clrPink

   SetIndexArrow(0,221);// ,200
   SetIndexArrow(1,222);// ,202

   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
   SetIndexEmptyValue(2,0.0);

   IndicatorSetString(INDICATOR_SHORTNAME,"MACD Cross Zero");
//---
   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 i,j,limit;
//---
   limit=rates_total-prev_calculated;
   if(prev_calculated>0)
      limit++;
   if(limit==rates_total)
      limit--;
   ArraySetAsSeries(MacdBuffer,True);
   ArraySetAsSeries(BufferSell,True);
   ArraySetAsSeries(BufferBuy,True);

//--- main loop of calculations
//   for(i=0; i<limit; i++)
   for(i=limit-1; i>=0; i--)
     {
      MacdBuffer[i]=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i)-//InpFastEMA
                    iMA(NULL,0,26,0,MODE_EMA,PRICE_CLOSE,i);//InpSlowEMA
     }
//---limit=1;
//   for( j=0;j<limit; j++)
   for(j=limit-1; j>=0; j--)
     {
      //---
      if(MacdBuffer[j+1]>0 && MacdBuffer[j]<0)  // cross down
        {
            BufferBuy[j]=close[j];
        }
      //---
      if(MacdBuffer[j+1]<0 && MacdBuffer[j]>0)  // cross up
        {
            BufferSell[j]=close[j];
        }
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


 but when I write some complicated state machine , despide compliance with  above notices , expert does not work


//+------------------------------------------------------------------+
//|                                           MACD_his_Brout_V00.mq4 |
//|                               Copyright 2024,02, Mehrdad Sarrafi |
//|                                     https://www.te.com/m_sarrafi |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024,02, Mehrdad Sarrafi"
#property link      "https://www.te.com/m_sarrafi"
#property version   "1.00"
#property strict
#property indicator_chart_window

#property indicator_buffers 3
#property indicator_plots   2
//--- plot
#property indicator_label1 "Buy"
#property indicator_label2  "Sell"


int            bar_count_Brout=30;
int            cz_ext_max=7;

//--- indicator buffers
double         MacdBuffer[],BufferBuy[],BufferSell[];

bool cr_up=false,cr_dwn=false;
bool search_Br_up=false,search_Br_dwn=false;
int cr_up_i=0,cr_dwn_i=0;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class his_ext
  {
public:
   double            value;
   int               index;
   bool              valid;
                     his_ext(void) {value=0 ; index=0; valid=false;};
                    ~his_ext(void) {};
  } ext_down,ext_up;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferBuy,INDICATOR_DATA);
   SetIndexBuffer(1,BufferSell,INDICATOR_DATA);
   SetIndexBuffer(2,MacdBuffer,INDICATOR_CALCULATIONS);
//---- drawing settings
   SetIndexStyle(0,DRAW_ARROW,STYLE_SOLID,4,clrGreen);//Blue ,clrLightBlue,
   SetIndexStyle(1,DRAW_ARROW,STYLE_SOLID,4,clrRed);//clrPink

   SetIndexArrow(0,221);// ,200
   SetIndexArrow(1,222);// ,202

   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
   SetIndexEmptyValue(2,0.0);

   IndicatorSetString(INDICATOR_SHORTNAME,"MACD Historam BrOut");
//---
   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 i,j,limit;
//---
   limit=rates_total-prev_calculated;
   if(prev_calculated>0)
      limit++;
   if(limit==rates_total)
      limit--;
   ArraySetAsSeries(MacdBuffer,True);
   ArraySetAsSeries(BufferSell,True);
   ArraySetAsSeries(BufferBuy,True);

//--- main loop of calculations
//   for(i=0; i<limit; i++)
   for(i=limit-1; i>=0; i--)
     {
      MacdBuffer[i]=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i)-//InpFastEMA
                    iMA(NULL,0,26,0,MODE_EMA,PRICE_CLOSE,i);//InpSlowEMA
     }
//---limit=1;
   for(j=limit-1; j>=0; j--)
     {
      //---
      if(search_Br_dwn && ext_down.value!=0 && ext_down.index>j+1)   //-------------    SEARCH BREAK DOWN ----------------------
        {
         if(MacdBuffer[j]<=ext_down.value)
           {
            //       printf("setting Sell"+iTime(NULL,0,j));
            BufferSell[j]=close[j];
            search_Br_dwn=false;
           }
         if(MathAbs(ext_down.index-j)>bar_count_Brout)      // does not search  break down after bar_count_Brout candles 
           {
            search_Br_dwn=false;
            ext_down.value=0;
            ext_down.index=0;
           }
        }
      if(MacdBuffer[j+1]>0 && MacdBuffer[j]<0)  // cross down
        {
         cr_dwn=true;
         cr_dwn_i=j;
        }

      if(cr_dwn)
        {
         if(MathAbs(cr_dwn_i - j)<=cz_ext_max)     // only for cz_ext_max candles search for extremum down
           {
            if(MacdBuffer[j+1]<=MacdBuffer[j])     // find extremum down when change color to green 
              {
               ext_down.value=MacdBuffer[j+1];
               ext_down.index=j;
               cr_dwn=false;
               search_Br_dwn=true;
              }
           }
         else
           {
            ext_down.value=0;
            ext_down.index=0;
            cr_dwn=false;
            search_Br_dwn=false;
           }
        }
      //----------------------------------------------------------------    SEARCH BREAK UP ----------------------
      //---
      if(search_Br_up && ext_up.value!=0 && ext_up.index>j+1)// *** atleast 2 candle
        {
         if(MacdBuffer[j]>=ext_up.value)
           {
            BufferBuy[j]=close[j];
            search_Br_up=false;
           }
         if(MathAbs(ext_up.index-j)>bar_count_Brout)
           {
            search_Br_up=false;
            ext_up.value=0;
            ext_up.index=0;
           }
        }
      if(MacdBuffer[j+1]<0 && MacdBuffer[j]>0)  // cross up
        {
         cr_up= true;
         cr_up_i=j;
        }

      if(cr_up)
        {
         if(MathAbs(cr_up_i - j)<=cz_ext_max)
           {
            if(MacdBuffer[j+1]>=MacdBuffer[j])
              {
               ext_up.value=MacdBuffer[j+1];
               ext_up.index=j;
               cr_up=false;
               search_Br_up=true;
              }
           }
         else
           {
            ext_up.value=0;
            ext_up.index=0;
            cr_up=false;
            search_Br_up=false;
           }
        }
     }      // end of for


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



 and this is my simple expert 

that I check prints output in journal tab of tester


//+------------------------------------------------------------------+
//|                                   Expert_macd_hist_BrOut_V00.mq4 |
//|                               Copyright 2024,02, Mehrdad Sarrafi |
//|                                     https://www.te.com/m_sarrafi |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024,04, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

string ind_name="MACD_his_Brout_V00";        
//string ind_name="MACD_cz_test";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();

  }
//+------------------------------------------------------------------+
//| Expert tick function                                                 |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(IsNewCandle())
     {
    if(buy())
        {


        }

      if(sell())
        {


        }
     }   // -----------------End of NewCandle Block-------------
  }
//+------------------------------------------------------------------+
//|                                                                                |
//+------------------------------------------------------------------+
double buy_v=0;
bool buy()
  {
   buy_v=iCustom(NULL,0,ind_name,0,1);
   if(buy_v>0)
     {
      printf(DoubleToString(buy_v)+"  signal  Buy " +TimeToString(iTime(NULL,0,0)));
      return true;
     }
   return false;
  }
//+------------------------------------------------------------------+
//|                                                                                   |
//+------------------------------------------------------------------+
double sell_v=0;
bool sell()
  {
   sell_v=iCustom(NULL,0,ind_name,1,1);
   if(sell_v>0)
     {
      printf(DoubleToString(sell_v)+"  signal  Sell " +TimeToString(iTime(NULL,0,0)));
      return true;
     }
   return false;
  }
//+------------------------------------------------------------------+
bool IsNewCandle()
  {
   static datetime lasttime=0;
   if(iTime(NULL,0,0)==lasttime)
      return false;
   else
      lasttime=iTime(NULL,0,0);
   return true;
  }
//+------------------------------------------------------------------+
 
William Roeder #:
Your buffers and loop are as-series (bar zero is most recent).
Then you access them into the future (non-series). What happens when limit equals one (second tick)?
You don't set the arrays to as-series before access.

I do some correction

in simple indicator written below , expert works correctly 

//+------------------------------------------------------------------+
//|                                              MACD_cz_test.mq4      |
//|                          Copyright 2024,02, 			|   
//|                                					 |
//+------------------------------------------------------------------+
#property version   "1.00"
#property strict
#property indicator_chart_window

#property indicator_buffers 3
#property indicator_plots   2
//--- plot
#property indicator_label1 "Buy"
#property indicator_label2  "Sell"



//--- indicator buffers
double         MacdBuffer[],BufferBuy[],BufferSell[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferBuy,INDICATOR_DATA);
   SetIndexBuffer(1,BufferSell,INDICATOR_DATA);
   SetIndexBuffer(2,MacdBuffer,INDICATOR_CALCULATIONS);
//---- drawing settings
   SetIndexStyle(0,DRAW_ARROW,STYLE_SOLID,4,clrGreen);   //Blue ,clrLightBlue,
   SetIndexStyle(1,DRAW_ARROW,STYLE_SOLID,4,clrRed);     //clrPink

   SetIndexArrow(0,221);// ,200
   SetIndexArrow(1,222);// ,202

   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
   SetIndexEmptyValue(2,0.0);

   IndicatorSetString(INDICATOR_SHORTNAME,"MACD Cross Zero");
//---
   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 i,j,limit;
//---
   limit=rates_total-prev_calculated;
   if(prev_calculated>0)
      limit++;
   if(limit==rates_total)
      limit--;
   ArraySetAsSeries(MacdBuffer,True);
   ArraySetAsSeries(BufferSell,True);
   ArraySetAsSeries(BufferBuy,True);

//--- main loop of calculations
//   for(i=0; i<limit; i++)
   for(i=limit-1; i>=0; i--)
     {
      MacdBuffer[i]=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i)-//InpFastEMA
                    iMA(NULL,0,26,0,MODE_EMA,PRICE_CLOSE,i);//InpSlowEMA
     }
//---limit=1;
//   for( j=0;j<limit; j++)
   for(j=limit-1; j>=0; j--)
     {
      //---
      if(MacdBuffer[j+1]>0 && MacdBuffer[j]<0)  // cross down
        {
            BufferBuy[j]=close[j];
        }
      //---
      if(MacdBuffer[j+1]<0 && MacdBuffer[j]>0)  // cross up
        {
            BufferSell[j]=close[j];
        }
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


 

but when I write some complicated state machine,

despide compliance with  above notices , expert does not work  !!!!


//+------------------------------------------------------------------+
//|                                           MACD_his_Brout_V00.mq4 |
//+------------------------------------------------------------------+
#property version   "1.00"
#property strict
#property indicator_chart_window

#property indicator_buffers 3
#property indicator_plots   2
//--- plot
#property indicator_label1 "Buy"
#property indicator_label2  "Sell"


int            bar_count_Brout=30;
int            cz_ext_max=7;

//--- indicator buffers
double         MacdBuffer[],BufferBuy[],BufferSell[];

bool cr_up=false,cr_dwn=false;
bool search_Br_up=false,search_Br_dwn=false;
int cr_up_i=0,cr_dwn_i=0;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class his_ext
  {
public:
   double            value;
   int               index;
   bool              valid;
                     his_ext(void) {value=0 ; index=0; valid=false;};
                    ~his_ext(void) {};
  } ext_down,ext_up;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferBuy,INDICATOR_DATA);
   SetIndexBuffer(1,BufferSell,INDICATOR_DATA);
   SetIndexBuffer(2,MacdBuffer,INDICATOR_CALCULATIONS);
//---- drawing settings
   SetIndexStyle(0,DRAW_ARROW,STYLE_SOLID,4,clrGreen);//Blue ,clrLightBlue,
   SetIndexStyle(1,DRAW_ARROW,STYLE_SOLID,4,clrRed);//clrPink

   SetIndexArrow(0,221);// ,200
   SetIndexArrow(1,222);// ,202

   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
   SetIndexEmptyValue(2,0.0);

   IndicatorSetString(INDICATOR_SHORTNAME,"MACD Historam BrOut");
//---
   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 i,j,limit;
//---
   limit=rates_total-prev_calculated;
   if(prev_calculated>0)
      limit++;
   if(limit==rates_total)
      limit--;
   ArraySetAsSeries(MacdBuffer,True);
   ArraySetAsSeries(BufferSell,True);
   ArraySetAsSeries(BufferBuy,True);

//--- main loop of calculations
//   for(i=0; i<limit; i++)
   for(i=limit-1; i>=0; i--)
     {
      MacdBuffer[i]=iMA(NULL,0,12,0,MODE_EMA,PRICE_CLOSE,i)-//InpFastEMA
                    iMA(NULL,0,26,0,MODE_EMA,PRICE_CLOSE,i);//InpSlowEMA
     }
//---limit=1;
   for(j=limit-1; j>=0; j--)
     {
      //---
      if(search_Br_dwn && ext_down.value!=0 && ext_down.index>j+1)   //-------------    SEARCH BREAK DOWN ----------------------
        {
         if(MacdBuffer[j]<=ext_down.value)
           {
            //       printf("setting Sell"+iTime(NULL,0,j));
            BufferSell[j]=close[j];
            search_Br_dwn=false;
           }
         if(MathAbs(ext_down.index-j)>bar_count_Brout)      // does not search  break down after bar_count_Brout candles 
           {
            search_Br_dwn=false;
            ext_down.value=0;
            ext_down.index=0;
           }
        }
      if(MacdBuffer[j+1]>0 && MacdBuffer[j]<0)  // cross down
        {
         cr_dwn=true;
         cr_dwn_i=j;
        }

      if(cr_dwn)
        {
         if(MathAbs(cr_dwn_i - j)<=cz_ext_max)     // only for cz_ext_max candles search for extremum down
           {
            if(MacdBuffer[j+1]<=MacdBuffer[j])     // find extremum down when change color to green 
              {
               ext_down.value=MacdBuffer[j+1];
               ext_down.index=j;
               cr_dwn=false;
               search_Br_dwn=true;
              }
           }
         else
           {
            ext_down.value=0;
            ext_down.index=0;
            cr_dwn=false;
            search_Br_dwn=false;
           }
        }
      //----------------------------------------------------------------    SEARCH BREAK UP ----------------------
      //---
      if(search_Br_up && ext_up.value!=0 && ext_up.index>j+1)// *** atleast 2 candle
        {
         if(MacdBuffer[j]>=ext_up.value)
           {
            BufferBuy[j]=close[j];
            search_Br_up=false;
           }
         if(MathAbs(ext_up.index-j)>bar_count_Brout)
           {
            search_Br_up=false;
            ext_up.value=0;
            ext_up.index=0;
           }
        }
      if(MacdBuffer[j+1]<0 && MacdBuffer[j]>0)  // cross up
        {
         cr_up= true;
         cr_up_i=j;
        }

      if(cr_up)
        {
         if(MathAbs(cr_up_i - j)<=cz_ext_max)
           {
            if(MacdBuffer[j+1]>=MacdBuffer[j])
              {
               ext_up.value=MacdBuffer[j+1];
               ext_up.index=j;
               cr_up=false;
               search_Br_up=true;
              }
           }
         else
           {
            ext_up.value=0;
            ext_up.index=0;
            cr_up=false;
            search_Br_up=false;
           }
        }
     }      // end of for


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



 and this is my simple expert 

that I check prints output in journal tab of tester


//+------------------------------------------------------------------+
//|                                   Expert_macd_hist_BrOut_V00.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024,04, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

string ind_name="MACD_his_Brout_V00";        
//string ind_name="MACD_cz_test";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();

  }
//+------------------------------------------------------------------+
//| Expert tick function                                                 |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(IsNewCandle())
     {
    if(buy())
        {


        }

      if(sell())
        {


        }
     }   // -----------------End of NewCandle Block-------------
  }
//+------------------------------------------------------------------+
//|                                                                                |
//+------------------------------------------------------------------+
double buy_v=0;
bool buy()
  {
   buy_v=iCustom(NULL,0,ind_name,0,1);
   if(buy_v>0)
     {
      printf(DoubleToString(buy_v)+"  signal  Buy " +TimeToString(iTime(NULL,0,0)));
      return true;
     }
   return false;
  }
//+------------------------------------------------------------------+
//|                                                                                   |
//+------------------------------------------------------------------+
double sell_v=0;
bool sell()
  {
   sell_v=iCustom(NULL,0,ind_name,1,1);
   if(sell_v>0)
     {
      printf(DoubleToString(sell_v)+"  signal  Sell " +TimeToString(iTime(NULL,0,0)));
      return true;
     }
   return false;
  }
//+------------------------------------------------------------------+
bool IsNewCandle()
  {
   static datetime lasttime=0;
   if(iTime(NULL,0,0)==lasttime)
      return false;
   else
      lasttime=iTime(NULL,0,0);
   return true;
  }
//+------------------------------------------------------------------+
 
William Roeder #:

You don't set the arrays to as-series before access.

I wonder what did you mean by this sentence!!!?

 maybe you meant something different than I understood , and then you donot answer me again  bacaue you think I ....

if so , It is better to go to an English class to learn the tenses or use google translate always before answering poor questioner .

Reason: