EA places multiple instances iCustom indicator on chart

Hi there,

Here’s the thing, I’m developing an EA, I’m reading a custom indicator (WT_TMA) using iCustom as the usual, but it creates multiple instances of the same indicator at backtest, I’ve already change the indicator to other custom one to test it and it works fine, but using the indicator that I need, the EA stores or loads or (I really don’t know) multiple times my custom indicator

Here is a pic at the end of my visual backtest: https://pasteboard.co/GPdjyOQ.jpg
it doesn’t happen on demo trading, only on visual backtest

And here’s my function, I’ve used this on the OnTick function and it set a global variables to know if the price crosses up or down to the indicators lines (I’ve already try with local variables and buffers, same error):

//----------------------CheckChannel()-------------------------------
//
//-------------------------------------------------------------------
void CheckChannel(){
   double   bid_actual=NormalizeDouble(Bid,Digits),
            ask_actual=NormalizeDouble(Ask,Digits);
   HideTestIndicators(FALSE);
   nivel_anterior_up=iCustom(Symbol(),PERIOD_CURRENT,ruta_WT_TMA,"","----",periodosTMA,periodosATR,multiplicadorATR,repintarIndicador,1,1);
   
   //nivel_anterior_up=iCustom(Symbol(),PERIOD_CURRENT,"FL01","--",61,0,2.6,110,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,2,1);
   //nivel_anterior_down=iCustom(Symbol(),PERIOD_CURRENT,ruta_WT_TMA,"","----",periodosTMA,periodosATR,multiplicadorATR,repintarIndicador,2,1);
   //nivel_actual_up=iCustom(Symbol(),PERIOD_CURRENT,ruta_WT_TMA,"","----",periodosTMA,periodosATR,multiplicadorATR,repintarIndicador,1,0);
   //nivel_actual_down=iCustom(Symbol(),PERIOD_CURRENT,ruta_WT_TMA,"","----",periodosTMA,periodosATR,multiplicadorATR,repintarIndicador,2,0);
   //COMPRA
   if(bid_anterior!=0 && bid_anterior>=nivel_anterior_down && bid_actual<=nivel_actual_down){
      channel_down=TRUE;
      channel_up=FALSE;
   }
   //VENTA
   else if(ask_anterior!=0 && ask_anterior<=nivel_anterior_up && bid_actual>=nivel_actual_up){
      channel_up=TRUE;
      channel_down=FALSE;
   }
}

Do anyone know why this happen?

This usually happens if the parameters you pass to the iCustom() call are implicitly casted at runtime to the declared type.

Let’s say your indicator configuration looks like this:

extern string MA_Periods      = "38";
extern string MA_Timeframe    = "current";            // M1|M5|M15|... or "" for the current timeframe
extern string MA_Method       = "SMA* | TMA | LWMA | EMA | ALMA";
extern string MA_AppliedPrice = "Open | High | Low | Close* | Median | Typical | Weighted";
...

and your iCustom() call looks like this:

double value = iCustom(NULL, NULL, "Moving Average", 100, "M15", "SMA", "Close", ..., MODE_BUFFER1, 1);

Everything looks nice. The indicator works flawless standalone. It’s no problem to pass an integer for the periods instead of the declared string because the integer is casted to the proper string anyway. But wait…

When the integer is implicitly casted the runtime allocates a small piece of memory to hold the resulting string (here “100”) and passes a pointer to this memory to iCustom(). This happens on each call of iCustom() and here is the point. This piece of memory changes on every call (each time a new allocation), so the pointer passed to iCustom() changes on every call, too. To iCustom() it looks like you pass each time a different variable (indeed you do, even if it holds each time the same value: “100”). iCustom() checks on each call if the passed parameters changed. It calculates a hash and compares it with former calls. If one of the parameters regarded as input parameter changed, the hash changes and a new indicator instance is instantiated. This is to make multiple calls with different parameters sets as efficient as possible.

Imagine you use the same custom indicator with different period settings - let’s say to detect a cross-over - and call them alternating on every tick. How does the runtime know to instantiate exactly two versions and not more?

By looking at the pointers passed. So the solution is easy. Make sure to pass exactly the declared types to prevent any implicit casting.

Regards

ps: Another more simple explanation would be that one of your parameters indeed changes at each call because of a bug in your code. Add log statements to find out.

You should encapsulate your iCustom calls to make your code self-documenting.
Detailed explanation of iCustom - MQL4 and MetaTrader 4 - MQL4 programming forum

Hi alphatrading, thanks for your answer but, I’ve even try this:

iCustom("[DJI30]",30,"WT_TMA","","----",61,190,4.0,FALSE,1,1);

and same result, it creates multiple instances of the indicator, but if I use another indicator, for example:

iCustom("[DJI30]",30,"FL01","--",61,0,2.6,110,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,2,1);

it works fine, only one instance is created and ploted at the end of backtest, so I think is a problem with the WT_TMA indicator, I’m feeling really lost at this poin

Ok, Thanks! …