//+------------------------------------------------------------------+ //| Events.mqh | //| Niquel y Leo, Copyright 2025. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Niquel y Leo, Copyright 2025" #property link "https://www.mql5.com" #property strict #ifndef MQLARTICLES_UTILS_FA_EVENTS_MQH #define MQLARTICLES_UTILS_FA_EVENTS_MQH //+------------------------------------------------------------------+ //| Include | //+------------------------------------------------------------------+ #include "Managers.mqh" //+------------------------------------------------------------------+ //| Clase base para los eventos basicos | //+------------------------------------------------------------------+ class CAllClassEventsBasic : public CSpecializedManager { protected: bool m_is_global; int m_hijos_events_valid_idx[]; int m_hijos_events_valid_idx_size; //--- Impidimos la instanciacion solo ptr.. pero se debe de asignar.. CAllClassEventsBasic(const bool& is_g) : m_is_global(is_g), m_hijos_events_valid_idx_size(0) {} //--- Ocultamos void AddLogger(CLoggerBase* _logger, bool is_all_class); void AddLogger(CLoggerBase &_logger, bool is_all_class); bool RemoveLogger(CLoggerBase* _logger); //--- void CleanItems(const string &den_name) override final; void CleanItemsNoDelete(const string& den_name) override final; public: ~CAllClassEventsBasic() {} //--- void __SetGlobal(bool is_global); //--- __forceinline bool IsGlobalInstance() { return m_is_global; } //--- Eventos basicos // Nota: Estos eventos son los basicos virtual void OnNewDay(const datetime& curr_time) {} virtual void OnNewWeek(const datetime& curr_time) {} virtual void OnNewMonth(const datetime& curr_time) {} }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CAllClassEventsBasic::CleanItems(const string &den_name) { m_hijos_events_valid_idx_size = ArrayResize(m_hijos_events_valid_idx, 0); CSpecializedManager::CleanItems(den_name); } //+------------------------------------------------------------------+ void CAllClassEventsBasic::CleanItemsNoDelete(const string &den_name) { m_hijos_events_valid_idx_size = ArrayResize(m_hijos_events_valid_idx, 0); CSpecializedManager::CleanItemsNoDelete(den_name); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CAllClassEventsBasic::AddLogger(CLoggerBase* _logger, bool is_all_class) { //--- if(!CheckPointer(_logger)) { LogFatalError("El puntero *_logger es inválido", FUNCION_ACTUAL); return; } //--- m_loggers[ArrayResize(m_loggers, (++m_loggers_total)) - 1] = _logger; //--- if(is_all_class) m_hijos_events_valid_idx[ArrayResize(m_hijos_events_valid_idx, (++m_hijos_events_valid_idx_size)) - 1] = (m_loggers_total - 1); //--- _logger.AddLogFlags(LogFlags()); } //+------------------------------------------------------------------+ __forceinline void CAllClassEventsBasic::AddLogger(CLoggerBase &_logger, bool is_all_class) { AddLogger(GetPointer(_logger), is_all_class); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ /* - [L1, L2, L3, L4, L5, L6, L7, L8] 0 3 5 7 - Eliminar L4 - [L1, L2, L3, L8, L5, L6, L7] 0 3 5 - [0, 3, 7, 5] - [0, 5, 7] - [0, 5, 3] L1, L8, - El orden no improta... aqui eliminamos usando find + swap */ bool CAllClassEventsBasic::RemoveLogger(CLoggerBase* _logger) { //--- if(!CheckPointer(_logger)) { LogError("Se esta removiendo un logger NULL", FUNCION_ACTUAL); } //--- for(int i = 0; i < m_loggers_total; i++) { if(m_loggers[i] == _logger) { //--- const int last_idx = --m_loggers_total; m_loggers[i] = m_loggers[last_idx]; ArrayResize(m_loggers, m_loggers_total); //--- for(int k = 0; k < m_hijos_events_valid_idx_size; k++) { if(m_hijos_events_valid_idx[k] == i) { m_hijos_events_valid_idx[k] = m_hijos_events_valid_idx[--m_hijos_events_valid_idx_size]; ArrayResize(m_hijos_events_valid_idx, m_hijos_events_valid_idx_size); k--; } else if(m_hijos_events_valid_idx[k] == last_idx) { m_hijos_events_valid_idx[k] = i; } } //--- LogInfo(StringFormat("Logger en índice %d removido. Total restante: %d", i, m_loggers_total), FUNCION_ACTUAL); //--- return true; } } //--- LogWarning("Logger no encontrado para remover", FUNCION_ACTUAL); return false; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CAllClassEventsBasic::__SetGlobal(bool is_global) { m_is_global = is_global; for(int k = 0; k < m_hijos_events_valid_idx_size; k++) ((CAllClassEventsBasic*)m_loggers[m_hijos_events_valid_idx[k]]).__SetGlobal(is_global); } //+------------------------------------------------------------------+ //| Clase base para los eventos | //+------------------------------------------------------------------+ #define BASICEVENT_REG_FLAG_ON_NEW_DAY (1) #define BASICEVENT_REG_FLAG_ON_NEW_WEEK (2) #define BASICEVENT_REG_FLAG_ON_NEW_MON (4) //--- #define BASICEVENT_REG_ALL_FLAG (BASICEVENT_REG_FLAG_ON_NEW_DAY|BASICEVENT_REG_FLAG_ON_NEW_WEEK|BASICEVENT_REG_FLAG_ON_NEW_MON) //--- class CBasicEvents { private: static CAllClassEventsBasic* m_on_new_day[]; static int m_on_new_day_size; static CAllClassEventsBasic* m_on_new_week[]; static int m_on_new_week_size; static CAllClassEventsBasic* m_on_new_mon[]; static int m_on_new_mon_size; //--- static void RemoveFromArrayFast(CAllClassEventsBasic* &array[], int &size, CAllClassEventsBasic* &ptr); public: CBasicEvents(void) {} ~CBasicEvents(void) {} //--- Registrar static void Register(CAllClassEventsBasic* ptr, const uint8_t flags); static void RegisterEvent(CAllClassEventsBasic* ptr, const uint8_t event); static void Unregister(CAllClassEventsBasic* ptr, const uint8_t flags); static void UnregisterEvent(CAllClassEventsBasic* ptr, const uint8_t event); //--- Eventos static void OnNewDay(const datetime& curr_time); static void OnNewWeek(const datetime& curr_time); static void OnNewMonth(const datetime& curr_time); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void CBasicEvents::RemoveFromArrayFast(CAllClassEventsBasic* &array[], int &size, CAllClassEventsBasic* &ptr) { for(int i = 0; i < size; i++) { if(array[i] == ptr) { array[i] = array[size - 1]; ArrayResize(array, --size); return; } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void CBasicEvents::Unregister(CAllClassEventsBasic* ptr, const uint8_t flags) { if(!CheckPointer(ptr)) { FastLog(FUNCION_ACTUAL, WARNING_TEXT, "Invalid pointer for unregister"); return; } //--- OnNewDay if((flags & BASICEVENT_REG_FLAG_ON_NEW_DAY) != 0) RemoveFromArrayFast(m_on_new_day, m_on_new_day_size, ptr); //--- OnNewWeek if((flags & BASICEVENT_REG_FLAG_ON_NEW_WEEK) != 0) RemoveFromArrayFast(m_on_new_week, m_on_new_week_size, ptr); //--- OnNewMonth if((flags & BASICEVENT_REG_FLAG_ON_NEW_MON) != 0) RemoveFromArrayFast(m_on_new_mon, m_on_new_mon_size, ptr); } //+------------------------------------------------------------------+ static void CBasicEvents::UnregisterEvent(CAllClassEventsBasic *ptr, const uchar event) { if(!CheckPointer(ptr)) { FastLog(FUNCION_ACTUAL, WARNING_TEXT, "Invalid pointer for unregister"); return; } //--- OnNewDay if(event == BASICEVENT_REG_FLAG_ON_NEW_DAY) RemoveFromArrayFast(m_on_new_day, m_on_new_day_size, ptr); //--- OnNewWeek else if(event == BASICEVENT_REG_FLAG_ON_NEW_WEEK) RemoveFromArrayFast(m_on_new_week, m_on_new_week_size, ptr); //--- OnNewMonth else if(event == BASICEVENT_REG_FLAG_ON_NEW_MON) RemoveFromArrayFast(m_on_new_mon, m_on_new_mon_size, ptr); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void CBasicEvents::RegisterEvent(CAllClassEventsBasic *ptr, const uchar event) { //--- if(!CheckPointer(ptr)) { FastLog(FUNCION_ACTUAL, FATAL_ERROR_TEXT, "No se puede registrar puntos invalidos"); Remover(); return; } //--- if(event == BASICEVENT_REG_FLAG_ON_NEW_DAY) { m_on_new_day[ArrayResize(m_on_new_day, (++m_on_new_day_size)) - 1 ] = ptr; } //--- else if(event == BASICEVENT_REG_FLAG_ON_NEW_WEEK) { m_on_new_week[ArrayResize(m_on_new_week, (++m_on_new_week_size)) - 1 ] = ptr; } //--- else if(event == BASICEVENT_REG_FLAG_ON_NEW_MON) { m_on_new_mon[ArrayResize(m_on_new_mon, (++m_on_new_mon_size)) - 1 ] = ptr; } } //+------------------------------------------------------------------+ static void CBasicEvents::Register(CAllClassEventsBasic *ptr, const uint8_t flags) { //--- if(!CheckPointer(ptr)) { FastLog(FUNCION_ACTUAL, FATAL_ERROR_TEXT, "No se puede registrar puntos invalidos"); Remover(); return; } //--- if((flags & BASICEVENT_REG_FLAG_ON_NEW_DAY) != 0) { m_on_new_day[ArrayResize(m_on_new_day, (++m_on_new_day_size)) - 1 ] = ptr; } //--- if((flags & BASICEVENT_REG_FLAG_ON_NEW_WEEK) != 0) { m_on_new_week[ArrayResize(m_on_new_week, (++m_on_new_week_size)) - 1 ] = ptr; } //--- if((flags & BASICEVENT_REG_FLAG_ON_NEW_MON) != 0) { m_on_new_mon[ArrayResize(m_on_new_mon, (++m_on_new_mon_size)) - 1 ] = ptr; } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void CBasicEvents::OnNewDay(const datetime& curr_time) { for(int i = 0; i < m_on_new_day_size; i++) { m_on_new_day[i].OnNewDay(curr_time); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void CBasicEvents::OnNewWeek(const datetime &curr_time) { for(int i = 0; i < m_on_new_week_size; i++) { m_on_new_week[i].OnNewWeek(curr_time); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void CBasicEvents::OnNewMonth(const datetime &curr_time) { for(int i = 0; i < m_on_new_mon_size; i++) { m_on_new_mon[i].OnNewMonth(curr_time); } } //+------------------------------------------------------------------+ CAllClassEventsBasic* CBasicEvents::m_on_new_day[] = {}; int CBasicEvents::m_on_new_day_size = 0; //--- CAllClassEventsBasic* CBasicEvents::m_on_new_week[] = {}; int CBasicEvents::m_on_new_week_size = 0; //--- CAllClassEventsBasic*CBasicEvents:: m_on_new_mon[] = {}; int CBasicEvents::m_on_new_mon_size = 0; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ /* ---------- Experts //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //| Timer function | //+------------------------------------------------------------------+ void OnTimer() { //--- } //+------------------------------------------------------------------+ //| Trade function | //+------------------------------------------------------------------+ void OnTrade() { //--- } //+------------------------------------------------------------------+ //| TradeTransaction function | //+------------------------------------------------------------------+ void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result) { //--- } //+------------------------------------------------------------------+ //| Tester function | //+------------------------------------------------------------------+ double OnTester() { //--- double ret=0.0; //--- //--- return(ret); } //+------------------------------------------------------------------+ //| TesterInit function | //+------------------------------------------------------------------+ void OnTesterInit() { //--- } //+------------------------------------------------------------------+ //| TesterPass function | //+------------------------------------------------------------------+ void OnTesterPass() { //--- } //+------------------------------------------------------------------+ //| TesterDeinit function | //+------------------------------------------------------------------+ void OnTesterDeinit() { //--- } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- } //+------------------------------------------------------------------+ //| BookEvent function | //+------------------------------------------------------------------+ void OnBookEvent(const string &symbol) { //--- } --- [L1, L2, L3, L4] [0, 2, 3] --- Eliminar L3 - [L1, L2, L4] Eliminar indice 2 - [0, 3] */ //+------------------------------------------------------------------+ #endif // MQLARTICLES_UTILS_FA_EVENTS_MQH