//+------------------------------------------------------------------+ //| RSI_Pro_Calculator.mqh | //| VERSION 3.22: Fixed enum conflicts and variable scopes. | //| 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 CRSIProCalculator { protected: int m_rsi_period, m_ma_period; double m_deviation; ENUM_SMOOTHING_METHOD m_ma_method; // Use the new enum double m_sig_f1, m_sig_f2; double m_price[], m_rsi_buffer[], m_ma_buffer[], m_upper_band[], 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) {}; virtual ~CRSIProCalculator(void) {}; bool Init(int rsi_p, int ma_p, ENUM_SMOOTHING_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) { 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; return true; } //+------------------------------------------------------------------+ 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) 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) m_rsi_buffer[i] = 100.0 - (100.0 / (1.0 + (sum_pos / sum_neg))); else m_rsi_buffer[i] = 100.0; } } //--- Step 2: Calculate Signal Line 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: 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