_AppliedTo Return 0 When Calling iCustom

 

Hi, I'm testing some features, and am stuck trying to use data from another indicator using iCustom() 

The goal is that I want to pass applied price or an indicator handle to iCustom, but in that Indicator it always returns value = 0.  My TestMA indicator works without any problem

Specifically here, I create 2 MA handles to calculate MACD with 3 cases:

// Case 1: Test without Applied price input, failed
  if(inpCaseTest == 1) {
    Print("Case 1: Test without Applied price input");
    handleMAFast = iCustom(_Symbol, _Period, TESTMA, inpMAFastPeriod);
    handleMASlow = iCustom(_Symbol, _Period, TESTMA, inpMASlowPeriod);
  }

  // Case 2: Test with Applied price input
  else if(inpCaseTest == 2) {
    Print("Case 2: Test with Applied price input");
    handleMAFast = iCustom(_Symbol, _Period, TESTMA, inpMAFastPeriod, inpPriceFast);
    handleMASlow = iCustom(_Symbol, _Period, TESTMA, inpMASlowPeriod, inpPriceSlow);
  }

// Case 3: Test with previous handle
  else {
    Print("Case 3: Test with previous handle");
    handleMAFast = iCustom(_Symbol, _Period, TESTMA, inpMAFastPeriod, inpPriceFast);
    handleMASlow = iCustom(_Symbol, _Period, TESTMA, inpMASlowPeriod, handleMAFast);
  }


1. After nearly a dozen times of reloading the indicator, I see that case 2 sometimes works, sometimes not, why?

2. Why doesn't handleMASlow use the value of handleMAFast, and _LastError has a value of 0? How can I use the data from the previous handle in this case?

3. When not passing the Applied price parameter (case 1), why doesn't it call the default value?

Files:
TestMA.mq5  5 kb
TestMACD.mq5  6 kb
 

I will publish the code here for those who do not want to download the file

My Test MACD code

//+------------------------------------------------------------------+
//| Import, Include & Define                                         |
//+------------------------------------------------------------------+
//--- Import & Include
#define indexMACDVal    0
#define indexMACDColor  1
#define indexMAFast     2
#define indexMASlow     3
#define TESTMA          "\\Indicators\\TestMA.ex5"
// #resource TESTMA         
//+------------------------------------------------------------------+
#property copyright   "Copyright © "
#property version     "1.00"
#property strict
//+------------------------------------------------------------------+
#property indicator_separate_window

#property indicator_buffers 4
#property indicator_plots   1

#property indicator_color1  C'49,242,49', C'242,49,49'

//+------------------------------------------------------------------+
//| Inputs and variables                                             |
//+------------------------------------------------------------------+
input int                 inpMAFastPeriod   = 12;               // Fast MA Period
input int                 inpMASlowPeriod   = 26;               // Slow MA Period
input int                 inpCaseTest       = 1;

double bufferMACDValue[];
double bufferMACDColors[];
double bufferMAFast[];
double bufferMASlow[];

// Handles
int handleMAFast;
int handleMASlow;
ENUM_APPLIED_PRICE  inpPriceFast = PRICE_CLOSE;
ENUM_APPLIED_PRICE  inpPriceSlow = PRICE_CLOSE;
// Others
int longestPeriod;
string indicatorShortName;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
  IndicatorInit();
  longestPeriod = MathMax(inpMAFastPeriod, inpMASlowPeriod);

  if(handleMAFast == INVALID_HANDLE) return INIT_FAILED;
  if(handleMASlow == INVALID_HANDLE) return INIT_FAILED;

  // Check result
  return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+

int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) {
  ArraySetAsSeries(price, true);
  int limit = rates_total - prev_calculated;
  if(prev_calculated < 1) {
    limit   = rates_total - longestPeriod;
  } 
  else if(limit == 0) ++limit;
  if(CopyBuffer(handleMAFast, 0, 0, limit, bufferMAFast) < 1 ||
     CopyBuffer(handleMASlow, 0, 0, limit, bufferMASlow) < 1) return prev_calculated;

  for(int bar = (limit)-1; bar > -1 && !IsStopped(); --bar) {
    bufferMACDValue[bar] = bufferMAFast[bar] - bufferMASlow[bar];
    if(bufferMACDValue[bar] < 0) bufferMACDColors[bar] = 0;
    else                         bufferMACDColors[bar] = 1;
  }

  return(rates_total);
}

//+------------------------------------------------------------------+
void IndicatorInit() {
  indicatorShortName = StringFormat("MACD(%d, %d)", inpMAFastPeriod, inpMASlowPeriod);
  IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
  
  PlotIndexSetString(indexMACDVal, PLOT_LABEL, "MACD");
  PlotIndexSetInteger(indexMACDVal, PLOT_DRAW_TYPE, DRAW_COLOR_HISTOGRAM);
  PlotIndexSetInteger(indexMACDVal, PLOT_LINE_STYLE, STYLE_SOLID);
  PlotIndexSetInteger(indexMACDVal, PLOT_LINE_WIDTH, 2);

  PlotIndexSetInteger(indexMACDVal, PLOT_DRAW_BEGIN, longestPeriod);
  SetIndexBuffer(indexMACDVal, bufferMACDValue, INDICATOR_DATA);

  SetIndexBuffer(indexMAFast, bufferMACDValue, INDICATOR_CALCULATIONS);
  SetIndexBuffer(indexMASlow, bufferMACDValue, INDICATOR_CALCULATIONS);
  SetIndexBuffer(indexMACDColor, bufferMACDColors, INDICATOR_COLOR_INDEX);

// Case 1: Test without Applied price input
  if(inpCaseTest == 1) {
    Print("Case 1: Test without Applied price input");
    handleMAFast = iCustom(_Symbol, _Period, TESTMA, inpMAFastPeriod);
    handleMASlow = iCustom(_Symbol, _Period, TESTMA, inpMASlowPeriod);
  }

  // Case 2: Test with Applied price input
  else if(inpCaseTest == 2) {
    Print("Case 2: Test with Applied price input");
    handleMAFast = iCustom(_Symbol, _Period, TESTMA, inpMAFastPeriod, inpPriceFast);
    handleMASlow = iCustom(_Symbol, _Period, TESTMA, inpMASlowPeriod, inpPriceSlow);
  }

// Case 3: Test with previous handle
  else {
    Print("Case 3: Test with previous handle");
    handleMAFast = iCustom(_Symbol, _Period, TESTMA, inpMAFastPeriod, inpPriceFast);
    handleMASlow = iCustom(_Symbol, _Period, TESTMA, inpMASlowPeriod, handleMAFast);
  }

  ArraySetAsSeries(bufferMACDValue, true); 
  ArraySetAsSeries(bufferMACDColors, true); 
  ArraySetAsSeries(bufferMASlow, true); 
  ArraySetAsSeries(bufferMAFast, true); 
}

//+==================================================================+


TestMA:

//+------------------------------------------------------------------+
//| Import, Include & Define                                         |
//+------------------------------------------------------------------+
//--- Import & Include
#define indexBufferEMA         0

//+------------------------------------------------------------------+
#property copyright   "Copyright © "
#property version     "1.00"
#property strict
//+------------------------------------------------------------------+
#property indicator_chart_window

#property indicator_buffers 1

#property indicator_plots   1

#property indicator_type1   DRAW_LINE
#property indicator_color1  clrWhite
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1


//+------------------------------------------------------------------+
//| Inputs and variables                                             |
//+------------------------------------------------------------------+
input int                 inpCallBack       = 26;               // Call Back Periods

double bufferEMA[];
string indicatorShortName;
double weight = 2 / (inpCallBack + 1.0);

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
  IndicatorInit();
  Print("_LastError: ", _LastError);
  Print("inpCallBack: ", inpCallBack, ", _AppliedTo: ", getIndicatorDataDescription(_AppliedTo));
  // Check result
  return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) {
  ArraySetAsSeries(price, true);
  int limit          = rates_total - prev_calculated;
  if(prev_calculated < 1) {
    limit            = rates_total - inpCallBack;
    bufferEMA[limit] = price[limit];
  } else if(limit == 0) ++limit;

  for(int bar = limit-1; bar > -1 && !IsStopped(); --bar) {
    bufferEMA[bar] = (weight * (price[bar] - bufferEMA[bar+1])) + bufferEMA[bar+1];
  }

  return(rates_total);
}

//+------------------------------------------------------------------+
void IndicatorInit() {
  indicatorShortName = StringFormat("EMA(%d)", inpCallBack);
  IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);

  SetIndexBuffer(indexBufferEMA, bufferEMA, INDICATOR_DATA);
  ArraySetAsSeries(bufferEMA, true);
  ArrayInitialize(bufferEMA, 0);
  PlotIndexSetDouble(indexBufferEMA, PLOT_EMPTY_VALUE, 0);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string getIndicatorDataDescription(int data_id) {
  string descr="";
  switch(data_id) {
  case(0):
    descr="It's first type of OnCalculate() - no data buffer";
    break;
  case(1):
    descr="Indicator calculates on Close price";
    break;
  case(2):
    descr="Indicator calculates on Open price";
    break;
  case(3):
    descr="Indicator calculates on High price";
    break;
  case(4):
    descr="Indicator calculates on Low price";
    break;
  case(5):
    descr="Indicator calculates on Median Price (HL/2)";
    break;
  case(6):
    descr="Indicator calculates on Typical Price (HLC/3)";
    break;
  case(7):
    descr="Indicator calculates on Weighted Price (HLCC/4)";
    break;
  case(8):
    descr="Indicator calculates Previous Indicator's data";
    break;
  case(9):
    descr="Indicator calculates on First Indicator's data";
    break;
  default:
    descr="Indicator calculates on data of indicator with handle="+string(data_id);
    break;
  }
//---
  return descr;
}
//+==================================================================+
//+------------------------------------------------------------------+
 

Does anyone have the answers to the above questions? 

 
still no answer, this may be a bug of MQL5, I will report to the development team about this issue when I have time
 
Honestly I did not go through all data you provided above. But a good solution is to merge the indicators' codes in the final indicator instead of applying iCustom which is prone to load issues.