diff --git a/Include/MyIncludes/MACD_Calculator.mqh b/Include/MyIncludes/MACD_Calculator.mqh new file mode 100644 index 0000000..d584b6b --- /dev/null +++ b/Include/MyIncludes/MACD_Calculator.mqh @@ -0,0 +1,278 @@ +//+------------------------------------------------------------------+ +//| MACD_Calculator.mqh| +//| Calculation engine for Standard and Heikin Ashi MACD. | +//| Copyright 2025, xxxxxxxx | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2025, xxxxxxxx" + +#include + +//+==================================================================+ +//| | +//| CLASS 1: CMACDCalculator (Base Class) | +//| | +//+==================================================================+ +class CMACDCalculator + { +protected: + int m_fast_period, m_slow_period, m_signal_period; + ENUM_MA_METHOD m_source_ma_type, m_signal_ma_type; + 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: + CMACDCalculator(void) {}; + virtual ~CMACDCalculator(void) {}; + + bool Init(int fast_p, int slow_p, int signal_p, ENUM_MA_METHOD src_ma, ENUM_MA_METHOD sig_ma); + void Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type, + double &macd_line[], double &signal_line[], double &histogram[]); + }; + +//+------------------------------------------------------------------+ +//| CMACDCalculator: Initialization | +//+------------------------------------------------------------------+ +bool CMACDCalculator::Init(int fast_p, int slow_p, int signal_p, ENUM_MA_METHOD src_ma, ENUM_MA_METHOD sig_ma) + { + m_fast_period = (fast_p < 1) ? 1 : fast_p; + m_slow_period = (slow_p < 1) ? 1 : slow_p; + if(m_fast_period > m_slow_period) + { + int temp=m_fast_period; + m_fast_period=m_slow_period; + m_slow_period=temp; + } + m_signal_period = (signal_p < 1) ? 1 : signal_p; + m_source_ma_type = src_ma; + m_signal_ma_type = sig_ma; + return true; + } + +//+------------------------------------------------------------------+ +//| CMACDCalculator: Main Calculation Method (CORRECTED LOGIC) | +//+------------------------------------------------------------------+ +void CMACDCalculator::Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], ENUM_APPLIED_PRICE price_type, + double &macd_line[], double &signal_line[], double &histogram[]) + { + int start_pos = m_slow_period + m_signal_period - 2; + if(rates_total <= start_pos) + return; + + if(!PreparePriceSeries(rates_total, open, high, low, close, price_type)) + return; + + double fast_ma[], slow_ma[]; + ArrayResize(fast_ma, rates_total); + ArrayResize(slow_ma, rates_total); + +//--- STEP 1: Calculate Fast MA + for(int i = m_fast_period - 1; i < rates_total; i++) + { + switch(m_source_ma_type) + { + case MODE_EMA: + case MODE_SMMA: + if(i == m_fast_period - 1) + { + double sum=0; + for(int j=0; j0) fast_ma[i]=sum/w_sum;} + break; + default: + {double sum=0; for(int j=0; j0) slow_ma[i]=sum/w_sum;} + break; + default: + {double sum=0; for(int j=0; j0) signal_line[i]=sum/w_sum;} + break; + default: + {double sum=0; for(int j=0; j