From 9b11036edeee74c0b34b92a3fff97e97c0616f8b Mon Sep 17 00:00:00 2001 From: Toh4iem9 Date: Sun, 30 Nov 2025 10:24:04 +0100 Subject: [PATCH] new files added --- .../Laguerre_Filter_Volatility_Calculator.mqh | 285 ++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 Include/MyIncludes/Laguerre_Filter_Volatility_Calculator.mqh diff --git a/Include/MyIncludes/Laguerre_Filter_Volatility_Calculator.mqh b/Include/MyIncludes/Laguerre_Filter_Volatility_Calculator.mqh new file mode 100644 index 0000000..e248e2f --- /dev/null +++ b/Include/MyIncludes/Laguerre_Filter_Volatility_Calculator.mqh @@ -0,0 +1,285 @@ +//+------------------------------------------------------------------+ +//| Laguerre_Filter_Volatility_Calculator.mqh | +//| Calculation engine for Volatility-Adaptive Laguerre Filter. | +//| Based on MotiveWave documentation logic. | +//| Copyright 2025, xxxxxxxx | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2025, xxxxxxxx" + +#include + +//+==================================================================+ +class CLaguerreFilterVolatilityCalculator + { +protected: + int m_period1; // Lookback for High/Low of Diff + int m_period2; // Lookback for Median of Alpha + + //--- Persistent Buffers + double m_price[]; + double m_diff_buf[]; // Stores abs(price - prev_filter) + double m_mid_buf[]; // Stores normalized mid values + + //--- Laguerre State + double m_L0_buf[], m_L1_buf[], m_L2_buf[], m_L3_buf[]; + double m_filter_buf[]; // Stores the final filter output + + 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[]); + + //--- Helpers + double GetHighest(const double &arr[], int start_idx, int len); + double GetLowest(const double &arr[], int start_idx, int len); + double GetMedian(const double &arr[], int start_idx, int len); + +public: + CLaguerreFilterVolatilityCalculator(void) {}; + virtual ~CLaguerreFilterVolatilityCalculator(void) {}; + + bool Init(int p1, int p2); + 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 &output_buffer[]); + }; + +//+------------------------------------------------------------------+ +bool CLaguerreFilterVolatilityCalculator::Init(int p1, int p2) + { + m_period1 = (p1 < 1) ? 1 : p1; + m_period2 = (p2 < 1) ? 1 : p2; + return true; + } + +//+------------------------------------------------------------------+ +void CLaguerreFilterVolatilityCalculator::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 &output_buffer[]) + { + int needed_history = MathMax(m_period1, m_period2) + 1; + if(rates_total < needed_history) + return; + +//--- 1. Determine Start Index + int start_index; + if(prev_calculated == 0) + start_index = 0; + else + start_index = prev_calculated - 1; + +//--- 2. Resize Buffers + if(ArraySize(m_price) != rates_total) + { + ArrayResize(m_price, rates_total); + ArrayResize(m_diff_buf, rates_total); + ArrayResize(m_mid_buf, rates_total); + ArrayResize(m_L0_buf, rates_total); + ArrayResize(m_L1_buf, rates_total); + ArrayResize(m_L2_buf, rates_total); + ArrayResize(m_L3_buf, rates_total); + ArrayResize(m_filter_buf, rates_total); + } + +//--- 3. Prepare Price + if(!PreparePriceSeries(rates_total, start_index, price_type, open, high, low, close)) + return; + +//--- 4. Main Loop + int i = start_index; + +// Initialization + if(i == 0) + { + m_diff_buf[0] = 0; + m_mid_buf[0] = 0; + m_L0_buf[0] = m_price[0]; + m_L1_buf[0] = m_price[0]; + m_L2_buf[0] = m_price[0]; + m_L3_buf[0] = m_price[0]; + m_filter_buf[0] = m_price[0]; + output_buffer[0] = m_price[0]; + i = 1; + } + + for(; i < rates_total; i++) + { + // --- Step A: Calculate Diff --- + // diff = abs(price - prev_filter) + double prev_F = m_filter_buf[i-1]; + m_diff_buf[i] = MathAbs(m_price[i] - prev_F); + + // --- Step B: Calculate Alpha (Gamma) --- + double alpha = 0.5; // Default fallback + + if(i >= m_period1) + { + double hh = GetHighest(m_diff_buf, i, m_period1); + double ll = GetLowest(m_diff_buf, i, m_period1); + + double mid = 0; + if(hh - ll != 0) + mid = (m_diff_buf[i] - ll) / (hh - ll); + + m_mid_buf[i] = mid; + + if(i >= m_period2) + { + alpha = GetMedian(m_mid_buf, i, m_period2); + } + } + else + { + m_mid_buf[i] = 0; + } + + // --- Step C: Laguerre Filter with dynamic Alpha --- + double L0_prev = m_L0_buf[i-1]; + double L1_prev = m_L1_buf[i-1]; + double L2_prev = m_L2_buf[i-1]; + double L3_prev = m_L3_buf[i-1]; + + m_L0_buf[i] = alpha * m_price[i] + (1 - alpha) * L0_prev; + m_L1_buf[i] = -(1 - alpha) * m_L0_buf[i] + L0_prev + (1 - alpha) * L1_prev; + m_L2_buf[i] = -(1 - alpha) * m_L1_buf[i] + L1_prev + (1 - alpha) * L2_prev; + m_L3_buf[i] = -(1 - alpha) * m_L2_buf[i] + L2_prev + (1 - alpha) * L3_prev; + + double filt = (m_L0_buf[i] + 2.0 * m_L1_buf[i] + 2.0 * m_L2_buf[i] + m_L3_buf[i]) / 6.0; + + m_filter_buf[i] = filt; + output_buffer[i] = filt; + } + } + +//+------------------------------------------------------------------+ +//| Helpers | +//+------------------------------------------------------------------+ +double CLaguerreFilterVolatilityCalculator::GetHighest(const double &arr[], int start_idx, int len) + { + double max_val = arr[start_idx]; + for(int k=1; k max_val) + max_val = arr[start_idx-k]; + return max_val; + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +double CLaguerreFilterVolatilityCalculator::GetLowest(const double &arr[], int start_idx, int len) + { + double min_val = arr[start_idx]; + for(int k=1; k