Custom Indicator Applied Price or Indicator Handle

 

When creating a custom indicator of the form:  

int OnCalculate(const int rates_total, 
	        const int prev_calculated, 
	        const int begin,
	        const double &price[]);

Is there a function or pre-defined variable available to access the Price Series or the Indicator Handle the custom indicator was applied to? Something that could be used to pass to other indicators used for intermediate calculations

int OnInit()
  {
   int applied_price_or_handle = ????; 
   
   h_1 = iMA(Symbol(), Period(), 20, 0, MODE_SMA, applied_price_or_handle);
   h_2 = iMA(Symbol(), Period(), 40, 0, MODE_SMA, applied_price_or_handle);

   return(0);
  }

Thanks,
Jay 

Edit: spelling 

 
MQL5 for Newbies: Guide to Using Technical Indicators in Expert Advisors
  • 2010.03.18
  • Sergey Pavlov
  • www.mql5.com
In order to obtain values of a built-in or custom indicator in an Expert Advisor, first its handle should be created using the corresponding function. Examples in the article show how to use this or that technical indicator while creating your own programs. The article describes indicators that are built n the MQL5 language. It is intended for those who don't have much experience in the development of trading strategies and offers simple and clear ways of working with indicators using the offered library of functions.
 

Thank you. Appreciate your effort in trying to be helpful, but that totally doesn't answer the question.  I wasn't asking how to use the standard indicator functions.

I'm not sure if you're aware, but many of the standard indicator functions (iMA, iMACD, etc.) accept an indicator handle to apply that indicator to another indicator's data.  It works with iCustom as well if the indicator's OnCalculate is of the first-form as above, just pass the handle or price series as the last parameter after all input parameters are supplied.

int OnInit()
  {
   h_1 = iMA(Symbol(), Period(), 20, 0, MODE_SMA, PRICE_CLOSE);
   h_2 = iMA(Symbol(), Period(), 40, 0, MODE_SMA, h_1);
   h_3 = iCustom(Symbol(), Period(), "SomeCustomIndicator",1,2,3,h_2);

   return(0);
  }

However, what I need is to apply my custom indicator on another indicator (already possible, both dropping on a chart and with iCustom function) and want to use other already existing indicators to calculate some of the intermediate values needed, but need those calculations need to be based on the same base series of data, not a hard-coded price series (PRICE_CLOSE, for example) or by passing the price series as an input parameter. It would be "workable" for usage with iCustom (passing the handle/price series twice as both the input parameter and as the last parameter to the iCustom function), but will not work when the indicator is dropped on a chart with previous indicator to be applied to since can't pass the handle as the input parameter. 

     Indicator A or Price Series applied to (PRICE_CLOSE, PRICE_TYPICAL, etc.)
          |
     Indicator B - My Custom Indicator
      /       \ 
Indicator C  Indicator D  - indicators used for intermediate calculations in Indicator B 

It's possible I can work around this if the ultimate answer is "There is no function or pre-defined variable to access the price series or indicator handle custom indicator is applied to", but i then have to duplicate the calculation logic of those already built indicators (iMA was just an example) in this custom indicator I'm building (not what I want, and won't work if I don't have access to the logic of the specific indicators in question).

I suspect that is the answer, since I couldn't find anything, and thus the reason for the post in the first place.  If that's so, I would also like to suggest to MetaQuotes that it be considered for a possible feature to make this available for a future update/version.

Thanks,
Jay 

 

Hello Jay,

 have you learned how to properly input a handle into another indicator? I am living this struggle right now.

Thanks,

Thiago

 
Thiago:

have you learned how to properly input a handle into another indicator? I am living this struggle right now.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Последовательность выполнение Init() и DeInit()

fxsaber, 2017.04.17 09:03

int GetShortNames( string &ShortNames[], const long Chart_ID = 0, const int SubWindow = 0 )
{    
  const int Total = ChartIndicatorsTotal(Chart_ID, SubWindow);

  ArrayResize(ShortNames, Total);
  
  for (int i = 0; i < Total; i++)
    ShortNames[i] = ChartIndicatorName(Chart_ID, SubWindow, i);
    
  return(Total);

}

// Возвращает свое "Короткое имя" - ShortName
string GetMyShortName( void )
{  
  string Res = "";
  
  const int SubWindow = ChartWindowFind();
  
  string ShortNames[];

  GetShortNames(ShortNames, 0, SubWindow);
  
  const string TmpShortName = __FUNCSIG__ + (string)MathRand();

  IndicatorSetString(INDICATOR_SHORTNAME, TmpShortName);    

  string NewShortNames[];

  const int Total = GetShortNames(NewShortNames, 0, SubWindow);
  
  for (int i = 0; i < Total; i++)
    if (NewShortNames[i] == TmpShortName)
    {
      Res = ShortNames[i];
      
      IndicatorSetString(INDICATOR_SHORTNAME, Res);
      
      break;
    }
  
  return(Res);
}

// Возвращает свой хэндл
int GetMyHandle( void )
{
  const string ShortName = GetMyShortName();
  
  const string TmpShortName = __FUNCSIG__ + (string)MathRand();  
  
  IndicatorSetString(INDICATOR_SHORTNAME, TmpShortName);

  const int Res = ChartIndicatorGet(0, ChartWindowFind(), TmpShortName);
  
  IndicatorSetString(INDICATOR_SHORTNAME, ShortName);  

  return(Res);
}

Очень важно ДО OnDeinit сделать IndicatorRelease своего хэндла.

Интересно, что после каждого такого IndicatorRelease хэндл индикатора увеличивается на единицу.

 
Thiago:

Hello Jay,

 have you learned how to properly input a handle into another indicator? I am living this struggle right now.

Thanks,

Thiago


Got it in this way:


// MOVING AVERAGE OF MOVING AVERAGE

// Plot settings
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2

#property indicator_label1  "Price MA"
   #property indicator_type1   DRAW_LINE
   #property indicator_color1  clrBlue
   #property indicator_style1  STYLE_SOLID
   #property indicator_width1  1;
#property indicator_label2  "MA of MA"
   #property indicator_type2   DRAW_LINE
   #property indicator_color2  clrOrange
   #property indicator_style2  STYLE_DASH
   #property indicator_width2  1


// Inputs
input int                  PMA_period=14; // price MA period
input ENUM_MA_METHOD       PMA_method=MODE_SMA; // type of smoothing
input ENUM_APPLIED_PRICE   PMA_applied_price=PRICE_CLOSE;    // type of price
input int                  MAoMA_period=6; // MA of MA period
input ENUM_MA_METHOD       MAoMA_method=MODE_SMA; // type of smoothing


// Global
double PMA_buffer[], MAoMA_buffer[]; // buffers
int    PMA_handle, MAoMA_handle; //handles
string short_name; // nome do indicador impresso no gráfico
int    bars_calculated=0; // manteremos o número de valores no indicador Volumes


// Initialization
int OnInit()
  {
   SetIndexBuffer(0,PMA_buffer,INDICATOR_DATA); // link buffer to array
   SetIndexBuffer(1,MAoMA_buffer,INDICATOR_DATA); // link buffer to array

   PMA_handle=iMA(_Symbol,_Period,PMA_period,0,PMA_method,PMA_applied_price);
   if(PMA_handle==INVALID_HANDLE) // if handle fails
     {
      PrintFormat("Error: %d", GetLastError());
      return(INIT_FAILED);
     }
     
   MAoMA_handle=iMA(_Symbol,_Period,MAoMA_period,0,MAoMA_method,PMA_handle); // inputing a handle into another indicator
   if(PMA_handle==INVALID_HANDLE) // if handle fails
     {
      PrintFormat("Error: %d", GetLastError());
      return(INIT_FAILED);
     }

   short_name=StringFormat("PMA(%d), MAoMA(%d) - %s,%s)",
                           PMA_period, MAoMA_period,
                           _Symbol,EnumToString(_Period));
   IndicatorSetString(INDICATOR_SHORTNAME,short_name); // print indicator name on chart
   IndicatorSetInteger(INDICATOR_DIGITS, 5); // set indicator digits
   
   PrintFormat("%s - Idicator started - %s",
                            TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
                            short_name); // log de sucesso
   
   return(INIT_SUCCEEDED); // inicialização normal do indicador  
  }


// Iteraction
int OnCalculate(const int rates_total, // número de barras disponíveis no gráfico (JANELA CORRENTE)
                const int prev_calculated, // barras tratadas na chamada anterior
                const datetime &time[], // hora de abertura (se M5, de 5 em 5 min - se M15, de 15 em 15 min)
                const double &open[], // open (abertura)
                const double &high[], // high (máximo)
                const double &low[], // low (mínimo)
                const double &close[], // close (fechamento)
                const long &tick_volume[], // volume de Tick
                const long &volume[], // volume real
                const int &spread[]) // spread
  {
   int values_to_copy; 
   int calculated=BarsCalculated(PMA_handle);
   string comm; // string for log msg
   
   if(calculated<=0)
     {
      PrintFormat("Error: %d",calculated,GetLastError()); // log
      return(0);
     }

   if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1) // Values to be copied to buffer
     {
      if(calculated>rates_total) values_to_copy=rates_total;
      else                       values_to_copy=calculated;
     }
   else
     {
      values_to_copy=(rates_total-prev_calculated)+1;
     }

   // Filling buffer arrays
   if(!FillArrayFromBuffer(PMA_buffer,PMA_handle,MAoMA_buffer, MAoMA_handle, values_to_copy)) return(0);
   
   bars_calculated=calculated; // memoriza o número de valores no indicador

   return(rates_total); // retorna o valor prev_calculated para a próxima chamada
  }
  
 
// Function for filling buffer arrays
bool FillArrayFromBuffer(double &values1[],
                         int handle1,
                         double &values2[],
                         int handle2,
                         int amount // number of copied values
                         )
  {
   ResetLastError();

   if(CopyBuffer(handle1,0,0,amount,values1)<0) //  fill a part of the PMAbuffer array with values from the indicator buffer
     {
      PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
      return(false);
     }

   if(CopyBuffer(handle2,0,0,amount,values2)<0) //  fill a part of the PMAbuffer array with values from the indicator buffer
     {
      PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
      return(false);
     }

   return(true); // everything is fine
  }
 

// Closing indicator
void OnDeinit(const int reason)
  {
   IndicatorRelease(PMA_handle);
   IndicatorRelease(MAoMA_handle);

   Comment("");
  }