From be6e2ee0f322b5e1fb125d67a81b35b2f92d0a6e Mon Sep 17 00:00:00 2001 From: Toh4iem9 Date: Wed, 4 Feb 2026 16:27:23 +0100 Subject: [PATCH] new files added --- .../MyIncludes/EfficiencyRatio_Calculator.mqh | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 Include/MyIncludes/EfficiencyRatio_Calculator.mqh diff --git a/Include/MyIncludes/EfficiencyRatio_Calculator.mqh b/Include/MyIncludes/EfficiencyRatio_Calculator.mqh new file mode 100644 index 0000000..7449ac8 --- /dev/null +++ b/Include/MyIncludes/EfficiencyRatio_Calculator.mqh @@ -0,0 +1,128 @@ +//+------------------------------------------------------------------+ +//| EfficiencyRatio_Calculator.mqh | +//| Engine for Kaufman's Efficiency Ratio (ER). | +//| Formula: Net Change / Sum of Changes. | +//| Copyright 2026, xxxxxxxx | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2026, xxxxxxxx" + +#include + +//+==================================================================+ +//| CLASS: CEfficiencyRatioCalculator | +//+==================================================================+ +class CEfficiencyRatioCalculator + { +protected: + int m_period; + double m_price[]; // Persistent price buffer + + virtual bool PreparePrice(int rates_total, int start_index, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[]); + +public: + CEfficiencyRatioCalculator() {}; + virtual ~CEfficiencyRatioCalculator() {}; + + bool Init(int period); + + 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[], + double &out_er[]); + }; + +//+------------------------------------------------------------------+ +//| Init | +//+------------------------------------------------------------------+ +bool CEfficiencyRatioCalculator::Init(int period) + { + m_period = (period < 1) ? 1 : period; + return true; + } + +//+------------------------------------------------------------------+ +//| Main Calculation | +//+------------------------------------------------------------------+ +void CEfficiencyRatioCalculator::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 &out_er[]) + { + if(rates_total <= m_period) + return; + +// 1. Resize Internal + if(ArraySize(m_price) != rates_total) + ArrayResize(m_price, rates_total); + +// 2. Prepare Data + int prepare_start = (prev_calculated > 0) ? prev_calculated - 1 : 0; + if(!PreparePrice(rates_total, prepare_start, price_type, open, high, low, close)) + return; + +// 3. Calculate ER + int start_index = (prev_calculated > 0) ? prev_calculated - 1 : m_period; + if(start_index < m_period) + start_index = m_period; + + for(int i = start_index; i < rates_total; i++) + { + double net_change = MathAbs(m_price[i] - m_price[i - m_period]); + double sum_change = 0.0; + + // Sum absolute bar-to-bar changes over period + for(int k = 0; k < m_period; k++) + { + sum_change += MathAbs(m_price[i - k] - m_price[i - k - 1]); + } + + if(sum_change > 1.0e-9) // Determine efficiency + out_er[i] = net_change / sum_change; + else + out_er[i] = 1.0; // If no volatility, mathematically efficient (flat line) but usually handled as 0 or previous. + // 1.0 is technically correct for straight line, but in trading sum_change=0 usually happens with gaps or bad data. + // Let's default to 0.0 for safety in trading context if flat. + + if(sum_change == 0.0) + out_er[i] = 0.0; + } + } + +//+------------------------------------------------------------------+ +//| Prepare Price | +//+------------------------------------------------------------------+ +bool CEfficiencyRatioCalculator::PreparePrice(int rates_total, int start_index, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[]) + { + for(int i = start_index; i < rates_total; i++) + { + switch(price_type) + { + case PRICE_CLOSE: + m_price[i] = close[i]; + break; + case PRICE_OPEN: + m_price[i] = open[i]; + break; + case PRICE_HIGH: + m_price[i] = high[i]; + break; + case PRICE_LOW: + m_price[i] = low[i]; + break; + case PRICE_MEDIAN: + m_price[i] = (high[i]+low[i])*0.5; + break; + case PRICE_TYPICAL: + m_price[i] = (high[i]+low[i]+close[i])/3.0; + break; + case PRICE_WEIGHTED: + m_price[i] = (high[i]+low[i]+close[i]*2.0)*0.25; + break; + default: + m_price[i] = close[i]; + break; + } + } + return true; + } +//+------------------------------------------------------------------+