When an indicator first loads, prev_calculated is 0 on the firs execution. On subsequent calls, prev_calculated holds the number of bars that were processed in the previous execution.
So when the indicator has has calculated more than one bar, prev_calculated – 1 can be accepted as the last processed bar and is an efficient starting point for future calculations if only the current bar in the indicator is necessary to be updated on each recalculation.
If the indicator must update X bars at a time like in the Fractals indicator (example 5 bars), then the starting index should be prev_calculated – 5.
When prev_calculated == 0 (first execution), the indicator needs to calculate the preliminary data.
In some custom indicators, you need enough historical data points to correctly calculate the buffers, this would be for example pivot indicators where the result is obtained based on a period of bars. This also applies to indicators that do not use CopyBuffer.
In thiskind of indicator, you could have a start index like this:
it start = (prev_calculated == 0) ? period_var : prev_calculated – 1;
or else
int start = (prev_calculated < period_var) ? period_var : prev_calculated – 1;
If you wanted to create bar confirmations, then you would alter the start index to support this:
int start = (prev_calculated == 0) ? period_var : prev_calculated - (bar_confirmations + 1);
( + 1 should be added to bar_confirmations to account for the fact that “bar_confirmations” can be 0 and prev_calculated – 1 is the last calculated bar)
Prev_calculated can theoretically be -1 (though usually 0) or greater than rates_total.
In some indicators iMA equivalent bars are copied with copybuffer and there is no strict minimum number of bars required. If prev_calculated < 0, restarting from 0 can be done to prevent errors with the plotting, but it should start the update from the last copied bar when prev_calculated is greater or equal to 0.
When copying bars in an indicator with copybuffer, it’s best not to copy all rates/bars because it can slow down the indicator, which will then also slow down an EA if the indicator is instantiated in the EA with iCustom.
To properly and safely copy bars, you need to ensure that prev_calculated is not less than 0 and not greater than rates_total. If it is, copy all bars temporarily, otherwise only copy new unprocessed bars. Then it does not need to recalculate everything on each execution.
if(prev_calculated > rates_total || prev_calculated < 0){ to_copy = rates_total; } else { to_copy = rates_total - prev_calculated; if(prev_calculated > 0) to_copy++; }
or
if(prev_calculated > rates_total || prev_calculated < 0) { to_copy = rates_total; } else { to_copy = rates_total - prev_calculated + 1; }
Finally call the CopyBuffer function to copy the data into your plot buffer:
if(CopyBuffer(handle, 0, 0, to_copy, buffer) < 0){ Print(“Errror encountered copying bars, please stand by.”); ChartRedraw(); }