In modern C++ and OOP practices, pointer and reference qualifiers are treated as an intrinsic part of the data type rather than the variable name. Aligning these symbols with the type reinforces this semantic distinction, improving conceptual clarity and consistency with modern conventions.
Introduce CSmoothingBase as an intermediate abstract base class between
CSubIndiBase and concrete smoothing sub-indicators (such as CSma).
Extract common traits shared across all smoothing algorithms:
- Declare pure virtual onCalculate() to standardize the calculation interface.
- Pull up the output indicator buffer (buffer[]) and its clearBuffersAt() hook.
- Generalize correctPeriod() with a configurable minPeriod parameter.
- Hardcode emptyValue to EMPTY_VALUE in the base class constructor.
Update CSma to inherit from CSmoothingBase and remove redundant members.
Add an overload for CSubIndiBase::prepareCalculation() that outputs whether
drawBegin is included in the calculation range via the isFullCalculation flag.
Adopt this overload in CSma::onCalculate(), allowing the redundant prepareRecurrenceSeed()
helper to be inlined and removed since the if (isFullCalculation) check makes seed
initialization transparent and self-documenting.
Using "rates_total - prev_calculated > 1" was insufficient for detecting
when the seed value at drawBegin needed to be computed by summation.
When calculating with minimal history (prev_calculated == barsRequired),
recalcStartIdx equals drawBegin. Because the difference is <= 1, summation
was skipped and the recurrence loop ran at index drawBegin, causing a fatal
'Array out of range' error when accessing source[drawBegin - period] (index -1).
Introduce prepareRecurrenceSeed() to calculate the seed via summation
whenever recalcStartIdx <= drawBegin, and start the recurrence from drawBegin + 1.
https://www.mql5.com/en/forum/510519#comment_60245675