diff --git a/Include/MyIncludes/MACD_Laguerre_Histogram_Calculator.mqh b/Include/MyIncludes/MACD_Laguerre_Histogram_Calculator.mqh index 0bc3c86..138d8f6 100644 --- a/Include/MyIncludes/MACD_Laguerre_Histogram_Calculator.mqh +++ b/Include/MyIncludes/MACD_Laguerre_Histogram_Calculator.mqh @@ -1,6 +1,6 @@ //+------------------------------------------------------------------+ //| MACD_Laguerre_Histogram_Calculator.mqh | -//| VERSION 1.20: Optimized for incremental calculation. | +//| VERSION 2.00: Optimized for incremental calculation. | //| Copyright 2025, xxxxxxxx | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" @@ -15,7 +15,10 @@ enum ENUM_SMOOTHING_METHOD_LAGUERRE SMOOTH_SMA, SMOOTH_EMA, SMOOTH_SMMA, - SMOOTH_LWMA + SMOOTH_LWMA, + SMOOTH_TMA, + SMOOTH_DEMA, + SMOOTH_TEMA }; //+==================================================================+ @@ -30,10 +33,16 @@ protected: CLaguerreEngine *m_fast_engine; CLaguerreEngine *m_slow_engine; - //--- Engines for Signal Line (Optimization) + //--- Engines for Signal Line CLaguerreEngine *m_signal_laguerre_engine; CMovingAverageCalculator *m_signal_ma_engine; + //--- Persistent Buffers + double m_fast_filter[]; + double m_slow_filter[]; + double m_macd_line[]; + double m_signal_line[]; + virtual CLaguerreEngine *CreateEngineInstance(void); public: @@ -115,12 +124,14 @@ bool CMACDLaguerreHistogramCalculator::Init(double g1, double g2, double sig_g, if(m_signal_ma_type == SMOOTH_Laguerre) { m_signal_laguerre_engine = new CLaguerreEngine(); + // Signal engine works on MACD line (price-like), so SOURCE_PRICE is appropriate if(!m_signal_laguerre_engine.Init(m_signal_gamma, SOURCE_PRICE)) return false; } else { m_signal_ma_engine = new CMovingAverageCalculator(); + // Map custom enum to engine enum (offset by 1 because Laguerre is 0) ENUM_MA_TYPE ma_type = (ENUM_MA_TYPE)(m_signal_ma_type - 1); if(!m_signal_ma_engine.Init(m_signal_period, ma_type)) return false; @@ -138,43 +149,47 @@ void CMACDLaguerreHistogramCalculator::Calculate(int rates_total, int prev_calcu if(rates_total < 2) return; -//--- 1. Calculate Fast and Slow Laguerre Filters (Incremental) - double fast_filter[], slow_filter[]; -// Note: The engine resizes them. +// Resize internal buffers + if(ArraySize(m_fast_filter) != rates_total) + { + ArrayResize(m_fast_filter, rates_total); + ArrayResize(m_slow_filter, rates_total); + ArrayResize(m_macd_line, rates_total); + ArrayResize(m_signal_line, rates_total); + } - m_fast_engine.CalculateFilter(rates_total, prev_calculated, price_type, open, high, low, close, fast_filter); - m_slow_engine.CalculateFilter(rates_total, prev_calculated, price_type, open, high, low, close, slow_filter); +//--- 1. Calculate Fast and Slow Laguerre Filters (Incremental) +// The engine handles resizing and incremental logic internally + m_fast_engine.CalculateFilter(rates_total, prev_calculated, price_type, open, high, low, close, m_fast_filter); + m_slow_engine.CalculateFilter(rates_total, prev_calculated, price_type, open, high, low, close, m_slow_filter); //--- 2. Calculate MACD Line - double macd_line[]; - ArrayResize(macd_line, rates_total); - int start_index = (prev_calculated > 0) ? prev_calculated - 1 : 0; for(int i = start_index; i < rates_total; i++) - macd_line[i] = fast_filter[i] - slow_filter[i]; + m_macd_line[i] = m_fast_filter[i] - m_slow_filter[i]; //--- 3. Calculate Signal Line - double signal_line[]; - ArrayResize(signal_line, rates_total); +// Offset: Laguerre filter warms up quickly, but let's say 2 bars to be safe + int macd_offset = 2; if(m_signal_ma_type == SMOOTH_Laguerre) { // Use Laguerre Engine on the MACD Line + // We pass m_macd_line as 'close' price. Other prices are dummy. m_signal_laguerre_engine.CalculateFilter(rates_total, prev_calculated, PRICE_CLOSE, - macd_line, macd_line, macd_line, macd_line, - signal_line); + m_macd_line, m_macd_line, m_macd_line, m_macd_line, + m_signal_line); } else { // Use MA Engine on the MACD Line - m_signal_ma_engine.Calculate(rates_total, prev_calculated, PRICE_CLOSE, - macd_line, macd_line, macd_line, macd_line, - signal_line); + m_signal_ma_engine.CalculateOnArray(rates_total, prev_calculated, m_macd_line, m_signal_line, macd_offset); } //--- 4. Calculate Histogram for(int i = start_index; i < rates_total; i++) - histogram[i] = macd_line[i] - signal_line[i]; + histogram[i] = m_macd_line[i] - m_signal_line[i]; } //+------------------------------------------------------------------+ +//+------------------------------------------------------------------+