diff --git a/Include/MyIncludes/CCI_Oscillator_Calculator.mqh b/Include/MyIncludes/CCI_Oscillator_Calculator.mqh new file mode 100644 index 0000000..49cb2da --- /dev/null +++ b/Include/MyIncludes/CCI_Oscillator_Calculator.mqh @@ -0,0 +1,252 @@ +//+------------------------------------------------------------------+ +//| CCI_Oscillator_Calculator.mqh| +//| Calculation engine for Standard and Heikin Ashi CCI Oscillator. | +//| (Self-contained version with duplicated logic) | +//| Copyright 2025, xxxxxxxx | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2025, xxxxxxxx" + +#include + +//+==================================================================+ +//| | +//| CLASS 1: CCCI_OscillatorCalculator (Base Class) | +//| | +//+==================================================================+ +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[]); + }; + +//+------------------------------------------------------------------+ +//| CCCI_OscillatorCalculator: Initialization | +//+------------------------------------------------------------------+ +bool CCCI_OscillatorCalculator::Init(int cci_p, int ma_p, ENUM_MA_METHOD ma_m) + { + 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; + } + +//+------------------------------------------------------------------+ +//| 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++) + { + 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; + } + +//--- 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++) + { + 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