//+------------------------------------------------------------------+ //| BarWatcher.mqh | //| | //| KnitPkg for MetaTrader | //| | //| MIT License | //| Copyright (c) 2025 Douglas Rechia | //| | //| Bar change detector. Tracks new bar formation and provides | //| precise tick context information for event-driven logic. | //| | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| BarWatcher — detects new bars and first tick //+------------------------------------------------------------------+ class BarWatcher { private: string m_symbol; ENUM_TIMEFRAMES m_timeframe; datetime m_last_bar_time; bool m_first_update; bool m_first_tick; bool m_new_bar; public: // Constructor // symbol: symbol to monitor (NULL = current chart symbol) // timeframe: timeframe to monitor (PERIOD_CURRENT = current chart timeframe) BarWatcher(string symbol = NULL, ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT) { m_symbol = (symbol == "" || symbol == NULL) ? _Symbol : symbol; m_timeframe = (timeframe == 0) ? (ENUM_TIMEFRAMES)Period() : timeframe; m_first_update = true; m_first_tick = true; m_new_bar = false; m_last_bar_time = 0; } // Update internal state — call at the beginning of OnTick() void Update() { datetime current[]; if(CopyTime(m_symbol, m_timeframe, 0, 1, current) <= 0) return; if(m_first_update) { m_first_update = false; m_first_tick = true; m_last_bar_time = current[0]; return; } else { m_first_tick = false; } if(current[0] != m_last_bar_time) { m_last_bar_time = current[0]; m_new_bar = true; } else { m_new_bar = false; } } // Returns true only on the very first OnTick() call after initialization bool IsFirstTick() const { return m_first_tick; } // Returns true only on the first tick of a newly formed bar bool IsNewBar() const { return m_new_bar; } // Returns the open time of the current bar datetime CurrentBarTime() const { return m_last_bar_time; } // Reset internal state (useful for reinitialization) void Reset() { m_first_update = true; m_first_tick = true; m_new_bar = false; m_last_bar_time = 0; } }; //+------------------------------------------------------------------+