diff --git a/Include/MyIncludes/HMA_Calculator.mqh b/Include/MyIncludes/HMA_Calculator.mqh index 12dda5c..e73ac48 100644 --- a/Include/MyIncludes/HMA_Calculator.mqh +++ b/Include/MyIncludes/HMA_Calculator.mqh @@ -1,6 +1,6 @@ //+------------------------------------------------------------------+ //| HMA_Calculator.mqh | -//| Calculation engine for Standard and Heikin Ashi HMA. | +//| VERSION 2.00: Optimized for incremental calculation. | //| Copyright 2025, xxxxxxxx | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" @@ -8,33 +8,36 @@ #include //+==================================================================+ -//| | //| CLASS 1: CHMACalculator (Base Class) | -//| | //+==================================================================+ class CHMACalculator { protected: int m_hma_period; + + //--- Persistent Buffers for Incremental Calculation double m_price[]; + double m_raw_hma[]; // Intermediate buffer for the 3rd WMA //--- Helper function for manual WMA calculation double CalculateWMA(int period, int index, const double &source_array[]); - //--- Virtual method for preparing the price series. - virtual bool PreparePriceSeries(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type); + //--- Updated: Accepts start_index + virtual bool PreparePriceSeries(int rates_total, int start_index, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[]); public: CHMACalculator(void) {}; virtual ~CHMACalculator(void) {}; - //--- Public methods bool Init(int period); - void Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type, double &hma_buffer[]); + int GetPeriod(void) const { return m_hma_period; } + + //--- Updated: Accepts prev_calculated + void Calculate(int rates_total, int prev_calculated, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[], double &hma_buffer[]); }; //+------------------------------------------------------------------+ -//| CHMACalculator: Initialization | +//| Init | //+------------------------------------------------------------------+ bool CHMACalculator::Init(int period) { @@ -43,40 +46,56 @@ bool CHMACalculator::Init(int period) } //+------------------------------------------------------------------+ -//| CHMACalculator: Main Calculation Method (Shared Logic) | +//| Main Calculation (Optimized) | //+------------------------------------------------------------------+ -void CHMACalculator::Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type, double &hma_buffer[]) +void CHMACalculator::Calculate(int rates_total, int prev_calculated, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[], double &hma_buffer[]) { int period_sqrt = (int)MathMax(1, MathRound(MathSqrt(m_hma_period))); int start_pos = m_hma_period + period_sqrt - 2; if(rates_total <= start_pos) return; - if(!PreparePriceSeries(rates_total, open, high, low, close, price_type)) - return; +//--- 1. Determine Start Index + int start_index; + if(prev_calculated == 0) + start_index = 0; + else + start_index = prev_calculated - 1; - double wma_half[], wma_full[], raw_hma[]; - ArrayResize(wma_half, rates_total); - ArrayResize(wma_full, rates_total); - ArrayResize(raw_hma, rates_total); - - int period_half = (int)MathMax(1, MathRound(m_hma_period / 2.0)); - - for(int i = m_hma_period - 1; i < rates_total; i++) +//--- 2. Resize Buffers + if(ArraySize(m_price) != rates_total) { - wma_half[i] = CalculateWMA(period_half, i, m_price); - wma_full[i] = CalculateWMA(m_hma_period, i, m_price); - raw_hma[i] = 2 * wma_half[i] - wma_full[i]; + ArrayResize(m_price, rates_total); + ArrayResize(m_raw_hma, rates_total); } - for(int i = start_pos; i < rates_total; i++) +//--- 3. Prepare Price (Optimized) + if(!PreparePriceSeries(rates_total, start_index, price_type, open, high, low, close)) + return; + +//--- 4. Calculate Intermediate WMAs (Incremental) + int period_half = (int)MathMax(1, MathRound(m_hma_period / 2.0)); + int loop_start_raw = MathMax(m_hma_period - 1, start_index); + + for(int i = loop_start_raw; i < rates_total; i++) { - hma_buffer[i] = CalculateWMA(period_sqrt, i, raw_hma); + double wma_half = CalculateWMA(period_half, i, m_price); + double wma_full = CalculateWMA(m_hma_period, i, m_price); + m_raw_hma[i] = 2 * wma_half - wma_full; + } + +//--- 5. Calculate Final HMA (Incremental) +// Uses m_raw_hma which is persistent + int loop_start_final = MathMax(start_pos, start_index); + + for(int i = loop_start_final; i < rates_total; i++) + { + hma_buffer[i] = CalculateWMA(period_sqrt, i, m_raw_hma); } } //+------------------------------------------------------------------+ -//| CHMACalculator: Helper for manual WMA calculation | +//| Helper for WMA | //+------------------------------------------------------------------+ double CHMACalculator::CalculateWMA(int period, int index, const double &source_array[]) { @@ -91,95 +110,107 @@ double CHMACalculator::CalculateWMA(int period, int index, const double &source_ } //+------------------------------------------------------------------+ -//| CHMACalculator: Prepares the standard source price series. | +//| Prepare Price (Standard - Optimized) | //+------------------------------------------------------------------+ -bool CHMACalculator::PreparePriceSeries(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type) +bool CHMACalculator::PreparePriceSeries(int rates_total, int start_index, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[]) { - ArrayResize(m_price, rates_total); - switch(price_type) +// Optimized copy loop + for(int i = start_index; i < rates_total; i++) { - case PRICE_OPEN: - ArrayCopy(m_price, open, 0, 0, rates_total); - break; - case PRICE_HIGH: - ArrayCopy(m_price, high, 0, 0, rates_total); - break; - case PRICE_LOW: - ArrayCopy(m_price, low, 0, 0, rates_total); - break; - case PRICE_MEDIAN: - for(int i=0; i