Calling icustom with variable parameters

 

Hello everyone!

is it possible to call iCustom with different parameters that started as a string input?

I'll post some photos of what I mean.

This is where the user set the inputs of the indicator:


and this is how I am eliminating spaces and treating the input:

input string confirmationIndicatorName1="";
input string confirmationIndicatorInputs1="";


string confInputs1[];
int damiani;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
   string text=confirmationIndicatorInputs1;
   
   StringReplace(text," ","");

   ArraySetAsSeries(confInputs1,true);
   for(int i=0;i<StringLen(text);i++)
     {
      int comma = StringFind(text,",",i);
      if(StringSubstr(text,i,comma-i)!=",")
        {
         ArrayResize(confInputs1,ArraySize(confInputs1)+1,0);
         confInputs1[ArraySize(confInputs1)-1]=StringSubstr(text,i,comma-i);
        }
      if(comma==-1)break;
        
      i=comma;
     }
   ArrayPrint(confInputs1);
   damiani = iCustom(NULL,PERIOD_CURRENT,"Damiani_Volatmeter 2018",text);
//---
   return(INIT_SUCCEEDED);
  }

Okay...so I'm not using the array, but instead the text from where the array is built from.

I get an error that is the error 4002 (2019.05.01 19:56:44.319 2019.04.01 00:00:00   cannot load custom indicator 'Damiani_Volatmeter 2018' [4002]).

At first, I don't know if what I am doing is doable, but in case it is, what I'm doing wrong?


Thank you!

 
Pedro Severin:

I get an error that is the error 4002 (2019.05.01 19:56:44.319 2019.04.01 00:00:00   cannot load custom indicator 'Damiani_Volatmeter 2018' [4002]).

It's doable. Check your indicator name to make sure it's exactly the same as the file name.

 
Seng Joo Thio:

It's doable. Check your indicator name to make sure it's exactly the same as the file name.

Just checked. Its the same name :(.

 
Pedro Severin:

Just checked. Its the same name :(.

There's weird, because when I tested your code, I have these in an expert:

input string confirmationIndicatorName1="";
input string confirmationIndicatorInputs1="5, 2,4, 64,3";

string confInputs1[];
int damiani;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetTimer(60);
   
   string text=confirmationIndicatorInputs1;
   
   StringReplace(text," ","");

   ArraySetAsSeries(confInputs1,true);
   for(int i=0;i<StringLen(text);i++)
     {
      int comma = StringFind(text,",",i);
      if(StringSubstr(text,i,comma-i)!=",")
        {
         ArrayResize(confInputs1,ArraySize(confInputs1)+1,0);
         confInputs1[ArraySize(confInputs1)-1]=StringSubstr(text,i,comma-i);
        }
      if(comma==-1)break;
        
      i=comma;
     }
   ArrayPrint(confInputs1);
   damiani = iCustom(NULL,PERIOD_CURRENT,"Damiani_Volatmeter 2018",text);


  //---
   return(INIT_SUCCEEDED);
  }

and I created a dummy indicator named as Damiani_Volatmeter 2018:

//--- input parameters
input string   Input1;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   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[])
  {
//---
   Print ("Input1 = ", Input1);
//--- return value of prev_calculated for next call
   return(rates_total);
  }

I get:


First line printed by expert, the rest printed by the dummy indicator - proved that the method works.

So if yours can't work, and you're sure the name's correct, how about checking if your indicator can receive a string input in the first place?

 
Seng Joo Thio:

There's weird, because when I tested your code, I have these in an expert:

and I created a dummy indicator named as Damiani_Volatmeter 2018:

I get:


First line printed by expert, the rest printed by the dummy indicator - proved that the method works.

So if yours can't work, and you're sure the name's correct, how about checking if your indicator can receive a string input in the first place?

Well, thats a good question and might be the origin of the problem.

This is the code of the indicator, and I think it does not accept a string as input parameter. I was hoping that mt5 read the inputs just as a string.

//+------------------------------------------------------------------+
//|                                           Damiani_Volatmeter.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                                 https://mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com"
#property version   "1.00"
#property description "Damiani volatmeter oscillator"
#property indicator_separate_window
#property indicator_buffers 6
#property indicator_plots   2
//--- plot P
#property indicator_label1  "P"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot M
#property indicator_label2  "M"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- enums
enum ENUM_INPUT_YES_NO
  {
   INPUT_YES   =  1, // Yes
   INPUT_NO    =  0  // No
  };
//--- input parameters
input uint                 InpViscosity      =  13;             // ATR Viscosity
input uint                 InpAtrSedimentation= 40;            //ATR Sedimentation
input uint                 InpStdViscosity   =  20;            // STD Viscosity
input uint                 InpSedimentation  =  100;            // STD Sedimentation
input double               InpThreshold      =  1.4;           // Threshold
input ENUM_INPUT_YES_NO    InpLagSuppressor  =  INPUT_YES;     // Lag suppressor
input ENUM_APPLIED_PRICE   InpAppliedPrice   =  PRICE_CLOSE;   // Applied price
//--- indicator buffers
double         BufferP[];
double         BufferM[];
double         BufferATRV[];
double         BufferATRS[];
double         BufferDevV[];
double         BufferDevS[];
//--- global variables
double         threshold;
int            ATRviscosity;
int            STDviscosity;
int            ATRsedimentation;
int            STDsedimentation;
int            handle_atrv;
int            handle_atrs;
int            handle_devv;
int            handle_devs;
int            period_max;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- set global variables
   ATRviscosity=int(InpViscosity<1 ? 1 : InpViscosity);
   STDviscosity=int(InpStdViscosity<1 ? 1 : InpStdViscosity);
   ATRsedimentation=int(InpAtrSedimentation<2 ? 2 : InpAtrSedimentation);
   STDsedimentation=int(InpSedimentation<2 ? 2 : InpSedimentation);
   period_max=fmax(STDsedimentation,ATRsedimentation);
   threshold=InpThreshold;
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferP,INDICATOR_DATA);
   SetIndexBuffer(1,BufferM,INDICATOR_DATA);
   SetIndexBuffer(2,BufferATRV,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,BufferATRS,INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,BufferDevV,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,BufferDevS,INDICATOR_CALCULATIONS);
//--- setting indicator parameters
   IndicatorSetString(INDICATOR_SHORTNAME,"Damiani volatmeter ("+(string)ATRviscosity+","+(string)ATRsedimentation+","+DoubleToString(threshold,1)+")");
   IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--- setting plot buffer parameters
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);
//--- setting buffer arrays as timeseries
   ArraySetAsSeries(BufferP,true);
   ArraySetAsSeries(BufferM,true);
   ArraySetAsSeries(BufferATRV,true);
   ArraySetAsSeries(BufferATRS,true);
   ArraySetAsSeries(BufferDevV,true);
   ArraySetAsSeries(BufferDevS,true);
//--- create MA's handles
   ResetLastError();
   handle_atrv=iATR(NULL,PERIOD_CURRENT,ATRviscosity);
   if(handle_atrv==INVALID_HANDLE)
     {
      Print("The iATR(",(string)ATRviscosity,") object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
   handle_atrs=iATR(NULL,PERIOD_CURRENT,ATRsedimentation);
   if(handle_atrs==INVALID_HANDLE)
     {
      Print("The iATR(",(string)ATRsedimentation,") object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
   handle_devv=iStdDev(NULL,PERIOD_CURRENT,STDviscosity,0,MODE_LWMA,InpAppliedPrice);
   if(handle_devv==INVALID_HANDLE)
     {
      Print("The iStdDev(",(string)STDviscosity,") object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
   handle_devs=iStdDev(NULL,PERIOD_CURRENT,STDsedimentation,0,MODE_LWMA,InpAppliedPrice);
   if(handle_devs==INVALID_HANDLE)
     {
      Print("The iStdDev(",(string)STDsedimentation,") object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
//---
   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[])
  {
//--- Проверка и расчёт количества просчитываемых баров
   if(rates_total<fmax(period_max,4)) return 0;
//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-period_max-4;
      ArrayInitialize(BufferP,0);
      ArrayInitialize(BufferM,0);
      ArrayInitialize(BufferATRV,0);
      ArrayInitialize(BufferATRS,0);
      ArrayInitialize(BufferDevV,0);
      ArrayInitialize(BufferDevS,0);
     }
//--- Подготовка данных
   int count=(limit>1 ? rates_total : 1),copied=0;
   copied=CopyBuffer(handle_atrs,0,0,count,BufferATRS);
   if(copied!=count) return 0;
   copied=CopyBuffer(handle_atrv,0,0,count,BufferATRV);
   if(copied!=count) return 0;
   copied=CopyBuffer(handle_devs,0,0,count,BufferDevS);
   if(copied!=count) return 0;
   copied=CopyBuffer(handle_devv,0,0,count,BufferDevV);
   if(copied!=count) return 0;

//--- Расчёт индикатора
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      double ATR_V=BufferATRV[i];
      double ATR_S=BufferATRS[i];
      double StdDev_V=BufferDevV[i];
      double StdDev_S=BufferDevS[i];

      if(ATR_S!=0. && StdDev_S!=0.)
        {
         double s1=BufferP[i+1];
         double s3=BufferP[i+3];
         BufferP[i]=(InpLagSuppressor ? ATR_V/ATR_S+(s1-s3)/2.0 : ATR_V/ATR_S);
         BufferM[i]=threshold-StdDev_V/StdDev_S;
        }
     }

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

Well, thats a good question and might be the origin of the problem.

This is the code of the indicator, and I think it does not accept a string as input parameter. I was hoping that mt5 read the inputs just as a string.

No. mt5 reads according to the type that was declared within the indicator.

Reason: