From f9f067ce94895283050ea1b2eab529db994923f3 Mon Sep 17 00:00:00 2001 From: Toh4iem9 Date: Mon, 1 Dec 2025 18:51:58 +0100 Subject: [PATCH] refactor: Optimized for incremental calculation --- Include/MyIncludes/MACD_Calculator.mqh | 236 ++++++++++++++----------- 1 file changed, 136 insertions(+), 100 deletions(-) diff --git a/Include/MyIncludes/MACD_Calculator.mqh b/Include/MyIncludes/MACD_Calculator.mqh index d584b6b..23fae7a 100644 --- a/Include/MyIncludes/MACD_Calculator.mqh +++ b/Include/MyIncludes/MACD_Calculator.mqh @@ -1,6 +1,6 @@ //+------------------------------------------------------------------+ //| MACD_Calculator.mqh| -//| Calculation engine for Standard and Heikin Ashi MACD. | +//| VERSION 1.20: Optimized for incremental calculation. | //| Copyright 2025, xxxxxxxx | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" @@ -8,31 +8,35 @@ #include //+==================================================================+ -//| | //| CLASS 1: CMACDCalculator (Base Class) | -//| | //+==================================================================+ class CMACDCalculator { protected: int m_fast_period, m_slow_period, m_signal_period; ENUM_MA_METHOD m_source_ma_type, m_signal_ma_type; - double m_price[]; - //--- 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); + //--- Persistent Buffers for Incremental Calculation + double m_price[]; + double m_fast_ma[]; + double m_slow_ma[]; + + //--- Updated: Accepts start_index + virtual bool PreparePriceSeries(int rates_total, int start_index, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type); public: CMACDCalculator(void) {}; virtual ~CMACDCalculator(void) {}; bool Init(int fast_p, int slow_p, int signal_p, ENUM_MA_METHOD src_ma, ENUM_MA_METHOD sig_ma); - void Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type, + + //--- Updated: Accepts prev_calculated + void Calculate(int rates_total, int prev_calculated, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type, double &macd_line[], double &signal_line[], double &histogram[]); }; //+------------------------------------------------------------------+ -//| CMACDCalculator: Initialization | +//| Init | //+------------------------------------------------------------------+ bool CMACDCalculator::Init(int fast_p, int slow_p, int signal_p, ENUM_MA_METHOD src_ma, ENUM_MA_METHOD sig_ma) { @@ -51,24 +55,38 @@ bool CMACDCalculator::Init(int fast_p, int slow_p, int signal_p, ENUM_MA_METHOD } //+------------------------------------------------------------------+ -//| CMACDCalculator: Main Calculation Method (CORRECTED LOGIC) | +//| Main Calculation (Optimized) | //+------------------------------------------------------------------+ -void CMACDCalculator::Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type, +void CMACDCalculator::Calculate(int rates_total, int prev_calculated, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type, double &macd_line[], double &signal_line[], double &histogram[]) { int start_pos = m_slow_period + m_signal_period - 2; if(rates_total <= start_pos) return; - if(!PreparePriceSeries(rates_total, open, high, low, close, price_type)) +//--- 1. Determine Start Index + int start_index; + if(prev_calculated == 0) + start_index = 0; + else + start_index = prev_calculated - 1; + +//--- 2. Resize Buffers + if(ArraySize(m_price) != rates_total) + { + ArrayResize(m_price, rates_total); + ArrayResize(m_fast_ma, rates_total); + ArrayResize(m_slow_ma, rates_total); + } + +//--- 3. Prepare Price (Optimized) + if(!PreparePriceSeries(rates_total, start_index, open, high, low, close, price_type)) return; - double fast_ma[], slow_ma[]; - ArrayResize(fast_ma, rates_total); - ArrayResize(slow_ma, rates_total); +//--- 4. Calculate Fast MA (Incremental) + int loop_start_fast = MathMax(m_fast_period - 1, start_index); -//--- STEP 1: Calculate Fast MA - for(int i = m_fast_period - 1; i < rates_total; i++) + for(int i = loop_start_fast; i < rates_total; i++) { switch(m_source_ma_type) { @@ -79,30 +97,32 @@ void CMACDCalculator::Calculate(int rates_total, const double &open[], const dou double sum=0; for(int j=0; j0) fast_ma[i]=sum/w_sum;} + {double sum=0,w_sum=0; for(int j=0; j0) m_fast_ma[i]=sum/w_sum;} break; default: - {double sum=0; for(int j=0; j0) slow_ma[i]=sum/w_sum;} + {double sum=0,w_sum=0; for(int j=0; j0) m_slow_ma[i]=sum/w_sum;} break; default: - {double sum=0; for(int j=0; j