ictCore/Experts/core/common.mqh
nazgul 9e8ce6a0ee core: refactor into bounded, symbol-agnostic building blocks
Same code as the luvinga repo's Include/core (commit "Refactor core/ ...").

- common.mqh (new): as-series contract, CRing<T>
- session.mqh: now implemented (was declarations only); force-added because
  Experts/core is listed in .gitignore
- candlesticks/swings/marketWatchFilter: no more input variables in headers;
  use configure() / constructor arguments
- orderflow, fvg, equilibrium: multi-symbol safe, bug fixes

Breaking: bots that relied on inpWatchTimeframe from marketWatchFilter.mqh
(preReleasedBots/ttrades.mq5) must now declare that input themselves.
signalLab.mqh is untouched by this commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 21:47:19 +03:00

76 lines
2.8 KiB
MQL5

#ifndef CORE_COMMON_MQH
#define CORE_COMMON_MQH
//+------------------------------------------------------------------+
//| common.mqh - conventions and the one data structure core/ shares |
//| |
//| Contract for every core/*.mqh: |
//| - rates[] is AS-SERIES: [0] = forming bar, [1] = last closed |
//| bar, higher index = older. Callers do CopyRates() then |
//| ArraySetAsSeries(rates, true). |
//| - Nothing reads globals or chart state. Data comes in by |
//| argument, so any symbol/timeframe can be scanned. |
//| - Direction flags are ints: +1 bullish, -1 bearish, 0 none. |
//| - Memory is bounded: history lives in CRing, never in a |
//| structure that grows per tick. |
//| - update() methods are safe to call every tick; they act once |
//| per new closed bar. |
//+------------------------------------------------------------------+
//--- true when rates[] is as-series and holds at least minBars bars
bool CoreSeriesReady(const MqlRates &rates[], const int minBars)
{
return ArrayGetAsSeries(rates) && ArraySize(rates) >= minBars;
}
//+------------------------------------------------------------------+
//| CRing<T> - fixed-capacity ring buffer |
//| Push O(1), evicts the oldest entry when full |
//| At O(1), pos 0 = newest, Count()-1 = oldest |
//+------------------------------------------------------------------+
template<typename T>
class CRing
{
private:
T m_buf[];
int m_cap;
int m_head; // slot of the NEXT write
int m_count; // valid entries, never above m_cap
public:
CRing() : m_cap(0), m_head(0), m_count(0) {}
bool Init(const int capacity)
{
if(capacity <= 0 || ArrayResize(m_buf, capacity) != capacity)
return false;
m_cap = capacity;
m_head = 0;
m_count = 0;
return true;
}
void Clear() { m_head = 0; m_count = 0; }
int Count() const { return m_count; }
int Capacity() const { return m_cap; }
bool Push(const T &value)
{
if(m_cap == 0)
return false;
m_buf[m_head] = value;
m_head = (m_head + 1) % m_cap;
if(m_count < m_cap)
m_count++;
return true;
}
bool At(const int pos, T &out) const
{
if(pos < 0 || pos >= m_count)
return false;
out = m_buf[(m_head - 1 - pos + m_cap) % m_cap];
return true;
}
};
#endif // CORE_COMMON_MQH