From ea74b602bdc0d192940619ab8bd91c377690b4f6 Mon Sep 17 00:00:00 2001 From: Toh4iem9 Date: Thu, 25 Dec 2025 11:48:15 +0100 Subject: [PATCH] refactor: Optimized for incremental calculation --- .../MyIncludes/MACD_Laguerre_Calculator.mqh | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/Include/MyIncludes/MACD_Laguerre_Calculator.mqh b/Include/MyIncludes/MACD_Laguerre_Calculator.mqh index a8bd451..4e13b9a 100644 --- a/Include/MyIncludes/MACD_Laguerre_Calculator.mqh +++ b/Include/MyIncludes/MACD_Laguerre_Calculator.mqh @@ -1,6 +1,6 @@ //+------------------------------------------------------------------+ //| MACD_Laguerre_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,9 +33,13 @@ protected: CLaguerreEngine *m_fast_engine; CLaguerreEngine *m_slow_engine; - //--- Engines for Signal Line (Optimization: Use dedicated engines) - CLaguerreEngine *m_signal_laguerre_engine; // Used if type is Laguerre - CMovingAverageCalculator *m_signal_ma_engine; // Used if type is SMA/EMA... + //--- Engines for Signal Line + CLaguerreEngine *m_signal_laguerre_engine; + CMovingAverageCalculator *m_signal_ma_engine; + + //--- Persistent Buffers + double m_fast_filter[]; + double m_slow_filter[]; virtual CLaguerreEngine *CreateEngineInstance(void); @@ -114,8 +121,6 @@ bool CMACDLaguerreCalculator::Init(double g1, double g2, double sig_g, int sig_p // Create Signal Engine based on type if(m_signal_ma_type == SMOOTH_Laguerre) { - // For Signal Line, we use standard Laguerre Engine (on MACD data, not HA) - // Even if main calc is HA, the MACD line is already processed, so signal is just math on array. m_signal_laguerre_engine = new CLaguerreEngine(); if(!m_signal_laguerre_engine.Init(m_signal_gamma, SOURCE_PRICE)) return false; @@ -140,29 +145,30 @@ void CMACDLaguerreCalculator::Calculate(int rates_total, int prev_calculated, co if(rates_total < 2) return; +// Resize internal buffers + if(ArraySize(m_fast_filter) != rates_total) + { + ArrayResize(m_fast_filter, rates_total); + ArrayResize(m_slow_filter, rates_total); + } + //--- 1. Calculate Fast and Slow Laguerre Filters (Incremental) -// We need temp buffers for the filters -// Optimization: We can reuse macd_line as one buffer if we are careful, but let's use temp buffers for clarity. -// Actually, LaguerreEngine needs a destination buffer. -// Let's use static/member buffers if we want to avoid allocation, but local arrays are fine for now as Engine handles state. - - double fast_filter[], slow_filter[]; -// Note: The engine resizes them. - - 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); + 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 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]; + macd_line[i] = m_fast_filter[i] - m_slow_filter[i]; //--- 3. Calculate Signal Line +// 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 treat MACD line as 'close' price. m_signal_laguerre_engine.CalculateFilter(rates_total, prev_calculated, PRICE_CLOSE, macd_line, macd_line, macd_line, macd_line, signal_line); @@ -170,9 +176,7 @@ void CMACDLaguerreCalculator::Calculate(int rates_total, int prev_calculated, co 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, macd_line, signal_line, macd_offset); } //--- 4. Calculate Histogram @@ -180,3 +184,4 @@ void CMACDLaguerreCalculator::Calculate(int rates_total, int prev_calculated, co histogram[i] = macd_line[i] - signal_line[i]; } //+------------------------------------------------------------------+ +//+------------------------------------------------------------------+