From 11f0e8f64bd5217759bcf8d78e5f78e1a831e71a Mon Sep 17 00:00:00 2001 From: Toh4iem9 Date: Mon, 8 Dec 2025 12:48:59 +0100 Subject: [PATCH] refactor: Optimized for incremental calculation --- .../Bollinger_Bands_Fibonacci_Calculator.mqh | 191 ++++++++++-------- 1 file changed, 108 insertions(+), 83 deletions(-) diff --git a/Include/MyIncludes/Bollinger_Bands_Fibonacci_Calculator.mqh b/Include/MyIncludes/Bollinger_Bands_Fibonacci_Calculator.mqh index 9dd5bbc..77487ce 100644 --- a/Include/MyIncludes/Bollinger_Bands_Fibonacci_Calculator.mqh +++ b/Include/MyIncludes/Bollinger_Bands_Fibonacci_Calculator.mqh @@ -1,16 +1,14 @@ //+------------------------------------------------------------------+ //| Bollinger_Bands_Fibonacci_Calculator.mqh | -//| Calculation engine for Standard and HA Bollinger Bands with | -//| Fibonacci Ratio deviations. Copyright 2025, xxxxxxxx | +//| VERSION 2.00: Optimized for incremental calculation. | +//| Copyright 2025, xxxxxxxx | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" #include //+==================================================================+ -//| | //| CLASS 1: CBollingerBandsFibonacciCalculator (Standard) | -//| | //+==================================================================+ class CBollingerBandsFibonacciCalculator { @@ -19,22 +17,26 @@ protected: double m_fib_ratio1, m_fib_ratio2, m_fib_ratio3; ENUM_MA_METHOD m_ma_method; + //--- Persistent Buffers for Incremental Calculation double m_price[]; double m_ma_buffer[]; - virtual bool PreparePriceSeries(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[]); + //--- 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: CBollingerBandsFibonacciCalculator(void) {}; virtual ~CBollingerBandsFibonacciCalculator(void) {}; bool Init(int period, double r1, double r2, double r3, ENUM_MA_METHOD ma_method); - void Calculate(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[], + + //--- 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 &ma_out[], double &upper1_out[], double &lower1_out[], double &upper2_out[], double &lower2_out[], double &upper3_out[], double &lower3_out[]); }; //+------------------------------------------------------------------+ -//| CBollingerBandsFibonacciCalculator: Initialization | +//| Init | //+------------------------------------------------------------------+ bool CBollingerBandsFibonacciCalculator::Init(int period, double r1, double r2, double r3, ENUM_MA_METHOD ma_method) { @@ -47,23 +49,37 @@ bool CBollingerBandsFibonacciCalculator::Init(int period, double r1, double r2, } //+------------------------------------------------------------------+ -//| CBollingerBandsFibonacciCalculator: Main Calculation Method | +//| Main Calculation (Optimized) | //+------------------------------------------------------------------+ -void CBollingerBandsFibonacciCalculator::Calculate(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[], +void CBollingerBandsFibonacciCalculator::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 &ma_out[], double &upper1_out[], double &lower1_out[], double &upper2_out[], double &lower2_out[], double &upper3_out[], double &lower3_out[]) { if(rates_total < m_period) return; - ArrayResize(m_price, rates_total); - ArrayResize(m_ma_buffer, rates_total); +//--- 1. Determine Start Index + int start_index; + if(prev_calculated == 0) + start_index = 0; + else + start_index = prev_calculated - 1; - if(!PreparePriceSeries(rates_total, price_type, open, high, low, close)) +//--- 2. Resize Buffers + if(ArraySize(m_price) != rates_total) + { + ArrayResize(m_price, rates_total); + ArrayResize(m_ma_buffer, rates_total); + } + +//--- 3. Prepare Price (Optimized) + if(!PreparePriceSeries(rates_total, start_index, price_type, open, high, low, close)) return; -//--- Step 1: Calculate the centerline (Moving Average) +//--- 4. Calculate Centerline (MA) - Incremental int ma_start_pos = m_period - 1; - for(int i = ma_start_pos; i < rates_total; i++) + int loop_start = MathMax(ma_start_pos, start_index); + + for(int i = loop_start; i < rates_total; i++) { switch(m_ma_method) { @@ -111,8 +127,8 @@ void CBollingerBandsFibonacciCalculator::Calculate(int rates_total, ENUM_APPLIED } } -//--- Step 2: Calculate the Standard Deviation and the Bands - for(int i = ma_start_pos; i < rates_total; i++) +//--- 5. Calculate Bands (Incremental) + for(int i = loop_start; i < rates_total; i++) { double std_dev_val = 0, sum_sq = 0; for(int j = 0; j < m_period; j++) @@ -131,98 +147,107 @@ void CBollingerBandsFibonacciCalculator::Calculate(int rates_total, ENUM_APPLIED } //+------------------------------------------------------------------+ -//| CBollingerBandsFibonacciCalculator: Prepares the source price. | +//| Prepare Price (Standard - Optimized) | //+------------------------------------------------------------------+ -bool CBollingerBandsFibonacciCalculator::PreparePriceSeries(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[]) +bool CBollingerBandsFibonacciCalculator::PreparePriceSeries(int rates_total, int start_index, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[]) { - switch(price_type) +// Optimized copy loop + for(int i = start_index; i < rates_total; i++) { - case PRICE_CLOSE: - ArrayCopy(m_price, close, 0, 0, rates_total); - break; - 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