diff --git a/Include/MyIncludes/Laguerre_ROC_Calculator.mqh b/Include/MyIncludes/Laguerre_ROC_Calculator.mqh new file mode 100644 index 0000000..4626539 --- /dev/null +++ b/Include/MyIncludes/Laguerre_ROC_Calculator.mqh @@ -0,0 +1,151 @@ +//+------------------------------------------------------------------+ +//| Laguerre_ROC_Calculator.mqh | +//| Laguerre Rate of Change (Slope) Calculator. | +//| Copyright 2026, xxxxxxxx | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2026, xxxxxxxx" + +#include +#include + +//--- Enum for ROC Calculation Mode +enum ENUM_ROC_MODE + { + ROC_POINTS, // Absolute difference (Slope) + ROC_PERCENT // Percentage change + }; + +//+==================================================================+ +//| CLASS 1: CLaguerreROCCalculator (Base) | +//+==================================================================+ +class CLaguerreROCCalculator + { +protected: + //--- Composition + CLaguerreEngine *m_laguerre_engine; + CMovingAverageCalculator *m_signal_engine; + + //--- Internal Buffer for Laguerre Filter values + double m_filter_buffer[]; + + virtual void CreateEngines(void); + +public: + CLaguerreROCCalculator(void); + virtual ~CLaguerreROCCalculator(void); + + bool Init(double gamma, int signal_period, ENUM_MA_TYPE signal_method); + + 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[], + ENUM_ROC_MODE roc_mode, double &roc_buffer[], double &signal_buffer[]); + }; + +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CLaguerreROCCalculator::CLaguerreROCCalculator(void) + { + m_laguerre_engine = NULL; + m_signal_engine = NULL; + } + +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CLaguerreROCCalculator::~CLaguerreROCCalculator(void) + { + if(CheckPointer(m_laguerre_engine) != POINTER_INVALID) + delete m_laguerre_engine; + if(CheckPointer(m_signal_engine) != POINTER_INVALID) + delete m_signal_engine; + } + +//+------------------------------------------------------------------+ +//| Factory Method | +//+------------------------------------------------------------------+ +void CLaguerreROCCalculator::CreateEngines(void) + { + m_laguerre_engine = new CLaguerreEngine(); + m_signal_engine = new CMovingAverageCalculator(); + } + +//+------------------------------------------------------------------+ +//| Init | +//+------------------------------------------------------------------+ +bool CLaguerreROCCalculator::Init(double gamma, int signal_period, ENUM_MA_TYPE signal_method) + { + CreateEngines(); + + if(CheckPointer(m_laguerre_engine) == POINTER_INVALID || !m_laguerre_engine.Init(gamma, SOURCE_PRICE)) + return false; + + if(!m_signal_engine.Init(signal_period, signal_method)) + return false; + + return true; + } + +//+------------------------------------------------------------------+ +//| Main Calculation | +//+------------------------------------------------------------------+ +void CLaguerreROCCalculator::Calculate(int rates_total, int prev_calculated, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[], + ENUM_ROC_MODE roc_mode, double &roc_buffer[], double &signal_buffer[]) + { + if(rates_total < 2) + return; + +//--- Resize Internal Buffer + if(ArraySize(m_filter_buffer) != rates_total) + ArrayResize(m_filter_buffer, rates_total); + +//--- 1. Calculate Laguerre Filter (The source for ROC) + m_laguerre_engine.CalculateFilter(rates_total, prev_calculated, price_type, open, high, low, close, m_filter_buffer); + +//--- 2. Calculate ROC (Incremental Loop) + int start_index = (prev_calculated > 0) ? prev_calculated - 1 : 1; + if(start_index < 1) + start_index = 1; + + for(int i = start_index; i < rates_total; i++) + { + double current = m_filter_buffer[i]; + double prev = m_filter_buffer[i-1]; + + if(roc_mode == ROC_POINTS) + { + // Simple Slope: Current - Previous + roc_buffer[i] = current - prev; + } + else // ROC_PERCENT + { + // Percentage Change: (Current - Previous) / Previous * 100 + if(prev != 0.0) + roc_buffer[i] = ((current - prev) / prev) * 100.0; + else + roc_buffer[i] = 0.0; + } + } + +//--- 3. Calculate Signal Line +// We pass roc_buffer as the source for the MA + m_signal_engine.CalculateOnArray(rates_total, prev_calculated, roc_buffer, signal_buffer); + } + +//+==================================================================+ +//| CLASS 2: CLaguerreROCCalculator_HA | +//+==================================================================+ +class CLaguerreROCCalculator_HA : public CLaguerreROCCalculator + { +protected: + virtual void CreateEngines(void) override; + }; + +//+------------------------------------------------------------------+ +//| Factory Override | +//+------------------------------------------------------------------+ +void CLaguerreROCCalculator_HA::CreateEngines(void) + { + m_laguerre_engine = new CLaguerreEngine_HA(); + m_signal_engine = new CMovingAverageCalculator(); + } +//+------------------------------------------------------------------+