mql5/Experts/_Architecture/ProcessController.mqh
younglubah-gmail 3e91e83c65
2026-08-14 16:18:08 +02:00

135 lines
No EOL
4.4 KiB
MQL5

//+------------------------------------------------------------------+
//| ProcessController.mqh |
//| Copyright 2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
// ProcessController.mqh
#include "Market/DataManager.mqh"
#include "Analysers/IAnalyser.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class ProcessController final
{
private:
DataManager* m_data;
IAnalyser* m_chapters[];
int m_chapterCount;
EventBus* m_eventBus;
// Time‑based tracking – one entry per symbol/tf (same order as rawData)
datetime m_lastProcessedTime[];
int m_seriesCount;
// Launch progress (used only during initial replay)
int m_launchProgress[]; // bar index for each series
void RunAllChapters(TfBarSeries &series, int barIndex)
{
for(int c = 0; c < m_chapterCount; c++)
m_chapters[c].ProcessBar(series, barIndex);
}
public:
ProcessController() : m_data(NULL), m_chapterCount(0), m_seriesCount(0) {}
void Initialize(EventBus* eventBus, DataManager &dm)
{
m_eventBus = eventBus;
m_data = &dm;
}
void AddChapter(IAnalyser* chapter, EventBus* _eventBus)
{
int sz = ArraySize(m_chapters);
ArrayResize(m_chapters, sz + 1);
chapter.Init(_eventBus);
m_chapters[sz] = chapter;
m_chapterCount = sz + 1;
}
//---------------------------------------------------------------
// Launch – replay all historical bars through every chapter
//---------------------------------------------------------------
void ProcessController::Launch()
{
if(m_data == NULL) return;
CArrayList<TfBarSeries*>* rawData = m_data.GetRawData(); // pointer to list
int totalSeries = rawData.Size();
ArrayResize(m_launchProgress, totalSeries);
ArrayResize(m_lastProcessedTime, totalSeries);
for(int i = 0; i < totalSeries; i++)
{
m_launchProgress[i] = 0;
m_lastProcessedTime[i] = 0;
}
m_seriesCount = totalSeries;
for(int i = 0; i < totalSeries; i++)
{
TfBarSeries* series = rawData.At(i); // pointer
int total = series.TotalBars();
for(int barIdx = 0; barIdx < total; barIdx++)
RunAllChapters(*series, barIdx);
if(total > 0)
m_lastProcessedTime[i] = series.Time(total - 1);
}
}
//---------------------------------------------------------------
// Update – process only newly arrived bars using time comparison
//---------------------------------------------------------------
void Update()
{
if(m_data == NULL) return;
CArrayList<TfBarSeries*>* rawData = m_data.GetRawData();
int totalSeries = rawData.Size();
if(totalSeries > m_seriesCount)
{
ArrayResize(m_lastProcessedTime, totalSeries);
for(int i = m_seriesCount; i < totalSeries; i++)
m_lastProcessedTime[i] = 0;
m_seriesCount = totalSeries;
}
for(int i = 0; i < totalSeries; i++)
{
TfBarSeries* series = rawData.At(i);
int total = series.TotalBars();
if(total == 0) continue;
datetime latestBarTime = series.Time(total - 1);
if(latestBarTime <= m_lastProcessedTime[i]) continue;
for(int barIdx = 0; barIdx < total; barIdx++)
if(series.Time(barIdx) > m_lastProcessedTime[i])
RunAllChapters(*series, barIdx);
m_lastProcessedTime[i] = latestBarTime;
}
}
void RelaunchSeries(int index);
};
void ProcessController::RelaunchSeries(int index)
{
TfBarSeries* series = m_data.GetRawData().At(index); // pointer
for(int c = 0; c < m_chapterCount; c++)
m_chapters[c].Reset(series.symbol, series.tf);
m_lastProcessedTime[index] = 0;
int total = series.TotalBars();
for(int barIdx = 0; barIdx < total; barIdx++)
RunAllChapters(*series, barIdx);
if(total > 0)
m_lastProcessedTime[index] = series.Time(total - 1);
}