//+------------------------------------------------------------------+ //| 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 AIDATATASKRUNNER_BACKEND_CAPA1_MAIN_MQH #define AIDATATASKRUNNER_BACKEND_CAPA1_MAIN_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include "..\\..\\..\\ExtraCodes\\MultiTester\\Multitester.mqh" #include "..\\..\\..\\MQLArticles\\Utils\\Basic.mqh" #include "Defines.mqh" #include //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CMTTesterRunner : public CLoggerBase { private: bool m_in_execution; CQueue m_cola; //--- MTTesterTask m_current_task; string m_expert_path; long m_current_exp_chart_id; //--- void ExecuteNext(); public: CMTTesterRunner(void) {} ~CMTTesterRunner(void) {} //--- bool OnEndTask(const int pos_idx); bool OnInitTask(const int pos_idx) { return true; } void SetSettingsForMTTester(INITDEINIT init_func, INITDEINIT end_func); //--- void ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMTTesterRunner::ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_CUSTOM + DEFMTTESTER_E_ON_TASK) { //--- //lparam = de donde proviene el evento enviado //sparm = informacion enviada (separada por , en un futuro si es complejo json) //dparam = nada //--- m_cola.Enqueue(sparam + "," + string(lparam)); // Paramos + de donde proviene ExecuteNext(); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMTTesterRunner::ExecuteNext(void) { if(!m_in_execution) // Solo ejecuatmos si no estamos haciendo nada { const string params = m_cola.Dequeue(); //--- const int t = StringSplit(params, ',', g_str_arr_dyn_arr); if(t < DEFMTTESTER_PARAMS_MIN) { const string msg = StringFormat("Tarea con parametros:\n%s\nEs invalida, como minimo debe de tener %d parametros", params, DEFMTTESTER_PARAMS_MIN); //--- LogError(msg, FUNCION_ACTUAL); m_current_exp_chart_id = (t > 0) ? long(g_str_arr_dyn_arr[t - DEFMTTESTER_PARAMS_OFFSET_CHARTID]) : -1; //--- if(m_current_exp_chart_id != -1) { const double dparam = double(m_current_exp_chart_id); ::EventChartCustom(m_current_exp_chart_id, DEFMTTESTER_E_FINISH_TASK, DEFMTTESTER_TESTER_R_FALLO_PARAMS_INVALIDOS, dparam, msg); } else LogError(StringFormat("Chart id del enviador es invalido = %I64d", m_current_exp_chart_id), FUNCION_ACTUAL); //--- return; } //--- m_current_task.Assing(g_str_arr_dyn_arr); m_expert_path = g_str_arr_dyn_arr[t - DEFMTTESTER_PARAMS_OFFSET_EXPERT_NAME]; //--- // Aqui inicar a Multites para que empize a ejeucta rla unica tarea que tiene g_multi_tester.Initialize(); // Lo corremos } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMTTesterRunner::SetSettingsForMTTester(INITDEINIT init_func, INITDEINIT end_func) { g_multi_tester.Add(m_expert_path, m_current_task.symbol, m_current_task.timeframe, m_current_task.start_date, m_current_task.end_date, init_func, end_func, m_current_task.set_file); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CMTTesterRunner::OnEndTask(const int pos_idx) { // Envaimos el mensaje al EA const double dparam = double(m_current_exp_chart_id); ::EventChartCustom(m_current_exp_chart_id, DEFMTTESTER_E_FINISH_TASK, DEFMTTESTER_TESTER_R_EXITO, dparam, ""); m_in_execution = false; return true; } //+------------------------------------------------------------------+ //| Clase internmeida para conectar no statis con static | //| esto es vcritico para el InitTask EndTask y se settings | //+------------------------------------------------------------------+ class COnEndTaskProcesator { public: COnEndTaskProcesator(void) {} ~COnEndTaskProcesator(void) {} //--- static CMTTesterRunner* s_executor; //--- // OnInitTask static __forceinline bool OnInitTask(const int id) { return s_executor.OnInitTask(id); } // OnEndTask static __forceinline bool OnEndTask(const int id) // Id de la tarea { return s_executor.OnEndTask(id); } //--- static __forceinline void SetSetings() { INITDEINIT init = (INITDEINIT)COnEndTaskProcesator::OnInitTask; INITDEINIT end = (INITDEINIT)COnEndTaskProcesator::OnEndTask; s_executor.SetSettingsForMTTester(init, end); } }; //+------------------------------------------------------------------+ CMTTesterRunner* COnEndTaskProcesator::s_executor = NULL; //+------------------------------------------------------------------+ __forceinline void SetTesterSettings() { COnEndTaskProcesator::SetSetings(); } //--- #endif // AIDATATASKRUNNER_BACKEND_CAPA1_MAIN_MQH