diff --git a/Include/MyIncludes/MFI_Calculator.mqh b/Include/MyIncludes/MFI_Calculator.mqh new file mode 100644 index 0000000..2eba7ca --- /dev/null +++ b/Include/MyIncludes/MFI_Calculator.mqh @@ -0,0 +1,175 @@ +//+------------------------------------------------------------------+ +//| MFI_Calculator.mqh | +//| Calculation engine for Standard and Heikin Ashi MFI. | +//| Copyright 2025, xxxxxxxx | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2025, xxxxxxxx" + +#include + +//+==================================================================+ +//| | +//| CLASS 1: CMFICalculator (Base Class) | +//| | +//+==================================================================+ +class CMFICalculator + { +protected: + int m_mfi_period, m_ma_period; + ENUM_MA_METHOD m_ma_method; + ENUM_APPLIED_VOLUME m_volume_type; + double m_typical_price[]; + + //--- CORRECTED: Added 'open' to signature + virtual bool PreparePriceSeries(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[]); + +public: + CMFICalculator(void) {}; + virtual ~CMFICalculator(void) {}; + + bool Init(int mfi_p, int ma_p, ENUM_MA_METHOD ma_m, ENUM_APPLIED_VOLUME vol_t); + //--- CORRECTED: Added 'open' to signature + void Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], + double &mfi_buffer[], double &signal_buffer[]); + }; + +//+------------------------------------------------------------------+ +//| CMFICalculator: Initialization | +//+------------------------------------------------------------------+ +bool CMFICalculator::Init(int mfi_p, int ma_p, ENUM_MA_METHOD ma_m, ENUM_APPLIED_VOLUME vol_t) + { + m_mfi_period = (mfi_p < 1) ? 1 : mfi_p; + m_ma_period = (ma_p < 1) ? 1 : ma_p; + m_ma_method = ma_m; + m_volume_type = vol_t; + return true; + } + +//+------------------------------------------------------------------+ +//| CMFICalculator: Main Calculation Method (Shared Logic) | +//+------------------------------------------------------------------+ +void CMFICalculator::Calculate(int rates_total, const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], + double &mfi_buffer[], double &signal_buffer[]) + { + if(rates_total <= m_mfi_period + m_ma_period) + return; +//--- CORRECTED: Pass 'open' to PreparePriceSeries + if(!PreparePriceSeries(rates_total, open, high, low, close)) + return; + + double pos_mf[], neg_mf[]; + ArrayResize(pos_mf, rates_total); + ArrayResize(neg_mf, rates_total); + + for(int i=1; i m_typical_price[i-1]) + pos_mf[i] = raw_mf; + else + if(m_typical_price[i] < m_typical_price[i-1]) + neg_mf[i] = raw_mf; + } + + double sum_pos = 0, sum_neg = 0; + for(int i = 1; i < rates_total; i++) + { + sum_pos += pos_mf[i]; + sum_neg += neg_mf[i]; + if(i > m_mfi_period) + { + sum_pos -= pos_mf[i - m_mfi_period]; + sum_neg -= neg_mf[i - m_mfi_period]; + } + if(i >= m_mfi_period) + { + if(sum_neg > 0) + { + double ratio = sum_pos / sum_neg; + mfi_buffer[i] = 100.0 - (100.0 / (1.0 + ratio)); + } + else + mfi_buffer[i] = 100.0; + } + } + + int ma_start_pos = m_mfi_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