From 64f39aeff6e2489924f29dac1772b2f9ef735b97 Mon Sep 17 00:00:00 2001 From: Toh4iem9 Date: Tue, 16 Dec 2025 15:23:40 +0100 Subject: [PATCH] refactor: Optimized for incremental calculation --- Include/MyIncludes/GannHiLo_Calculator.mqh | 180 ++++++++++++++------- 1 file changed, 120 insertions(+), 60 deletions(-) diff --git a/Include/MyIncludes/GannHiLo_Calculator.mqh b/Include/MyIncludes/GannHiLo_Calculator.mqh index de277f9..2649ca1 100644 --- a/Include/MyIncludes/GannHiLo_Calculator.mqh +++ b/Include/MyIncludes/GannHiLo_Calculator.mqh @@ -1,6 +1,6 @@ //+------------------------------------------------------------------+ //| Gann_HiLo_Calculator.mqh| -//| Calculation engine for Standard and Heikin Ashi Gann HiLo. | +//| VERSION 2.00: Optimized for incremental calculation. | //| Copyright 2025, xxxxxxxx | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" @@ -8,9 +8,7 @@ #include //+==================================================================+ -//| | //| CLASS 1: CGannHiLoCalculator (Base Class) | -//| | //+==================================================================+ class CGannHiLoCalculator { @@ -18,20 +16,25 @@ protected: int m_period; ENUM_MA_METHOD m_ma_method; + //--- Persistent Buffers for Incremental Calculation double m_src_high[], m_src_low[], m_src_close[]; + double m_hi_avg[], m_lo_avg[], m_trend[]; - virtual bool PrepareSourceData(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[]); + //--- Updated: Accepts start_index + virtual bool PrepareSourceData(int rates_total, int start_index, const double &open[], const double &high[], const double &low[], const double &close[]); public: CGannHiLoCalculator(void) {}; virtual ~CGannHiLoCalculator(void) {}; bool Init(int period, ENUM_MA_METHOD ma_method); - void Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], double &hilo_buffer[], double &color_buffer[]); + + //--- Updated: Accepts prev_calculated + void Calculate(int rates_total, int prev_calculated, const double &open[], const double &high[], const double &low[], const double &close[], double &hilo_buffer[], double &color_buffer[]); }; //+------------------------------------------------------------------+ -//| CGannHiLoCalculator: Initialization | +//| Init | //+------------------------------------------------------------------+ bool CGannHiLoCalculator::Init(int period, ENUM_MA_METHOD ma_method) { @@ -41,30 +44,46 @@ bool CGannHiLoCalculator::Init(int period, ENUM_MA_METHOD ma_method) } //+------------------------------------------------------------------+ -//| CGannHiLoCalculator: Main Calculation Method (Shared Logic) | +//| Main Calculation (Optimized) | //+------------------------------------------------------------------+ -void CGannHiLoCalculator::Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], double &hilo_buffer[], double &color_buffer[]) +void CGannHiLoCalculator::Calculate(int rates_total, int prev_calculated, const double &open[], const double &high[], const double &low[], const double &close[], double &hilo_buffer[], double &color_buffer[]) { if(rates_total <= m_period) return; - if(!PrepareSourceData(rates_total, open, high, low, close)) + +//--- 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_src_high) != rates_total) + { + ArrayResize(m_src_high, rates_total); + ArrayResize(m_src_low, rates_total); + ArrayResize(m_src_close, rates_total); + ArrayResize(m_hi_avg, rates_total); + ArrayResize(m_lo_avg, rates_total); + ArrayResize(m_trend, rates_total); + } + +//--- 3. Prepare Source Data (Optimized) + if(!PrepareSourceData(rates_total, start_index, open, high, low, close)) return; - double hi_avg[], lo_avg[], trend[]; - ArrayResize(hi_avg, rates_total); - ArrayResize(lo_avg, rates_total); - ArrayResize(trend, rates_total); +//--- 4. Calculate High/Low Averages (Incremental) + int ma_start_pos = m_period - 1; + int loop_start = MathMax(ma_start_pos, start_index); - for(int i = 1; i < rates_total; i++) + for(int i = loop_start; i < rates_total; i++) { - if(i < m_period - 1) - continue; - switch(m_ma_method) { case MODE_EMA: case MODE_SMMA: - if(i == m_period - 1) + if(i == ma_start_pos) { double sum_h=0, sum_l=0; for(int j=0; j0) {hi_avg[i]=wh/ws; lo_avg[i]=wl/ws;}} + { + double wh=0,wl=0,ws=0; + for(int j=0; j0) + { + m_hi_avg[i]=wh/ws; + m_lo_avg[i]=wl/ws; + } + } break; - default: - {double sh=0,sl=0; for(int j=0; j hi_avg[i-1]) - trend[i] = 1; + if(m_src_close[i] > m_hi_avg[i-1]) + m_trend[i] = 1; else - if(m_src_close[i] < lo_avg[i-1]) - trend[i] = -1; + if(m_src_close[i] < m_lo_avg[i-1]) + m_trend[i] = -1; else - trend[i] = trend[i-1]; + m_trend[i] = m_trend[i-1]; // Keep previous trend - if(trend[i] == 1) + //--- 6. Output to Buffers + if(m_trend[i] == 1) { - hilo_buffer[i] = lo_avg[i]; + hilo_buffer[i] = m_lo_avg[i]; color_buffer[i] = 0; - if(trend[i-1] == -1) - hilo_buffer[i-1] = lo_avg[i]; + // Backfill gap if trend changed + if(m_trend[i-1] == -1) + hilo_buffer[i-1] = m_lo_avg[i]; } else { - hilo_buffer[i] = hi_avg[i]; + hilo_buffer[i] = m_hi_avg[i]; color_buffer[i] = 1; - if(trend[i-1] == 1) - hilo_buffer[i-1] = hi_avg[i]; + if(m_trend[i-1] == 1) + hilo_buffer[i-1] = m_hi_avg[i]; } } } //+------------------------------------------------------------------+ -//| CGannHiLoCalculator: Prepares the standard source data series. | +//| Prepare Source Data (Standard - Optimized) | //+------------------------------------------------------------------+ -bool CGannHiLoCalculator::PrepareSourceData(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[]) +bool CGannHiLoCalculator::PrepareSourceData(int rates_total, int start_index, const double &open[], const double &high[], const double &low[], const double &close[]) { - ArrayResize(m_src_high, rates_total); - ArrayCopy(m_src_high, high, 0, 0, rates_total); - ArrayResize(m_src_low, rates_total); - ArrayCopy(m_src_low, low, 0, 0, rates_total); - ArrayResize(m_src_close, rates_total); - ArrayCopy(m_src_close, close, 0, 0, rates_total); +// Optimized copy loop + for(int i = start_index; i < rates_total; i++) + { + m_src_high[i] = high[i]; + m_src_low[i] = low[i]; + m_src_close[i] = close[i]; + } return true; } //+==================================================================+ -//| | -//| CLASS 2: CGannHiLoCalculator_HA (Heikin Ashi) | -//| | +//| CLASS 2: CGannHiLoCalculator_HA (Heikin Ashi) | //+==================================================================+ class CGannHiLoCalculator_HA : public CGannHiLoCalculator { private: CHeikinAshi_Calculator m_ha_calculator; + // Internal HA buffers + double m_ha_open[], m_ha_high_temp[], m_ha_low_temp[], m_ha_close_temp[]; + protected: - virtual bool PrepareSourceData(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[]) override; + virtual bool PrepareSourceData(int rates_total, int start_index, const double &open[], const double &high[], const double &low[], const double &close[]) override; }; //+------------------------------------------------------------------+ -//| CGannHiLoCalculator_HA: Prepares the Heikin Ashi source data. | +//| Prepare Source Data (Heikin Ashi - Optimized) | //+------------------------------------------------------------------+ -bool CGannHiLoCalculator_HA::PrepareSourceData(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[]) +bool CGannHiLoCalculator_HA::PrepareSourceData(int rates_total, int start_index, const double &open[], const double &high[], const double &low[], const double &close[]) { - double ha_open[]; - ArrayResize(ha_open, rates_total); - ArrayResize(m_src_high, rates_total); - ArrayResize(m_src_low, rates_total); - ArrayResize(m_src_close, rates_total); +// Resize internal HA buffers + if(ArraySize(m_ha_open) != rates_total) + { + ArrayResize(m_ha_open, rates_total); + ArrayResize(m_ha_high_temp, rates_total); + ArrayResize(m_ha_low_temp, rates_total); + ArrayResize(m_ha_close_temp, rates_total); + } - m_ha_calculator.Calculate(rates_total, open, high, low, close, ha_open, m_src_high, m_src_low, m_src_close); +//--- STRICT CALL: Use the optimized 10-param HA calculation + m_ha_calculator.Calculate(rates_total, start_index, open, high, low, close, + m_ha_open, m_ha_high_temp, m_ha_low_temp, m_ha_close_temp); + +//--- Copy to source buffers (Optimized loop) + for(int i = start_index; i < rates_total; i++) + { + m_src_high[i] = m_ha_high_temp[i]; + m_src_low[i] = m_ha_low_temp[i]; + m_src_close[i] = m_ha_close_temp[i]; + } return true; } //+------------------------------------------------------------------+ -//+------------------------------------------------------------------+