From 84e37e85d7996a44378d8bf403878fd56844c3cc Mon Sep 17 00:00:00 2001 From: Toh4iem9 Date: Wed, 12 Nov 2025 14:24:45 +0100 Subject: [PATCH] refactor: --- Include/MyIncludes/RSI_Pro_Calculator.mqh | 130 +++++++++++----------- 1 file changed, 62 insertions(+), 68 deletions(-) diff --git a/Include/MyIncludes/RSI_Pro_Calculator.mqh b/Include/MyIncludes/RSI_Pro_Calculator.mqh index 55c9f7f..1549e40 100644 --- a/Include/MyIncludes/RSI_Pro_Calculator.mqh +++ b/Include/MyIncludes/RSI_Pro_Calculator.mqh @@ -1,77 +1,80 @@ //+------------------------------------------------------------------+ //| RSI_Pro_Calculator.mqh | -//| VERSION 3.22: Fixed enum conflicts and variable scopes. | +//| Calculation engine for Standard and Heikin Ashi RSI Pro. | //| Copyright 2025, xxxxxxxx | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" #include -//--- NEW: Non-conflicting universal enum for all smoothing types --- -enum ENUM_SMOOTHING_METHOD - { - SMOOTH_SMA, - SMOOTH_EMA, - SMOOTH_SMMA, - SMOOTH_LWMA, - SMOOTH_SuperSmoother - }; - +//+==================================================================+ +//| | +//| CLASS 1: CRSIProCalculator (Base Class) | +//| | //+==================================================================+ class CRSIProCalculator { protected: - int m_rsi_period, m_ma_period; + int m_rsi_period; + int m_ma_period; double m_deviation; - ENUM_SMOOTHING_METHOD m_ma_method; // Use the new enum + ENUM_MA_METHOD m_ma_method; - double m_sig_f1, m_sig_f2; - double m_price[], m_rsi_buffer[], m_ma_buffer[], m_upper_band[], m_lower_band[]; + double m_price[]; + double m_rsi_buffer[]; + double m_ma_buffer[]; + double m_upper_band[]; + double m_lower_band[]; virtual bool PreparePriceSeries(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[]); public: - CRSIProCalculator(void) : m_sig_f1(0), m_sig_f2(0) {}; + CRSIProCalculator(void) {}; virtual ~CRSIProCalculator(void) {}; - bool Init(int rsi_p, int ma_p, ENUM_SMOOTHING_METHOD ma_m, double dev); + bool Init(int rsi_p, int ma_p, ENUM_MA_METHOD ma_m, double dev); void Calculate(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[], double &rsi_out[], double &ma_out[], double &upper_out[], double &lower_out[]); }; //+------------------------------------------------------------------+ -bool CRSIProCalculator::Init(int rsi_p, int ma_p, ENUM_SMOOTHING_METHOD ma_m, double dev) +//| CRSIProCalculator: Initialization | +//+------------------------------------------------------------------+ +bool CRSIProCalculator::Init(int rsi_p, int ma_p, ENUM_MA_METHOD ma_m, double dev) { m_rsi_period = (rsi_p < 1) ? 1 : rsi_p; - m_ma_period = (ma_p < 1) ? 1 : ma_p; - m_ma_method = ma_m; - m_deviation = dev; - m_sig_f1 = 0; - m_sig_f2 = 0; + m_ma_period = (ma_p < 1) ? 1 : ma_p; + m_ma_method = ma_m; + m_deviation = dev; return true; } +//+------------------------------------------------------------------+ +//| CRSIProCalculator: Main Calculation Method | //+------------------------------------------------------------------+ void CRSIProCalculator::Calculate(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[], double &rsi_out[], double &ma_out[], double &upper_out[], double &lower_out[]) { if(rates_total <= m_rsi_period) return; + ArrayResize(m_price, rates_total); ArrayResize(m_rsi_buffer, rates_total); ArrayResize(m_ma_buffer, rates_total); ArrayResize(m_upper_band, rates_total); ArrayResize(m_lower_band, rates_total); + if(!PreparePriceSeries(rates_total, price_type, open, high, low, close)) return; -//--- Step 1: Calculate base RSI (Unchanged) +//--- Step 1: Calculate base RSI double sum_pos = 0, sum_neg = 0; for(int i = 1; i < rates_total; i++) { double diff = m_price[i] - m_price[i-1]; sum_pos = (sum_pos * (m_rsi_period - 1) + (diff > 0 ? diff : 0)) / m_rsi_period; sum_neg = (sum_neg * (m_rsi_period - 1) + (diff < 0 ? -diff : 0)) / m_rsi_period; + if(i >= m_rsi_period) { if(sum_neg > 0) @@ -81,73 +84,64 @@ void CRSIProCalculator::Calculate(int rates_total, ENUM_APPLIED_PRICE price_type } } -//--- Step 2: Calculate Signal Line on RSI +//--- Step 2: Calculate Moving Average on RSI int ma_start_pos = m_rsi_period + m_ma_period - 1; - for(int i = ma_start_pos; i < rates_total; i++) { switch(m_ma_method) { - case SMOOTH_SuperSmoother: - { - //--- Coefficients are now calculated locally inside the case block --- - double a1 = exp(-M_SQRT2 * M_PI / m_ma_period); - double b1 = 2.0 * a1 * cos(M_SQRT2 * M_PI / m_ma_period); - double c2 = b1, c3 = -a1 * a1, c1 = 1.0 - c2 - c3; - - if(i==ma_start_pos) // Robust initialization - { - double sum=0; - for(int j=0; j 0) ? m_ma_buffer[i-1] : m_ma_buffer[i]; - } - else - { - m_ma_buffer[i] = c1 * (m_rsi_buffer[i] + m_rsi_buffer[i-1]) / 2.0 + c2 * m_sig_f1 + c3 * m_sig_f2; - m_sig_f2 = m_sig_f1; - m_sig_f1 = m_ma_buffer[i]; - } - break; - } - case SMOOTH_EMA: - case SMOOTH_SMMA: + case MODE_EMA: + case MODE_SMMA: if(i == ma_start_pos) { - double sum=0; - for(int j=0; j0) m_ma_buffer[i]=sum/w_sum; } - break; - default: // SMOOTH_SMA - { double sum=0; for(int j=0; j 0) + m_ma_buffer[i] = lwma_sum / weight_sum; + break; + } + default: // MODE_SMA + { + double sum = 0; + for(int j = 0; j < m_ma_period; j++) + sum += m_rsi_buffer[i-j]; + m_ma_buffer[i] = sum / m_ma_period; + break; + } } } -//--- Step 3: Calculate Bollinger Bands on the MA line (Unchanged) +//--- Step 3: Calculate Bollinger Bands on the MA line for(int i = ma_start_pos; i < rates_total; i++) { double std_dev_val = 0, sum_sq = 0; for(int j = 0; j < m_ma_period; j++) sum_sq += pow(m_rsi_buffer[i-j] - m_ma_buffer[i], 2); std_dev_val = sqrt(sum_sq / m_ma_period); + m_upper_band[i] = m_ma_buffer[i] + m_deviation * std_dev_val; m_lower_band[i] = m_ma_buffer[i] - m_deviation * std_dev_val; } @@ -254,4 +248,4 @@ bool CRSIProCalculator_HA::PreparePriceSeries(int rates_total, ENUM_APPLIED_PRIC return true; } //+------------------------------------------------------------------+ -//+------------------------------------------------------------------+ +//+------------------------------------------------------------------+ \ No newline at end of file