diff --git a/Include/MyIncludes/TDI_Calculator.mqh b/Include/MyIncludes/TDI_Calculator.mqh index e72a563..3ac7f6e 100644 --- a/Include/MyIncludes/TDI_Calculator.mqh +++ b/Include/MyIncludes/TDI_Calculator.mqh @@ -1,30 +1,36 @@ //+------------------------------------------------------------------+ //| TDI_Calculator.mqh | -//| VERSION 2.01: Fixed override signature mismatch. | +//| VERSION 3.10: Refactored to use RSI_Engine. | //| Copyright 2025, xxxxxxxx | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" -#include +#include +#include -//+==================================================================+ -//| CLASS 1: CTDICalculator (Base Class) | -//+==================================================================+ +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ class CTDICalculator { protected: + CRSIEngine *m_rsi_engine; + CMovingAverageCalculator m_price_line_engine; + CMovingAverageCalculator m_signal_line_engine; + CMovingAverageCalculator m_base_line_engine; + int m_rsi_period, m_price_period, m_signal_period, m_base_period; double m_std_dev; - //--- Persistent Buffers - double m_price[]; double m_rsi_buffer[]; + double m_price_line[]; + double m_base_line[]; - virtual bool PreparePriceSeries(int rates_total, int start_index, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[]); + virtual void CreateRSIEngine(void); public: - CTDICalculator(void) {}; - virtual ~CTDICalculator(void) {}; + CTDICalculator(void); + virtual ~CTDICalculator(void); bool Init(int rsi_p, int price_p, int signal_p, int base_p, double dev); 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[], @@ -33,20 +39,37 @@ public: }; //+------------------------------------------------------------------+ -//| Init | +//| | +//+------------------------------------------------------------------+ +CTDICalculator::CTDICalculator(void) { m_rsi_engine = NULL; } +CTDICalculator::~CTDICalculator(void) { if(CheckPointer(m_rsi_engine) != POINTER_INVALID) delete m_rsi_engine; } + +void CTDICalculator::CreateRSIEngine(void) { m_rsi_engine = new CRSIEngine(); } + +//+------------------------------------------------------------------+ +//| | //+------------------------------------------------------------------+ bool CTDICalculator::Init(int rsi_p, int price_p, int signal_p, int base_p, double dev) { - m_rsi_period = (rsi_p < 1) ? 1 : rsi_p; - m_price_period = (price_p < 1) ? 1 : price_p; - m_signal_period = (signal_p < 1) ? 1 : signal_p; - m_base_period = (base_p < 1) ? 1 : base_p; - m_std_dev = (dev <= 0) ? 1.618 : dev; + m_rsi_period = rsi_p; + m_price_period = price_p; + m_signal_period = signal_p; + m_base_period = base_p; + m_std_dev = dev; + CreateRSIEngine(); + if(!m_rsi_engine.Init(m_rsi_period)) + return false; + if(!m_price_line_engine.Init(m_price_period, SMA)) + return false; + if(!m_signal_line_engine.Init(m_signal_period, SMA)) + return false; + if(!m_base_line_engine.Init(m_base_period, SMA)) + return false; return true; } //+------------------------------------------------------------------+ -//| Main Calculation (Optimized) | +//| | //+------------------------------------------------------------------+ void CTDICalculator::Calculate(int rates_total, int prev_calculated, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[], double &price_line_out[], double &signal_line_out[], double &base_line_out[], @@ -55,193 +78,48 @@ void CTDICalculator::Calculate(int rates_total, int prev_calculated, ENUM_APPLIE if(rates_total <= m_rsi_period + m_base_period) return; - int start_index; - if(prev_calculated == 0) - start_index = 0; - else - start_index = prev_calculated - 1; - - if(ArraySize(m_price) != rates_total) + if(ArraySize(m_rsi_buffer) != rates_total) { - ArrayResize(m_price, rates_total); ArrayResize(m_rsi_buffer, rates_total); + ArrayResize(m_price_line, rates_total); + ArrayResize(m_base_line, rates_total); } - if(!PreparePriceSeries(rates_total, start_index, price_type, open, high, low, close)) - return; +// 1. Calculate RSI + m_rsi_engine.Calculate(rates_total, prev_calculated, price_type, open, high, low, close, m_rsi_buffer); -// RSI Loop - double sum_pos = 0, sum_neg = 0; - for(int i = 1; i < rates_total; i++) +// 2. Calculate Price Line + m_price_line_engine.CalculateOnArray(rates_total, prev_calculated, m_rsi_buffer, m_price_line, m_rsi_period); + ArrayCopy(price_line_out, m_price_line, 0, 0, rates_total); + +// 3. Calculate Signal Line + int signal_start = m_rsi_period + m_price_period - 1; + m_signal_line_engine.CalculateOnArray(rates_total, prev_calculated, m_price_line, signal_line_out, signal_start); + +// 4. Calculate Base Line + m_base_line_engine.CalculateOnArray(rates_total, prev_calculated, m_rsi_buffer, m_base_line, m_rsi_period); + ArrayCopy(base_line_out, m_base_line, 0, 0, rates_total); + +// 5. Calculate Bands + int start_index = (prev_calculated > 0) ? prev_calculated - 1 : 0; + int loop_start = MathMax(m_rsi_period + m_base_period - 1, start_index); + + for(int i = loop_start; i < rates_total; i++) { - double diff = m_price[i] - m_price[i-1]; - sum_pos = (sum_pos * (m_rsi_period - 1) + (diff > 0 ? diff : 0)) / m_rsi_period; - sum_neg = (sum_neg * (m_rsi_period - 1) + (diff < 0 ? -diff : 0)) / m_rsi_period; - - if(i >= m_rsi_period) - { - if(sum_neg > 0) - m_rsi_buffer[i] = 100.0 - (100.0 / (1.0 + (sum_pos / sum_neg))); - else - m_rsi_buffer[i] = 100.0; - } - else - m_rsi_buffer[i] = 0; - } - -// Price Line - int pl_start = m_rsi_period + m_price_period - 2; - int loop_start_pl = MathMax(pl_start, start_index); - for(int i = loop_start_pl; i < rates_total; i++) - { - double sum=0; - for(int j=0; j