given an indicator handle, how do I get the non plotted region width at the begining?

 

Hello, I have a Bollinger Bands indicator on the chart. Also I have its handle.

Then I would like to get the number of candles before it starts to be plotted?

Please, check the image below:


I want to get the number of candles betwen the two yellow dots, I mean: 39.

I would like a clean and eficiently way, I mean NOT something like detect what kind of indicator is and then using multiple "ifs" read the properties and apply some logic based on the specific indicator.

I don't know if I could use the function:

int  PlotIndexGetInteger(
        int  plot_index,        // plotting index
        int  prop_id,           // property identifier
        int  prop_modifier      // property modifier
)

// with prop_id: PLOT_DRAW_BEGIN

but I need to specify the indicator handle somehow somewhere because the chart could have multiple indicators.

If possible I  would like to avoid something like "CopyBuffer(...)" because I did a trick with it and when trying to get the candle-width for multiple indicators it worked on MT5 terminal and Debugger but the Strategy Tester freezed up without a properly error message (totally crashed). Following more detailed explanation...

I need to get the above candle-width (let's call it: "num_candles_left_needed") inside an indicator. So I did the code below. It works ok when you debug it like that, or when you launch the indicator over the MT5 terminal with some indicators there (and after you remove the line: "InitializeThingsForDebug();" inside on "OnInit()" method). The problem is that if you use this indicator inside an Expert Advisor and test it on the Strategy Tester, then the ST crashes without any message. That's why I would like to avoid using CopyBuffer.

#property indicator_separate_window
#property indicator_buffers     1
#property indicator_plots               1
#property indicator_type1               DRAW_LINE
#property indicator_color1              clrRed
#property indicator_style1              STYLE_SOLID
#property indicator_width1              1

double buffer[];

int num_candles_left_needed = 0;

void get_chart_indicators_handle(int &handles[]) {
        ArrayResize(handles, 0);
        int total = (int)ChartGetInteger(0, CHART_WINDOWS_TOTAL);
        for(int w = 0; w < total; w++) {
                for(int i = 0; i < ChartIndicatorsTotal(0, w); i++) {
                        string name = ChartIndicatorName(0, w, i);
                        ArrayResize(handles, ArraySize(handles)+1);
                        handles[ArraySize(handles)-1] = ChartIndicatorGet(0, w, name);
                }
        }
}

int get_num_candles_left_needed() {
        int result = 0;
        double data[];
        ArraySetAsSeries(data, true);
        int handles[];
        get_chart_indicators_handle(handles);
        for (int i = 0; i < ArraySize(handles); i++) {
                ResetLastError();
                CopyBuffer(handles[i], 0, (datetime)0, TimeCurrent(), data);
                if (GetLastError() > 0)
                        printf("GetLastError(): %d, after 'CopyBuffer' for handle: %d", GetLastError(), handles[i]);
                int count_blank = 0;
                for (int j = ArraySize(data)-1; j >= 0; j--) {
                        if (data[j] == DBL_MAX)
                                count_blank++;
                        else
                                break;
                }
                ArrayFree(data);
                result = MathMax(result, count_blank);
        }
        return result;
}

int OnInit() {

        InitializeThingsForDebug();
        
        ArraySetAsSeries(buffer, true);
        SetIndexBuffer(0, buffer, INDICATOR_DATA);
        
        return 0;
}

bool flag_one_time = false;
int OnCalculate(const int rates_total,                  // number of bars in history at the current tick
                const int prev_calculated,      // number of bars calculated at previous call
                const int begin,
                const double &price[])
{

        if (!flag_one_time) {
                num_candles_left_needed = get_num_candles_left_needed();
                printf("num_candles_left_needed: %d", num_candles_left_needed);
                flag_one_time = true;
        }

        /* here the code to fill the indicator buffer, but now it doesn't matter */

        return rates_total;
}

void InitializeThingsForDebug() {

        ChartSetInteger(0, CHART_SCALE, 3);
        ChartSetInteger(0, CHART_MODE, CHART_CANDLES);

        MqlParam params_1[4];
        params_1[0].type = TYPE_INT;
        params_1[0].integer_value = 20;              // period
        params_1[1].type = TYPE_INT;
        params_1[1].integer_value = 0;               // shift
        params_1[2].type = TYPE_INT;
        params_1[2].integer_value = MODE_SMA;
        params_1[3].type = TYPE_INT;
        params_1[3].integer_value = PRICE_CLOSE;
        int handle_1 = IndicatorCreate(_Symbol, PERIOD_CURRENT, IND_MA, ArraySize(params_1), params_1);
        ChartIndicatorAdd(0, 0, handle_1);
        
        MqlParam params_2[4];
        params_2[0].type = TYPE_INT;
        params_2[0].integer_value = 56; // period
        params_2[1].type = TYPE_INT;
        params_2[1].integer_value = 0;       // shift
        params_2[2].type = TYPE_DOUBLE;
        params_2[2].double_value = 2.0;      // deviation
        params_2[3].type = TYPE_INT;
        params_2[3].integer_value = PRICE_CLOSE;
        int handle_2 = IndicatorCreate(_Symbol, PERIOD_CURRENT, IND_BANDS, ArraySize(params_2), params_2);
        ChartIndicatorAdd(0, 0, handle_2);

}

Any idea on how to get the "candle-with" of the non-plotted area on the begining of the chart?


Thank you, Cyberglassed.



 
Isn't suppose to be the Bollinger Band period minus 1 ?
 
Alain Verleyen:
Isn't suppose to be the Bollinger Band period minus 1 ?

Hi Alain, the image on the top was a simple example. Yes, if we look the code then we should get:

num_candles_left_needed: 55

The problem is that the code inside the indicator needs to figure out that value without my intervention.

I mean, there are some indicators attached to the chart and it needs to get the number of candle where all indicators start to be drawn at the same time (AND).

I need to get this number inside an indicator as you can see above.

Any idea?


Thanks, Cyberglassed!

 
cyberglassed:

Hi Alain, the image on the top was a simple example. Yes, if we look the code then we should get:

The problem is that the code inside the indicator needs to figure out that value without my intervention.

I mean, there are some indicators attached to the chart and it needs to get the number of candle where all indicators start to be drawn at the same time (AND).

I need to get this number inside an indicator as you can see above.

Any idea?


Thanks, Cyberglassed!

Ah ok. Honestly I didn't read closely all your post, I was thinking the question was about BBands only.

 
Alain Verleyen:

Ah ok. Honestly I didn't read closely all your post, I was thinking the question was about BBands only.

then?, any idea on how to achieve this? or I don't have any other option than iterate over all the indicators on the chart and use several "ifs" and analyze all the indicators separately to get the amount of bars without be plotted before them calculated based on their parameters and get the maximum of all values?. This option is not too good because I have to add an entry for every indicator I could use.

what do you think?


Thanks, Cyberglassed!

 
cyberglassed:

then?, any idea on how to achieve this? or I don't have any other option than iterate over all the indicators on the chart and use several "ifs" and analyze all the indicators separately to get the amount of bars without be plotted before them calculated based on their parameters and get the maximum of all values?. This option is not too good because I have to add an entry for every indicator I could use.

what do you think?


Thanks, Cyberglassed!

I think I don't see why you need that, and so I am not very motivated to search a solution.

Who cares about this number of candles ?

 
Alain Verleyen:

I think I don't see why you need that, and so I am not very motivated to search a solution.

Who cares about this number of candles ?

I only wanted to know if it was possible to get it with something like one line of code like reading some property value but I guess that's not possible, so the workaround is the way :P
 

just run a for loop over all bars.

    for(i=Bars-1;i>1;i--)
     {
      //Do Something... use i as bar shift number.
     }

so you can run the loop with one or more calculations over each bar.

I agree with Alain here and i will add the hint for you that indicator data is essentially useless unless,

you are targeting minimal or maximal averages taken from the entire available history to find what happens never, what happens usually or most of the time, and what happens always,

if you add for example, a 200 MA it needs a certain amount of bars to be able to calculate the average, this is why it starts late, but like i said, it's useless data,

realize that anything can happen at any time so it is meaningless data representing the past, not usable for decision making unless you focus on, extract,  and use the limits....

 
Marco vd Heijden:

just run a for loop over all bars.

for(i = Bars-1; i>1; i--) {
        // Do Something... use i as bar shift number.
}

so you can run the loop with one or more calculations over each bar.

I agree with Alain here and i will add the hint for you that indicator data is essentially useless unless,

you are targeting minimal or maximal averages taken from the entire available history to find what happens never, what happens usually or most of the time, and what happens always,

if you add for example, a 200 MA it needs a certain amount of bars to be able to calculate the average, this is why it starts late, but like i said, it's useless data,

realize that anything can happen at any time so it is meaningless data representing the past, not usable for decision making unless you focus on, extract,  and use the limits....

Thank you Marco.

Do you know if is there some way that, given an indicator handle, get the number of bars plotted by that indicator?

I have tried with the following function but it returns the same number as: "Bars()", so it is not useful for my goal.

int ind_bars_calculated = BarsCalculated(indicator_handle);

for me would be useful get only the amount of bars plotted by the indicator.


Thank you!

 

it does not plot any bars, at least it depends on the indicator you are using normally it draws a line or histogram, or objects.

like i said if you load a 200 MA then it will simply take the last 200 bars and calculate them into one average, and it plots the averaged point on bar 201,

then shifts one bar and again calculates the average and plots another point on bar 202, and so on and by connecting the dots, it creates the line that represents the moving average,

as an overlay on the chart.

if you wanted to know the total amount of processed bars then you drop a counter++ in somewhere, so it will add one to total every time it processes a bar.

then you can Comment this number on the chart or use it where needed.

as usual, i have no clue as to what it is you are trying to do.

 
Marco vd Heijden:

it does not plot any bars, at least it depends on the indicator you are using normally it draws a line or histogram, or objects.

like i said if you load a 200 MA then it will simply take the last 200 bars and calculate them into one average, and it plots the averaged point on bar 201,

then shifts one bar and again calculates the average and plots another point on bar 202, and so on and by connecting the dots, it creates the line that represents the moving average,

as an overlay on the chart.

if you wanted to know the total amount of processed bars then you drop a counter++ in somewhere, so it will add one to total every time it processes a bar.

then you can Comment this number on the chart or use it where needed.

as usual, i have no clue as to what it is you are trying to do.

thank you Marco :)
Reason: