346 lines
10 KiB
MQL5
346 lines
10 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| EAEvents.mqh |
|
|
//| Copyright 2025, Your Company Name |
|
|
//| https://www.yoursite.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2025, Your Company Name"
|
|
#property link "https://www.yoursite.com"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
#include <Arrays\ArrayObj.mqh>
|
|
#include "EALogger.mqh"
|
|
#include "EAState.mqh"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Event types |
|
|
//+------------------------------------------------------------------+
|
|
enum ENUM_EVENT_TYPE
|
|
{
|
|
EVENT_TICK, // New tick event
|
|
EVENT_TIMER, // Timer event
|
|
EVENT_TRADE, // Trade event
|
|
EVENT_ORDER, // Order event
|
|
EVENT_POSITION, // Position event
|
|
EVENT_SIGNAL // Signal event
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Base event class |
|
|
//+------------------------------------------------------------------+
|
|
class CBaseEvent : public CObject
|
|
{
|
|
protected:
|
|
ENUM_EVENT_TYPE m_type; // Event type
|
|
ulong m_id; // Event ID
|
|
datetime m_time; // Event time
|
|
|
|
public:
|
|
// Constructor
|
|
CBaseEvent(ENUM_EVENT_TYPE type) : m_type(type), m_id(0), m_time(0)
|
|
{
|
|
m_time = TimeCurrent();
|
|
}
|
|
|
|
// Getters
|
|
ENUM_EVENT_TYPE Type() const { return m_type; }
|
|
ulong Id() const { return m_id; }
|
|
datetime Time() const { return m_time; }
|
|
|
|
// Virtual methods
|
|
virtual bool Process() = 0;
|
|
virtual string ToString() const = 0;
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Tick event |
|
|
//+------------------------------------------------------------------+
|
|
class CTickEvent : public CBaseEvent
|
|
{
|
|
private:
|
|
MqlTick m_tick;
|
|
|
|
public:
|
|
CTickEvent() : CBaseEvent(EVENT_TICK) {}
|
|
|
|
bool Process()
|
|
{
|
|
// Process tick event
|
|
if (!SymbolInfoTick(Symbol(), m_tick))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
string ToString() const { return StringFormat("Tick: %s %.5f", TimeToString(m_tick.time), m_tick.last); }
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Timer event |
|
|
//+------------------------------------------------------------------+
|
|
class CTimerEvent : public CBaseEvent
|
|
{
|
|
public:
|
|
CTimerEvent() : CBaseEvent(EVENT_TIMER) {}
|
|
|
|
bool Process()
|
|
{
|
|
// Process timer event
|
|
return true;
|
|
}
|
|
|
|
string ToString() const { return "Timer: " + TimeToString(Time()); }
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Trade event |
|
|
//+------------------------------------------------------------------+
|
|
class CTradeEvent : public CBaseEvent
|
|
{
|
|
private:
|
|
ENUM_TRADE_EVENT m_tradeEvent;
|
|
|
|
public:
|
|
CTradeEvent(ENUM_TRADE_EVENT event) : CBaseEvent(EVENT_TRADE), m_tradeEvent(event) {}
|
|
|
|
bool Process()
|
|
{
|
|
// Process trade event
|
|
return true;
|
|
}
|
|
|
|
string ToString() const { return "Trade: " + EnumToString(m_tradeEvent); }
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Event queue |
|
|
//+------------------------------------------------------------------+
|
|
class CEventQueue
|
|
{
|
|
private:
|
|
CArrayObj* m_events; // Event queue
|
|
int m_maxSize; // Maximum queue size
|
|
|
|
public:
|
|
CEventQueue(int maxSize = 1000) : m_maxSize(maxSize)
|
|
{
|
|
m_events = new CArrayObj();
|
|
}
|
|
|
|
~CEventQueue()
|
|
{
|
|
if (m_events != NULL)
|
|
{
|
|
m_events.Clear();
|
|
delete m_events;
|
|
}
|
|
}
|
|
|
|
bool Enqueue(CBaseEvent* event)
|
|
{
|
|
if (m_events.Total() >= m_maxSize)
|
|
return false;
|
|
|
|
return m_events.Add(event);
|
|
}
|
|
|
|
CBaseEvent* Dequeue()
|
|
{
|
|
if (m_events.Total() == 0)
|
|
return NULL;
|
|
|
|
CBaseEvent* event = m_events.At(0);
|
|
m_events.Delete(0);
|
|
return event;
|
|
}
|
|
|
|
int Size() const { return m_events.Total(); }
|
|
bool IsEmpty() const { return m_events.Total() == 0; }
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Event manager |
|
|
//+------------------------------------------------------------------+
|
|
class CEAEvents
|
|
{
|
|
private:
|
|
CEventQueue* m_eventQueue; // Event queue
|
|
CEALogger* m_logger; // Logger instance
|
|
CEAState* m_state; // State manager
|
|
|
|
// Event handlers
|
|
bool ProcessTickEvent(CBaseEvent* event);
|
|
bool ProcessTimerEvent(CBaseEvent* event);
|
|
bool ProcessTradeEvent(CBaseEvent* event);
|
|
|
|
public:
|
|
CEAEvents() : m_eventQueue(NULL), m_logger(NULL), m_state(NULL) {}
|
|
~CEAEvents() { Deinitialize(); }
|
|
|
|
bool Initialize(CEALogger* logger, CEAState* state);
|
|
void Deinitialize();
|
|
|
|
// Event processing
|
|
bool ProcessTick();
|
|
bool ProcessTimer();
|
|
bool ProcessTrade();
|
|
|
|
// Event generation
|
|
bool GenerateTickEvent();
|
|
bool GenerateTimerEvent();
|
|
bool GenerateTradeEvent(ENUM_TRADE_EVENT event);
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Initialize event system |
|
|
//+------------------------------------------------------------------+
|
|
bool CEAEvents::Initialize(CEALogger* logger, CEAState* state)
|
|
{
|
|
if (logger == NULL || state == NULL)
|
|
return false;
|
|
|
|
m_logger = logger;
|
|
m_state = state;
|
|
m_eventQueue = new CEventQueue();
|
|
|
|
m_logger.LogInfo("Event system initialized");
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Deinitialize event system |
|
|
//+------------------------------------------------------------------+
|
|
void CEAEvents::Deinitialize()
|
|
{
|
|
if (m_eventQueue != NULL)
|
|
{
|
|
delete m_eventQueue;
|
|
m_eventQueue = NULL;
|
|
}
|
|
|
|
m_logger = NULL;
|
|
m_state = NULL;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Process tick event |
|
|
//+------------------------------------------------------------------+
|
|
bool CEAEvents::ProcessTick()
|
|
{
|
|
// Process all pending events
|
|
while (!m_eventQueue.IsEmpty())
|
|
{
|
|
CBaseEvent* event = m_eventQueue.Dequeue();
|
|
if (event == NULL)
|
|
continue;
|
|
|
|
bool result = false;
|
|
|
|
switch (event.Type())
|
|
{
|
|
case EVENT_TICK: result = ProcessTickEvent(event); break;
|
|
case EVENT_TIMER: result = ProcessTimerEvent(event); break;
|
|
case EVENT_TRADE: result = ProcessTradeEvent(event); break;
|
|
default: break;
|
|
}
|
|
|
|
delete event;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Process timer event |
|
|
//+------------------------------------------------------------------+
|
|
bool CEAEvents::ProcessTimer()
|
|
{
|
|
// Process timer-based events
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Process trade event |
|
|
//+------------------------------------------------------------------+
|
|
bool CEAEvents::ProcessTrade()
|
|
{
|
|
// Process trade-related events
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Process tick event |
|
|
//+------------------------------------------------------------------+
|
|
bool CEAEvents::ProcessTickEvent(CBaseEvent* event)
|
|
{
|
|
if (event.Type() != EVENT_TICK)
|
|
return false;
|
|
|
|
CTickEvent* tick = (CTickEvent*)event;
|
|
|
|
// Update state with new tick data
|
|
if (m_state != NULL)
|
|
m_state->UpdateLastTick(tick);
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Process timer event |
|
|
//+------------------------------------------------------------------+
|
|
bool CEAEvents::ProcessTimerEvent(CBaseEvent* event)
|
|
{
|
|
if (event.Type() != EVENT_TIMER)
|
|
return false;
|
|
|
|
// Process timer-based tasks
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Process trade event |
|
|
//+------------------------------------------------------------------+
|
|
bool CEAEvents::ProcessTradeEvent(CBaseEvent* event)
|
|
{
|
|
if (event.Type() != EVENT_TRADE)
|
|
return false;
|
|
|
|
// Process trade events
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Generate tick event |
|
|
//+------------------------------------------------------------------+
|
|
bool CEAEvents::GenerateTickEvent()
|
|
{
|
|
if (m_eventQueue == NULL)
|
|
return false;
|
|
|
|
CTickEvent* event = new CTickEvent();
|
|
return m_eventQueue.Enqueue(event);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Generate timer event |
|
|
//+------------------------------------------------------------------+
|
|
bool CEAEvents::GenerateTimerEvent()
|
|
{
|
|
if (m_eventQueue == NULL)
|
|
return false;
|
|
|
|
CTimerEvent* event = new CTimerEvent();
|
|
return m_eventQueue.Enqueue(event);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Generate trade event |
|
|
//+------------------------------------------------------------------+
|
|
bool CEAEvents::GenerateTradeEvent(ENUM_TRADE_EVENT event)
|
|
{
|
|
if (m_eventQueue == NULL)
|
|
return false;
|
|
|
|
CTradeEvent* tradeEvent = new CTradeEvent(event);
|
|
return m_eventQueue.Enqueue(tradeEvent);
|
|
}
|