From 005fb92efd9302f3cb58aa318f002c76103f3058 Mon Sep 17 00:00:00 2001 From: Toh4iem9 Date: Mon, 15 Jun 2026 20:08:03 +0200 Subject: [PATCH] refactor: Integrated retroactive temporal SOT wave coloring --- .../WeisWave_Duration_Calculator.mqh | 145 +++++++++++++----- 1 file changed, 107 insertions(+), 38 deletions(-) diff --git a/Include/MyIncludes/WeisWave_Duration_Calculator.mqh b/Include/MyIncludes/WeisWave_Duration_Calculator.mqh index d2edae6..636b2dc 100644 --- a/Include/MyIncludes/WeisWave_Duration_Calculator.mqh +++ b/Include/MyIncludes/WeisWave_Duration_Calculator.mqh @@ -1,11 +1,11 @@ //+------------------------------------------------------------------+ //| WeisWave_Duration_Calculator.mqh| -//| Engine for Non-Repainting Weis Wave Duration (Time/Bars). | +//| Engine for Non-Repainting Weis Wave Duration with SOT. | //| Strictly O(1) Incremental Optimized. | //| Copyright 2026, xxxxxxxx | //+------------------------------------------------------------------+ #property copyright "Copyright 2026, xxxxxxxx" -#property version "1.10" // Fully commented and documented optimization structures +#property version "1.10" // Integrated retroactive temporal SOT wave coloring #ifndef WEISWAVE_DURATION_CALCULATOR_MQH #define WEISWAVE_DURATION_CALCULATOR_MQH @@ -19,13 +19,14 @@ private: int m_atr_period; double m_multiplier; - //--- Stateful persistent arrays for O(1) memory caching (Prevents Repainting) + //--- Stateful arrays to prevent repainting (O(1) state preservation) int m_direction[]; - int m_wave_dur[]; // Running bar count of the active wave - double m_peak_high[]; // Locks the peak high of the active up-wave - double m_peak_low[]; // Locks the trough low of the active down-wave + int m_wave_dur[]; // Running bar count of active wave + double m_peak_high[]; + double m_peak_low[]; double GetATR(int i, const double &high[], const double &low[], const double &close[]); + bool GetLastCompletedDurations(int current_idx, int target_dir, double &out_durs[]); public: CWeisWaveDurationCalculator(); @@ -34,7 +35,7 @@ public: bool Init(int atr_period, double multiplier); void Calculate(int rates_total, int prev_calculated, const double &high[], const double &low[], const double &close[], - double &out_wave_dur[], double &out_colors[]); + double &out_wave_dur[], double &out_colors[], bool show_sot=true); }; //+------------------------------------------------------------------+ @@ -57,12 +58,12 @@ bool CWeisWaveDurationCalculator::Init(int atr_period, double multiplier) //+------------------------------------------------------------------+ void CWeisWaveDurationCalculator::Calculate(int rates_total, int prev_calculated, const double &high[], const double &low[], const double &close[], - double &out_wave_dur[], double &out_colors[]) + double &out_wave_dur[], double &out_colors[], bool show_sot) { - if(rates_total < m_atr_period + 5) + if(rates_total < m_atr_period + 10) return; -//--- Dynamic array allocation: resized ONLY when bar count changes (ultra-fast) +//--- Sync state arrays with rates_total if(ArraySize(m_direction) != rates_total) { ArrayResize(m_direction, rates_total); @@ -71,16 +72,13 @@ void CWeisWaveDurationCalculator::Calculate(int rates_total, int prev_calculated ArrayResize(m_peak_low, rates_total); } -//--- O(1) Optimization: Determine the exact starting index -//--- On first run (prev_calculated == 0), start is 0 (full historical calculation) -//--- On subsequent live ticks, start is rates_total - 1 (calculates only the current forming bar) int start = (prev_calculated == 0) ? 0 : prev_calculated - 1; -//--- First bar initialization +//--- Initialization for the very first bar if(start == 0) { - m_direction[0] = 1; - m_wave_dur[0] = 1; + m_direction[0] = 1; // Default to Up wave + m_wave_dur[0] = 1; // Starting with 1 bar duration m_peak_high[0] = high[0]; m_peak_low[0] = low[0]; @@ -89,10 +87,9 @@ void CWeisWaveDurationCalculator::Calculate(int rates_total, int prev_calculated start = 1; } -//--- Stateful main calculation loop +//--- Stateful main loop for(int i = start; i < rates_total; i++) { - //--- Read locked states of the previous bar (i-1) to eliminate loop recalculations int prev_dir = m_direction[i-1]; int prev_dur = m_wave_dur[i-1]; double prev_hi = m_peak_high[i-1]; @@ -101,54 +98,126 @@ void CWeisWaveDurationCalculator::Calculate(int rates_total, int prev_calculated double atr = GetATR(i, high, low, close); double threshold = m_multiplier * atr; - //--- Set default state assumptions from previous bar m_direction[i] = prev_dir; m_peak_high[i] = prev_hi; m_peak_low[i] = prev_lo; if(prev_dir == 1) // Active UP Swing { - m_wave_dur[i] = prev_dur + 1; // Increment duration + m_wave_dur[i] = prev_dur + 1; // Increment duration count m_peak_high[i] = MathMax(prev_hi, high[i]); - // Reversal Check: If close price drops below threshold, reset and reverse + // Default visual outputs + out_wave_dur[i] = (double)m_wave_dur[i]; + out_colors[i] = 0.0; // Index 0: DodgerBlue (Normal Up) + + // Check for Reversal to Down Swing if(close[i] < m_peak_high[i] - threshold) { m_direction[i] = -1; - m_wave_dur[i] = 1; // Reset duration to 1 for the new wave + m_wave_dur[i] = 1; // Reset duration count for new wave m_peak_low[i] = low[i]; + + out_wave_dur[i] = -1.0; + out_colors[i] = 1.0; // Index 1: Crimson (Normal Down) + + //--- SOT Check: If show_sot is enabled, verify the completed Up wave (at index i-1) + if(show_sot) + { + double h_durs[3]; + if(GetLastCompletedDurations(i - 1, 1, h_durs)) + { + if(h_durs[0] < h_durs[1] && h_durs[1] < h_durs[2]) + { + // Retroactively color the entire completed Up wave to Index 2 (Orange) + for(int k = i - 1; k >= 0; k--) + { + if(m_direction[k] == 1) + out_colors[k] = 2.0; // SOT Up Wave Color (Orange) + else + break; + } + } + } + } } } else // Active DOWN Swing { - m_wave_dur[i] = prev_dur + 1; // Increment duration + m_wave_dur[i] = prev_dur + 1; // Increment duration count m_peak_low[i] = MathMin(prev_lo, low[i]); - // Reversal Check: If close price rises above threshold, reset and reverse + // Default visual outputs + out_wave_dur[i] = -(double)m_wave_dur[i]; + out_colors[i] = 1.0; // Index 1: Crimson (Normal Down) + + // Check for Reversal to Up Swing if(close[i] > m_peak_low[i] + threshold) { m_direction[i] = 1; - m_wave_dur[i] = 1; // Reset duration to 1 for the new wave + m_wave_dur[i] = 1; // Reset duration count for new wave m_peak_high[i] = high[i]; - } - } - //--- Render calculated state to indicator output buffers - if(m_direction[i] == 1) - { - out_wave_dur[i] = (double)m_wave_dur[i]; // Up wave is positive - out_colors[i] = 0.0; // Color Index 0 (DodgerBlue) - } - else - { - out_wave_dur[i] = -(double)m_wave_dur[i]; // Down wave is negative - out_colors[i] = 1.0; // Color Index 1 (Crimson) + out_wave_dur[i] = 1.0; + out_colors[i] = 0.0; // Index 0: DodgerBlue (Normal Up) + + //--- SOT Check: If show_sot is enabled, verify the completed Down wave (at index i-1) + if(show_sot) + { + double l_durs[3]; + if(GetLastCompletedDurations(i - 1, -1, l_durs)) + { + if(l_durs[0] < l_durs[1] && l_durs[1] < l_durs[2]) + { + // Retroactively color the entire completed Down wave to Index 3 (Fuchsia) + for(int k = i - 1; k >= 0; k--) + { + if(m_direction[k] == -1) + out_colors[k] = 3.0; // SOT Down Wave Color (Fuchsia) + else + break; + } + } + } + } + } } } } //+------------------------------------------------------------------+ -//| GetATR (Self-contained rolling ATR calculation) | +//| GetLastCompletedDurations (Historical state backward-search) | +//+------------------------------------------------------------------+ +bool CWeisWaveDurationCalculator::GetLastCompletedDurations(int current_idx, int target_dir, double &out_durs[]) + { + int found = 0; + bool in_target_wave = false; + ArrayInitialize(out_durs, 0.0); + + for(int j = current_idx; j >= 0; j--) + { + int dir = m_direction[j]; + if(dir == target_dir) + { + if(!in_target_wave) + { + in_target_wave = true; + out_durs[found] = (double)m_wave_dur[j]; // Capture locked final wave duration + found++; + if(found >= 3) + return true; + } + } + else + { + in_target_wave = false; + } + } + return (found >= 3); + } + +//+------------------------------------------------------------------+ +//| GetATR | //+------------------------------------------------------------------+ double CWeisWaveDurationCalculator::GetATR(int i, const double &high[], const double &low[], const double &close[]) {