//+------------------------------------------------------------------+ //| Main.mqh | //| Copyright 2025, Niquel Mendoza. | //| https://www.mql5.com/es/users/nique_372 | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Niquel Mendoza." #property link "https://www.mql5.com/es/users/nique_372" #property strict #ifndef MQLARTICLES_UTILS_TFMANAGER_MQH #define MQLARTICLES_UTILS_TFMANAGER_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include "Basic.mqh" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //#define NEW_BAR_MANAGER_DEBUG //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ struct pack(8) SBarControler { datetime next_time; int period_in_seconds; uint8_t value; //--- SBarControler() : next_time(wrong_datetime) { } //--- inline void Create(const ENUM_TIMEFRAMES& _timeframe) { period_in_seconds = PeriodSecondsFastSeg(_timeframe); // Esta clase solo la usara CNewBarManager value = (_timeframe == PERIOD_W1 ? 1 : (_timeframe == PERIOD_MN1 ? 2 : 0)); } //--- void NewBar(const datetime& curr_time, bool& res) { if(curr_time >= next_time) { switch(value) { case 0: next_time = ((curr_time - (curr_time % period_in_seconds)) + period_in_seconds); break; case 1: next_time = CBarControlerNextTimeW(curr_time); break; case 2: next_time = CBarControlerNextTimeM(curr_time); break; } res = true; } else res = false; } //--- bool IsNewBar(const datetime& curr_time) { if(curr_time >= next_time) { switch(value) { case 0: next_time = ((curr_time - (curr_time % period_in_seconds)) + period_in_seconds); break; case 1: next_time = CBarControlerNextTimeW(curr_time); break; case 2: next_time = CBarControlerNextTimeM(curr_time); break; } return true; } return false; } }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // Excluyendo PERIOD_CURRENT #define CNEWBARMANAGER_TOTAL_TF 21 #define CNEWBARMANAGER_IDX_M1 0 /* timeframes[1] = 1 | EnumToString: PERIOD_M1 | PeriodSeconds: 60 timeframes[2] = 2 | EnumToString: PERIOD_M2 | PeriodSeconds: 120 timeframes[3] = 3 | EnumToString: PERIOD_M3 | PeriodSeconds: 180 timeframes[4] = 4 | EnumToString: PERIOD_M4 | PeriodSeconds: 240 timeframes[5] = 5 | EnumToString: PERIOD_M5 | PeriodSeconds: 300 timeframes[6] = 6 | EnumToString: PERIOD_M6 | PeriodSeconds: 360 timeframes[7] = 10 | EnumToString: PERIOD_M10 | PeriodSeconds: 600 timeframes[8] = 12 | EnumToString: PERIOD_M12 | PeriodSeconds: 720 timeframes[9] = 15 | EnumToString: PERIOD_M15 | PeriodSeconds: 900 timeframes[10] = 20 | EnumToString: PERIOD_M20 | PeriodSeconds: 1200 timeframes[11] = 30 | EnumToString: PERIOD_M30 | PeriodSeconds: 1800 timeframes[12] = 16385 | EnumToString: PERIOD_H1 | PeriodSeconds: 3600 timeframes[13] = 16386 | EnumToString: PERIOD_H2 | PeriodSeconds: 7200 timeframes[14] = 16387 | EnumToString: PERIOD_H3 | PeriodSeconds: 10800 timeframes[15] = 16388 | EnumToString: PERIOD_H4 | PeriodSeconds: 14400 timeframes[16] = 16390 | EnumToString: PERIOD_H6 | PeriodSeconds: 21600 timeframes[17] = 16392 | EnumToString: PERIOD_H8 | PeriodSeconds: 28800 timeframes[18] = 16396 | EnumToString: PERIOD_H12 | PeriodSeconds: 43200 timeframes[19] = 16408 | EnumToString: PERIOD_D1 | PeriodSeconds: 86400 timeframes[20] = 32769 | EnumToString: PERIOD_W1 | PeriodSeconds: 604800 timeframes[21] = 49153 | EnumToString: PERIOD_MN1 | PeriodSeconds: 2592000 */ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CNewBarManager { private: //--- Correcta ejecucion SBarControler controlers_arr[20]; // Todos los controladores base int8_t total_execute_functions; // No mayor a 128 no hay tantos TF en mt5 //--- int8_t TimeframeToIdx[49160]; //--- SBarControler bar_controler_fast_m1; // Controler m1 public: CNewBarManager(); ~CNewBarManager() {} //--- bool arr_values[CNEWBARMANAGER_TOTAL_TF]; // Acceso con out_i/pos | 0 es para M1 //--- void GetPosExecute(ENUM_TIMEFRAMES tf, int8_t& out_i); // Obtiene un indice inline void Execute(const datetime& curr_time); // Ejecucion general //--- __forceinline int8_t TotalRegisterTimframes() { return total_execute_functions; } }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #define CNewBarManager_IsNewBar(instance, pos) (instance.arr_values[pos]) #define CNewBarManager_IsNewBarM1(instance) (instance.arr_values[CNEWBARMANAGER_IDX_M1]) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CNewBarManager::CNewBarManager(void) { ArrayInitialize(TimeframeToIdx, -1); ArrayInitialize(arr_values, false); bar_controler_fast_m1.Create(PERIOD_M1); TimeframeToIdx[PERIOD_M1] = CNEWBARMANAGER_IDX_M1; // Indice 0 total_execute_functions = 0; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ inline void CNewBarManager::Execute(const datetime& curr_time) { if((arr_values[CNEWBARMANAGER_IDX_M1] = bar_controler_fast_m1.IsNewBar(curr_time))) { for(int8_t i = 0; i < total_execute_functions; i++) { controlers_arr[i].NewBar(curr_time, arr_values[i + 1]); } } } //+------------------------------------------------------------------+ //| Controlador | //+------------------------------------------------------------------+ void CNewBarManager::GetPosExecute(ENUM_TIMEFRAMES tf, int8_t& out_i) { //--- const ENUM_TIMEFRAMES real_tf = (tf == PERIOD_CURRENT) ? _Period : tf; // Corregimos en caso sea current //--- int8_t timeframe_to_pos_idx = TimeframeToIdx[real_tf]; //--- if(timeframe_to_pos_idx >= 0) // Si ya existe retornamos su posiicon en el boolean manager { out_i = timeframe_to_pos_idx; } else // Si no existe lo creamos { //--- timeframe_to_pos_idx = total_execute_functions + 1; //--- TimeframeToIdx[real_tf] = timeframe_to_pos_idx; //--- controlers_arr[total_execute_functions].Create(real_tf); //--- out_i = timeframe_to_pos_idx; //--- total_execute_functions++; // PrintFormat("IDX = %d | Timeframe = %s | New total = %d", out_i, EnumToString(tf), total_execute_functions); } } //+------------------------------------------------------------------+ #endif // MQLARTICLES_UTILS_TFMANAGER_MQH