From 4aa70d3e0303de6011605cb87dbd94c900eef6c0 Mon Sep 17 00:00:00 2001 From: Toh4iem9 Date: Mon, 29 Sep 2025 16:22:40 +0200 Subject: [PATCH] refactor: add CutlerRSI_Engine --- Include/MyIncludes/CutlerRSI_Calculator.mqh | 226 +++----------------- 1 file changed, 27 insertions(+), 199 deletions(-) diff --git a/Include/MyIncludes/CutlerRSI_Calculator.mqh b/Include/MyIncludes/CutlerRSI_Calculator.mqh index c84521b..19262b5 100644 --- a/Include/MyIncludes/CutlerRSI_Calculator.mqh +++ b/Include/MyIncludes/CutlerRSI_Calculator.mqh @@ -1,223 +1,51 @@ //+------------------------------------------------------------------+ //| CutlerRSI_Calculator.mqh| -//| Calculation engine for Standard and Heikin Ashi Cutler's RSI. | +//| Wrapper for the CutlerRSI_Engine to produce RSI output. | //| Copyright 2025, xxxxxxxx | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" -#include +#include -//+==================================================================+ -//| | -//| CLASS 1: CCutlerRSICalculator (Base Class) | -//| | -//+==================================================================+ +//--- Abstract base class for polymorphism class CCutlerRSICalculator { -protected: - int m_rsi_period; - int m_ma_period; - ENUM_MA_METHOD m_ma_method; - - //--- Internal buffer for the selected source price - 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); - public: - CCutlerRSICalculator(void) {}; - virtual ~CCutlerRSICalculator(void) {}; - - //--- Public methods - bool Init(int rsi_p, int ma_p, ENUM_MA_METHOD ma_m); - void Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type, double &rsi_buffer[], double &signal_buffer[]); + virtual bool Init(int rsi_p, int ma_p, ENUM_MA_METHOD ma_m)=0; + virtual void Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type, double &rsi_buffer[], double &signal_buffer[])=0; }; -//+------------------------------------------------------------------+ -//| CCutlerRSICalculator: Initialization | -//+------------------------------------------------------------------+ -bool CCutlerRSICalculator::Init(int rsi_p, int ma_p, ENUM_MA_METHOD ma_m) +//--- Standard version uses the standard engine +class CCutlerRSICalculator_Std : public CCutlerRSICalculator { - m_rsi_period = (rsi_p < 1) ? 1 : rsi_p; - m_ma_period = (ma_p < 1) ? 1 : ma_p; - m_ma_method = ma_m; - return true; - } +protected: + CCutlerRSI_Engine *m_engine; +public: + CCutlerRSICalculator_Std(void) { m_engine = new CCutlerRSI_Engine(); } + ~CCutlerRSICalculator_Std(void) { if(CheckPointer(m_engine)!=POINTER_INVALID) delete m_engine; } -//+------------------------------------------------------------------+ -//| CCutlerRSICalculator: Main Calculation Method (Shared Logic) | -//+------------------------------------------------------------------+ -void CCutlerRSICalculator::Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type, double &rsi_buffer[], double &signal_buffer[]) - { - if(rates_total <= m_rsi_period) - return; - -//--- STEP 1: Prepare the source price array (delegated to virtual method) - if(!PreparePriceSeries(rates_total, open, high, low, close, price_type)) - return; - -//--- STEP 2: Calculate Cutler's RSI (SMA-based) using a sliding window sum - double sum_pos = 0, sum_neg = 0; - for(int i = 1; i < rates_total; i++) + virtual bool Init(int rsi_p, int ma_p, ENUM_MA_METHOD ma_m) override { return m_engine.Init(rsi_p, ma_p, ma_m); } + virtual void Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type, double &rsi_buffer[], double &signal_buffer[]) override { - double diff = m_price[i] - m_price[i-1]; - double pos_change = (diff > 0) ? diff : 0; - double neg_change = (diff < 0) ? -diff : 0; - - sum_pos += pos_change; - sum_neg += neg_change; - - if(i > m_rsi_period) - { - double old_diff = m_price[i - m_rsi_period] - m_price[i - m_rsi_period - 1]; - sum_pos -= (old_diff > 0) ? old_diff : 0; - sum_neg -= (old_diff < 0) ? -old_diff : 0; - } - - if(i >= m_rsi_period) - { - if(sum_pos + sum_neg > 0) - { - // The division by period cancels out, so we can use sums directly - double rs = sum_pos / sum_neg; - rsi_buffer[i] = 100.0 - (100.0 / (1.0 + rs)); - } - else - { - rsi_buffer[i] = 100.0; - } - } + if(CheckPointer(m_engine)!=POINTER_INVALID) + m_engine.Calculate(rates_total, open, high, low, close, price_type, rsi_buffer, signal_buffer); } + }; -//--- STEP 3: Calculate the Signal Line (MA of Cutler's 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 MODE_EMA: - case MODE_SMMA: - if(i == ma_start_pos) - { - double sum=0; - for(int j=0; j0) signal_buffer[i]=lwma_sum/weight_sum;} - break; - default: - {double sum=0; for(int j=0; j