From 15e4f2020c78d7d14301813eb71bbc31cf7f2d47 Mon Sep 17 00:00:00 2001 From: Toh4iem9 Date: Wed, 22 Oct 2025 16:19:48 +0200 Subject: [PATCH] new files added --- Include/MyIncludes/FRAMA_Calculator.mqh | 189 ++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 Include/MyIncludes/FRAMA_Calculator.mqh diff --git a/Include/MyIncludes/FRAMA_Calculator.mqh b/Include/MyIncludes/FRAMA_Calculator.mqh new file mode 100644 index 0000000..e10fbe9 --- /dev/null +++ b/Include/MyIncludes/FRAMA_Calculator.mqh @@ -0,0 +1,189 @@ +//+------------------------------------------------------------------+ +//| FRAMA_Calculator.mqh | +//| Calculation engine for the John Ehlers' FRAMA. | +//| Copyright 2025, xxxxxxxx | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2025, xxxxxxxx" + +#include + +//+==================================================================+ +//| | +//| CLASS 1: CFRAMACalculator (Base Class) | +//| | +//+==================================================================+ +class CFRAMACalculator + { +protected: + int m_period; + double m_price[], m_high[], m_low[]; + + virtual bool PrepareSourceData(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[]); + +public: + CFRAMACalculator(void) {}; + virtual ~CFRAMACalculator(void) {}; + + bool Init(int period); + void Calculate(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[], double &frama_buffer[]); + }; + +//+------------------------------------------------------------------+ +bool CFRAMACalculator::Init(int period) + { +// N must be an even number + m_period = (period < 4) ? 4 : period; + if(m_period % 2 != 0) + m_period++; + return true; + } + +//+------------------------------------------------------------------+ +void CFRAMACalculator::Calculate(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[], double &frama_buffer[]) + { + if(rates_total < m_period + 1) + return; + if(!PrepareSourceData(rates_total, price_type, open, high, low, close)) + return; + + double frama_prev = 0; + int half_period = m_period / 2; + + for(int i = m_period; i < rates_total; i++) + { + // Step 1: Calculate N1, N2, N3 + int high_idx1 = ArrayMaximum(m_high, i - half_period + 1, half_period); + int low_idx1 = ArrayMinimum(m_low, i - half_period + 1, half_period); + double n1 = (m_high[high_idx1] - m_low[low_idx1]) / half_period; + + int high_idx2 = ArrayMaximum(m_high, i - m_period + 1, half_period); + int low_idx2 = ArrayMinimum(m_low, i - m_period + 1, half_period); + double n2 = (m_high[high_idx2] - m_low[low_idx2]) / half_period; + + int high_idx3 = ArrayMaximum(m_high, i - m_period + 1, m_period); + int low_idx3 = ArrayMinimum(m_low, i - m_period + 1, m_period); + double n3 = (m_high[high_idx3] - m_low[low_idx3]) / m_period; + + // Step 2: Calculate Fractal Dimension (Dimen) + double dimen = 0.0; + if(n1 > 0 && n2 > 0 && n3 > 0) + { + dimen = (log(n1 + n2) - log(n3)) / log(2.0); + } + + // Step 3: Calculate adaptive alpha + double alpha = exp(-4.6 * (dimen - 1.0)); + if(alpha < 0.01) + alpha = 0.01; + if(alpha > 1.0) + alpha = 1.0; + + // Step 4: Calculate FRAMA + double current_frama = alpha * m_price[i] + (1.0 - alpha) * frama_prev; + frama_buffer[i] = current_frama; + + frama_prev = current_frama; + } + +// Initialization for the first value + if(rates_total > m_period) + frama_buffer[m_period] = m_price[m_period]; + } + +//+------------------------------------------------------------------+ +bool CFRAMACalculator::PrepareSourceData(int rates_total, ENUM_APPLIED_PRICE price_type, const double &open[], const double &high[], const double &low[], const double &close[]) + { + ArrayResize(m_price, rates_total); + ArrayResize(m_high, rates_total); + ArrayResize(m_low, rates_total); + ArrayCopy(m_high, high, 0, 0, rates_total); + ArrayCopy(m_low, low, 0, 0, rates_total); + + switch(price_type) + { + case PRICE_CLOSE: + ArrayCopy(m_price, close, 0, 0, rates_total); + break; + case PRICE_OPEN: + ArrayCopy(m_price, open, 0, 0, rates_total); + break; + case PRICE_HIGH: + ArrayCopy(m_price, high, 0, 0, rates_total); + break; + case PRICE_LOW: + ArrayCopy(m_price, low, 0, 0, rates_total); + break; + case PRICE_MEDIAN: + for(int i=0; i