EA creates multiple instances of an indicator using iCustom

 

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:


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):

void CheckChannel(){
   double   bid_actual=NormalizeDouble(Bid,Digits),
            ask_actual=NormalizeDouble(Ask,Digits);       
   nivel_anterior_up=iCustom(Symbol(),PERIOD_CURRENT,ruta_WT_TMA,"","----",periodosTMA,periodosATR,multiplicadorATR,repintarIndicador,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;
   }
}

I've even try iCustom using static hard coded values like this:

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

But same result, now, If I use another custom indicator:

nivel_anterior_up=iCustom(Symbol(),PERIOD_CURRENT,"FL01","--",61,0,2.6,110,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,2,1);

it works fine, only one instance created and plotted at the end of visual backtest, so I think is a problem with the WT_TMA indicator, I'm feeling really lost at this point :/

 

continuation from:  https://www.mql5.com/en/forum/217617


Please post your indicator input section. As I already told it indeed looks like you have a bug in your code or you pass wrong types. And follow the advice given by other members. Encapsulate your iCustom() calls.

 
alphatrading:

continuation from:  https://www.mql5.com/en/forum/217617


Please post your indicator input section. As I already told it indeed looks like you have a bug in your code or you pass wrong types. And follow the advice given by other members. Encapsulate your iCustom() calls.

Ok, thanks for the advice, here is the indicator's input:


now, encapsulating the iCustom() function:

Defined variables
Encapsulated iCustom() function
#define WT_TMA_NAME      "WT_TMA"
#define WT_TMA_NAME_created_by     ""
#define WT_TMA_NAME_separator_00   "--"
enum WT_TMA_buffers{LINE_MID,LINE_UP,LINE_DOWN};
string                  SymbName=_Symbol;
ENUM_TIMEFRAMES         tf=PERIOD_CURRENT;
int                     periodosTMA=61;
int                     periodosATR=190;
double                  multiplicadorATR=4.0;
bool                    repintarIndicador=FALSE;

double GetWT_TMA(int eBuf, int iBar = 0){ 
   return iCustom(SymbName, tf, 
                  WT_TMA_NAME, WT_TMA_NAME_created_by, 
                  WT_TMA_NAME_separator_00, periodosTMA, 
                  periodosATR, multiplicadorATR, 
                  repintarIndicador, eBuf, iBar); 
}

Now calling the required values:

line_up = GetWT_TMA(LINE_UP,0);
line_down  = GetWT_TMA(LINE_DOWN,0);

The returned values are ok, but same problem, WT_TMA indicator is added multiple times to the chart at the end of the visual backtest


 

Parameter "creadoPor" is declared as an integer but you pass a string. It's a mystery to me how you can have a string showing up there. Looks suspicious. Do you have the source code of it?

ps: Encapsulation means to pass the iCustom() parameters to the encapsulating or wrapping function. Your version still reads the parameters from the global scope.

 
alphatrading: ps: Encapsulation means to pass the iCustom() parameters to the encapsulating or wrapping function. Your version still reads the parameters from the global scope.

iCustom can't call a function. Encapsulation means a function to call the iCustom, with all appropriate values. Reading from global scope is fine if the data types are correct.

davidmesguerra: here is the indicator's input .. now, encapsulating the iCustom() function
  1. Your image shows the inputs as two strings, two ints, one double, and a bool. Your iCustom call has the same things. No problems. The two strings do not affect the indicator, so anything can be passed there.
  2. You defined an enumeration for the buffers, your function should use it, not int.
  3. Symbol, time frame and index are related. You can't change symbol or tf without changing a chart index to symbol/tf index. Either pass all three and require the caller to pass an adjusted index, or pass all three and have the function call iBarShift(SybName, tf, Time[iBar]).
Thus I would write
double GetWT_TMA(WT_TMA_buffers eBuf, int iBar = 0){                        // No sym/tf use global
   return GetWT_TMA(SymbName, tf, eBuf, iBar);
}
double GetWT_TMA(string sym, WT_TMA_buffers eBuf, int iBar = 0){           // No tf use global
   return GetWT_TMA(sym, PERIOD_CURRENT, eBuf, iBar);
}
double GetWT_TMA(ENUM_TIMEFRAMES per, WT_TMA_buffers eBuf, int iBar = 0){  // No sym use global
   return GetWT_TMA(_Symbol, per, eBuf, iBar);
}
double GetWT_TMA(string sym, ENUM_TIMEFRAMES per, WT_TMA_buffers eBuf, int iBar = 0){ // iBar is current chart
   if(per == PERIOD_CURRENT) per = ENUM_TIMEFRAMES(_PERIOD);
   if(per != _Period || sym != _Symbol){
      while(!download_history(sym, per) ){ Sleep(1000); RefreshRates(); }
      iBar = iBarShift(sym, per, Time[iBar]);
   }
   return iCustom(SymbName, tf, WT_TMA_NAME, 
                     "", "", 
                     periodosTMA, periodosATR, 
                     multiplicadorATR, 
                     repintarIndicador, 
                  eBuf, iBar); 
On MT4: Unless the current chart is the specific pair/TF referenced, you must handle 4066/4073 errors.
          Download history in MQL4 EA - MQL4 and MetaTrader 4 - MQL4 programming forum
 
alphatrading:

Parameter "creadoPor" is declared as an integer but you pass a string. It's a mystery to me how you can have a string showing up there. Looks suspicious. Do you have the source code of it?

ps: Encapsulation means to pass the iCustom() parameters to the encapsulating or wrapping function. Your version still reads the parameters from the global scope.

I didn't noticed that, I've changed the "creadoPor" value to 1 and now it works fine, thanks for the advice.
Reason: