_AppliedTo passed to iCustom but not being set in indicator

 

I'm trying to create an indicator that uses my own custom indicators and so the master indicator needs to pass _AppliedTo to the slave indicators. In the documentation it says _AppliedTo should be passed as the last parameter after the all the indicators other parameters. What I'm finding is _AppliedTo  doesn't get set in the slave indicators, it's always set to 0 no matter what I pass in. The indicators construct correctly i.e and their handles are valid. I've tried it with both Oncalculate signatures but get exactly the same problem. 

Here is the minimal code to reproduce the issue. Any help would be very much appreciated. 

Master Indicator

//+------------------------------------------------------------------+
//|                master_ind.mq5                               |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 0

int OnInit()
  {
   ENUM_APPLIED_PRICE applied = PRICE_TYPICAL;
   Print("Master: calling iCustom with _AppliedTo = ", (int)applied);

   int handle = iCustom(_Symbol, PERIOD_CURRENT, "slave_ind",applied);
   if(handle == INVALID_HANDLE)
      Print("Master: Failed to create Slave handle!");
   else
      Print("Master: Slave handle created OK");

   return(INIT_SUCCEEDED);
  }

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[])
  {
   return(rates_total);
  }

Slave Indicator

//+------------------------------------------------------------------+
//|                slave_ind.mq5                                |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 0

int OnInit()
{
   Print("Slave: _AppliedTo = ", (int)_AppliedTo);
   return(INIT_SUCCEEDED);
}

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[])
  {
  

      return(rates_total);
  
  }
 
Your topic has been moved to the section: Technical Indicators
Please consider which section is most appropriate — https://www.mql5.com/en/forum/172166/page6#comment_49114893
 
  1. Your "master" indicator should use the first or reduced form of the OnCalculate() event handler, not the second more complex form.
    int  OnCalculate(
       const int        rates_total,       // price[] array size
       const int        prev_calculated,   // number of handled bars at the previous call
       const int        begin,             // index number in the price[] array meaningful data starts from
       const double&    price[]            // array of values for calculation
       );
  2. Your "slave" indicator should provide at least one buffer/plot for the values you want to feed the "master". If more than one buffer is generated by the "slave", then only the first will be used as the "price[]" in the "master".
Documentation on MQL5: Event Handling / OnCalculate
Documentation on MQL5: Event Handling / OnCalculate
  • www.mql5.com
The function is called in the indicators when the Calculate event occurs for processing price data changes. There are two function types. Only one...
 
Fernando Carreiro #:
  1. Your "master" indicator should use the first or reduced form of the OnCalculate() event handler, not the second more complex form.
  2. Your "slave" indicator should provide at least one buffer/plot for the values you want to feed the "master". If more than one buffer is generated by the "slave", then only the first will be used as the "price[]" in the "master".

Thanks Fernando ,


From what you've said, it seems my simplified example doesn't present my real use case well enough, I've over simplified it. 

What I wanted to do was create 2 indicators with iCustom within my master and within the oncalculate of the master, copy the data from each indicator and calculate a new indicator buffer. What I was trying to achieve by passing the _AppliedTo to each slave indicator was ensure they were using the same Applied Price as the master.

Do you think I'm going about aggregating two indicators data in the wrong way? I'm wondering if my understanding of the architecture is wrong and I'm going against the grain  with my method.


I could rewrite the slave indicators to use the longer OnCalculate signature and then set the Applied Price as an input parameter but I'm trying to avoid the ugly OnCalculate code that just seems like it should be unnecessary.

 
Richard Segrue #From what you've said, it seems my simplified example doesn't present my real use case well enough, I've over simplified it. 

Simplification for a forum question is a good thing, but it must at least reflect the real aspects of what you want to achieve. Otherwise, you will receive answers that may not fit your requirements.

Richard Segrue #Do you think I'm going about aggregating two indicators data in the wrong way? I'm wondering if my understanding of the architecture is wrong and I'm going against the grain  with my method.

It is currently unclear, because the information is insufficient.

Your intentions on what you want to achieve seems like it may be a XY Problem, where you have asked for a solution for issue "Y", but your real intention is solving issue "X".

Since we lack information we are unable to properly answer, neither for "X" nor "Y".

Richard Segrue #I could rewrite the slave indicators to use the longer OnCalculate signature and then set the Applied Price as an input parameter 

You are misunderstanding my explanation. The first or reduced form of the OnCalculate() is required for the "master", not the "slave". The "slave" can use any of the forms.

Richard Segrue #but I'm trying to avoid the ugly OnCalculate code that just seems like it should be unnecessary.

Ever consider not using the "master"/"slave" functionality at all?

Why not simply have the "master" do ALL of the calculations internally without need for a "slave"?

If you need the two separate indicators, then simply place the common logic or calculations in a ".mqh" file which can then be included for both indicators. That way an common code or logic is shared at compile time, but the final executable has no need for the other—hence no need for "master"/"slave".

However, since we lack information on your real issue and your intention, all we can do is speculate.

 
Fernando Carreiro #:

Simplification for a forum question is a good thing, but it must at least reflect the real aspects of what you want to achieve. Otherwise, you will receive answers that may not fit your requirements.

It is currently unclear, because the information is insufficient.

Your intentions on what you want to achieve seems like it may be a XY Problem, where you have asked for a solution for issue "Y", but your real intention is solving issue "X".

Since we lack information we are unable to properly answer, neither for "X" nor "Y".

You are misunderstanding my explanation. The first or reduced form of the OnCalculate() is required for the "master", not the "slave". The "slave" can use any of the forms.

Ever consider not using the "master"/"slave" functionality at all?

Why not simply have the "master" do ALL of the calculations internally without need for a "slave"?

If you need the two separate indicators, then simply place the common logic or calculations in a ".mqh" file which can then be included for both indicators. That way an common code or logic is shared at compile time, but the final executable has no need for the other—hence no need for "master"/"slave".

However, since we lack information on your real issue and your intention, all we can do is speculate.

Thanks for the feedback. I'll try to clarify what I'm trying to do.

The problem I'm trying to solve is to pass the Applied Price to the slave indicators in the last parameter of iCustom as the manual says you can . When I do ,  _AppliedTo in the slave indicators does not reflect that the value has been passed in. The example code I gave was to show exactly this problem. So this is the problem I think I need to solve if my understanding of the architecture is correct. All indications from the manual are that this should be possible. I'm pretty new to MQL5 so I don't know what I might be missing or misunderstanding. 

Separating the logic out into mqh files is a good option if I can't get the master slave thing working. If the master/slave idea is achievable and I'm just making a silly mistake that's scuppering my efforts then I'd like to know. 

Thanks

 
Richard Segrue #The problem I'm trying to solve is to pass the Applied Price to the slave indicators in the last parameter of iCustom as the manual says you can . 

That I have already explained in my post #2. So please adopt the instructions. Then if you are still unable to do that, show us a reviewed sample of your new attempt to receive advice.

However, this I suspect is your "Y" issue, not your "X" issue, but let's get the "Y" issue working at least, so that you can properly understand the mechanism.


Richard Segrue #Separating the logic out into mqh files is a good option if I can't get the master slave thing working. If the master/slave idea is achievable and I'm just making a silly mistake that's scuppering my efforts then I'd like to know. 

Please explain the reason why you need to have need for this "master"/"slave" method—in other words, please explain your "X" issue.

 

To help solve your issue, please provide actual code that compiles and executes, even if it is just a simple implementation.

That way we can see where you are actually going wrong.

EDIT: Remember to supply sample code for which you have already applied the instructions given in post #2.

 

After reading your initial post again, I think that you and I may be misunderstanding each other. So I am going to try re-explain things.

  1. I am assuming that a "slave" indicator, is one that simply produces a normal output, be it one or more buffers. Nothing special, and any ordinary indicator will do.
  2. I am assuming that a "master" indicator, is one that requires an "applied price" as input, which could simply be one of the default ones such Close, Median, Typical, etc.
  3. I am assuming that you want to feed the output of the "slave" as an input to the applied price of the "master" indicator.

Now, with that in mind, your initial post does not actually reflect that. In your code sample, your supposed "master" is trying to "inject" an applied price into an indicator that is supposedly the "slave" which was not designed for an applied price.

So, trying to clarify your issue, it seems that you first need to understand that there are two types of indicators:

  1. one that requires an applied price as an input.
  2. another that uses the full OHLC bar data as input.

These two types are defined by what format their OnCalculate() event handlers takes:

  1. int  OnCalculate(
       const int        rates_total,       // price[] array size
       const int        prev_calculated,   // number of handled bars at the previous call
       const int        begin,             // index number in the price[] array meaningful data starts from
       const double&    price[]            // array of values for calculation
       );
  2. int  OnCalculate(
       const int        rates_total,       // size of input time series
       const int        prev_calculated,   // number of handled bars at the previous call
       const datetime&  time[],            // Time array
       const double&    open[],            // Open array
       const double&    high[],            // High array
       const double&    low[],             // Low array
       const double&    close[],           // Close array
       const long&      tick_volume[],     // Tick Volume array
       const long&      volume[],          // Real Volume array
       const int&       spread[]           // Spread array
       );

Only the first format can take an applied price as an input.

Now, if you simply want to use standard applied price for the first format, then you don't need to any of this "master"/"slave" relationship. Just call the iCustom() function normally and define which price you want applied.

In essence, I may have misunderstood your question with your "master"/"slave" description.

Just use the first format of OnCalculate() in your indicator, and apply a price with your call to iCustom(), with the last parameter being the applied price.

Calling code:

ENUM_APPLIED_PRICE applied = PRICE_TYPICAL;
int handle = iCustom(_Symbol, PERIOD_CURRENT, "indi",applied);

Indicator code:

#property indicator_separate_window
#property indicator_buffers 1

int OnInit() {
   Print("Indi: _AppliedTo = ", (int)_AppliedTo);
   return INIT_SUCCEEDED;
}

int  OnCalculate(
   const int        rates_total,       // price[] array size
   const int        prev_calculated,   // number of handled bars at the previous call
   const int        begin,             // index number in the price[] array meaningful data starts from
   const double&    price[]            // array of values for calculation
   )  {

      // Do something
      return rates_total;
}

Hope that helps clarify a few things!

 
Fernando Carreiro #:

That I have already explained in my post #2. So please adopt the instructions. Then if you are still unable to do that, show us a reviewed sample of your new attempt to receive advice.

However, this I suspect is your "Y" issue, not your "X" issue, but let's get the "Y" issue working at least, so that you can properly understand the mechanism.


Please explain the reason why you need to have need for this "master"/"slave" method—in other words, please explain your "X" issue.

--Your  edit to post #8  happened while I was writing the response below----

I see  I may have confused the issue with a poorly worded explanation. Post 2 shows how I would get the Applied Prices but what I'm looking for is the ENUM_APPLIED_PRICE value. The method you've suggested would only allow me to get data from one indicator through the price[] array passed  via OnCalculate but not from the other indicator. So it would work for 1 indicator but not 2+.

With regards why I want to use this method rather than the alternative mqh approach. If it's possible I think it's cleaner and more flexible with regards publishing individual base indicators that don't have dependencies  as well as using them aggregated to create new indicators for algo trading research. 

 
Fernando Carreiro #:

After reading your initial post again, I think that you and I may be misunderstanding each other. So I am going to try re-explain things.

  1. I am assuming that a "slave" indicator, is one that simply produces a normal output, be it one or more buffers. Nothing special, and any ordinary indicator will do.
  2. I am assuming that a "master" indicator, is one that requires an "applied price" as input, which could simply be one of the default ones such Close, Median, Typical, etc.
  3. I am assuming that you want to feed the output of the "slave" as an input to the applied price of the "master" indicator.

Now, with that in mind, your initial post does not actually reflect that. In your code sample, your supposed "master" is trying to "inject" an applied price into an indicator that is supposedly the "slave" which was not designed for an applied price.

So, trying to clarify your issue, it seems that you first need to understand that there are two types of indicators:

  1. one that requires an applied price as an input.
  2. another that uses the full OHLC bar data as input.

These two types are defined by what format their OnCalculate() event handlers takes:

Only the first format can take an applied price as an input.

Now, if you simply want to use standard applied price for the first format, then you don't need to any of this "master"/"slave" relationship. Just call the iCustom() function normally and define which price you want applied.

In essence, I may have misunderstood your question with your "master"/"slave" description.

Just use the first format of OnCalculate() in your indicator, and apply a price with your call to iCustom(), with the last parameter being the applied price.

Calling code:

Indicator code:

Hope that helps clarify a few things!

Thanks,

I think it best that as you suggested I write a fuller version to better express what I'm trying to do. Possibly in so doing I'll bump into further issues and see that I'm taking a completely wrong approach.

Maybe a few days, unfortunately other work calls.

Appreciate you help so far.