diff --git a/Include/MyIncludes/CCI_Oscillator_Calculator.mqh b/Include/MyIncludes/CCI_Oscillator_Calculator.mqh index 49cb2da..4e99318 100644 --- a/Include/MyIncludes/CCI_Oscillator_Calculator.mqh +++ b/Include/MyIncludes/CCI_Oscillator_Calculator.mqh @@ -1,252 +1,75 @@ //+------------------------------------------------------------------+ //| CCI_Oscillator_Calculator.mqh| -//| Calculation engine for Standard and Heikin Ashi CCI Oscillator. | -//| (Self-contained version with duplicated logic) | +//| Wrapper for the CCI_Engine to produce Oscillator output. | //| Copyright 2025, xxxxxxxx | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" -#include +#include -//+==================================================================+ -//| | -//| CLASS 1: CCCI_OscillatorCalculator (Base Class) | -//| | -//+==================================================================+ +//--- Base class for polymorphism class CCCI_OscillatorCalculator { -protected: - int m_cci_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: - CCCI_OscillatorCalculator(void) {}; - virtual ~CCCI_OscillatorCalculator(void) {}; - - //--- Public methods - bool Init(int cci_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 &osc_buffer[]); + virtual bool Init(int cci_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 &osc_buffer[])=0; }; -//+------------------------------------------------------------------+ -//| CCCI_OscillatorCalculator: Initialization | -//+------------------------------------------------------------------+ -bool CCCI_OscillatorCalculator::Init(int cci_p, int ma_p, ENUM_MA_METHOD ma_m) +//--- Standard version +class CCCI_OscillatorCalculator_Std : public CCCI_OscillatorCalculator { - m_cci_period = (cci_p < 1) ? 1 : cci_p; - m_ma_period = (ma_p < 1) ? 1 : ma_p; - m_ma_method = ma_m; - return true; - } +protected: + CCCI_Engine *m_engine; +public: + CCCI_OscillatorCalculator_Std(void) { m_engine = new CCCI_Engine(); } + ~CCCI_OscillatorCalculator_Std(void) { if(CheckPointer(m_engine)!=POINTER_INVALID) delete m_engine; } -//+------------------------------------------------------------------+ -//| CCCI_OscillatorCalculator: Main Calculation Method | -//+------------------------------------------------------------------+ -void CCCI_OscillatorCalculator::Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type, double &osc_buffer[]) - { - int start_pos = m_cci_period + m_ma_period - 2; - if(rates_total <= start_pos) - return; - -//--- STEP 1: Prepare the source price array (delegated to virtual method) - if(!PreparePriceSeries(rates_total, open, high, low, close, price_type)) - return; - -//--- Internal calculation buffers - double buffer_cci[], buffer_signal[]; - ArrayResize(buffer_cci, rates_total); - ArrayResize(buffer_signal, rates_total); - - double buffer_sma[], buffer_mad[]; - ArrayResize(buffer_sma, rates_total); - ArrayResize(buffer_mad, rates_total); - const double CCI_CONSTANT = 0.015; - -//--- STEP 2: Calculate the Simple Moving Average of the price - double sma_sum = 0; - for(int i = 0; i < rates_total; i++) + virtual bool Init(int cci_p, int ma_p, ENUM_MA_METHOD ma_m) override { return m_engine.Init(cci_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 &osc_buffer[]) override { - sma_sum += m_price[i]; - if(i >= m_cci_period) - sma_sum -= m_price[i - m_cci_period]; - if(i >= m_cci_period - 1) - buffer_sma[i] = sma_sum / m_cci_period; - } + if(CheckPointer(m_engine)==POINTER_INVALID) + return; -//--- STEP 3: Calculate the Mean Absolute Deviation (MAD) - for(int i = m_cci_period - 1; i < rates_total; i++) - { - double deviation_sum = 0; - for(int j = 0; j < m_cci_period; j++) + double cci_values[], signal_values[]; + ArrayResize(cci_values, rates_total); + ArrayResize(signal_values, rates_total); + + m_engine.Calculate(rates_total, open, high, low, close, price_type, cci_values, signal_values); + + int start_pos = m_engine.GetPeriodCCI() + m_engine.GetPeriodMA() - 2; + for(int i = start_pos; i < rates_total; i++) { - deviation_sum += MathAbs(m_price[i - j] - buffer_sma[i]); - } - buffer_mad[i] = deviation_sum / m_cci_period; - } - -//--- STEP 4: Calculate the final CCI value - for(int i = m_cci_period - 1; i < rates_total; i++) - { - if(buffer_mad[i] > 0) - buffer_cci[i] = (m_price[i] - buffer_sma[i]) / (CCI_CONSTANT * buffer_mad[i]); - } - -//--- STEP 5: Calculate the Signal Line (MA of CCI) - int ma_start_pos = m_cci_period + m_ma_period - 2; - 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) - buffer_signal[i]=lwma_sum/weight_sum; - } - break; - default: // MODE_SMA - { - double sum=0; - for(int j=0; j