//+------------------------------------------------------------------+ //| Base.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 AIDATAGENBYLEO_TASKRUNENER_BASE_MQH #define AIDATAGENBYLEO_TASKRUNENER_BASE_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include "Saver.mqh" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // Debido a que solo podemos tener una instnacia del tester.. esta clase sera igual no podremos tener varias=¿ pero // de ogal forma mql es single theard?¿ asi que.. //+------------------------------------------------------------------+ class CExecutionTester : public CSpecializedManager { private: bool m_init; CTaskSaver* m_saver; TaskTester m_task[]; int m_task_size; string m_expert_path; string m_main_folder; //--- int m_files_common_to_move_size; string m_files_common_to_move[]; //--- string m_pased_task_file_name; public: CExecutionTester(void); ~CExecutionTester(void); //--- Incia las configuraciones basicas bool Init(const string& file_name); bool Init(const string& expert_path, const string& main_folder, const string& move_to_files[], string progrees_csv_file = "none"); //--- bool SetTaskByFile(const string& file_name) { return m_saver.Load(file_name, m_task, m_task_size); } bool AddTask(ENUM_TIMEFRAMES tf, string symbol_real, string symbol_folder_name, string label, int label_id, string set_file, datetime start, datetime end); //--- // En base al id de ejuccion encuntra la mosicion en m_task int FindByMTTesterId(const int id); //--- // Esta fucnion loq eu hace es el copaido se jeucta al temrina la tarea // task_idnex = la tarea que se ifnalizo bool OnEndTask(const int pos_idx); bool OnInitTask(const int pos_idx) { return true; } //--- // Aqui añadimos todos los simbolos a TesterSettings void SetSettingsForMTTester(INITDEINIT init_func, INITDEINIT end_func); //--- __forceinline bool Initialized() const { return m_init; } }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CExecutionTester::CExecutionTester(void) : m_init(false), m_main_folder(NULL), m_expert_path(NULL), m_pased_task_file_name(NULL) { m_files_common_to_move_size = ArrayResize(m_files_common_to_move, 0); m_task_size = ArrayResize(m_task, 0); m_saver = new CTaskSaver(); AddLogger(m_saver); } //+------------------------------------------------------------------+ CExecutionTester::~CExecutionTester() { CleanItems("CExeuctionTester"); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // move ifles tendra todos los arhcivos a mover ruta relativa desde el main_folder // main folder debe de tener \\ //+------------------------------------------------------------------+ bool CExecutionTester::Init(const string& expert_path, const string& main_folder, const string& move_to_files[], string progrees_csv_file = "none") { if(m_init) { LogWarning("Se esta volviendo a iniciar", FUNCION_ACTUAL); m_init = false; } //--- m_expert_path = expert_path; m_main_folder = main_folder; //--- m_files_common_to_move_size = ::ArraySize(move_to_files); for(int i = 0; i < m_files_common_to_move_size; i++) { m_files_common_to_move[i] = main_folder + move_to_files[i]; } //--- Solo cargamos el fils m_pased_task_file_name = progrees_csv_file; //--- m_init = true; return true; } //+------------------------------------------------------------------+ /* ExpertPath=ICTRaptor.ex5 MainFolder=ICTKiller\\ TemporalFIleName=none MoveFilesName=pred.csv,sl.csv,tp.csv,scaler_tp.csv,scaler_sl.csv,scaler_pred.csv */ //--- bool CExecutionTester::Init(const string &file_name) { //--- if(m_init) { LogWarning("Se esta volviendo a iniciar", FUNCION_ACTUAL); m_init = false; } //--- ::ResetLastError(); const int fh = FileOpen(file_name, FILE_COMMON | FILE_TXT | FILE_READ); if(fh == INVALID_HANDLE) { LogError(StringFormat("Fallo al abrir el archivo = %s, ultimo error = %d", file_name, ::GetLastError()), FUNCION_ACTUAL); return false; } //--- string line = ""; int s = 0; //--- Define #define EXECUTION_TESTER_ASSING(V) \ line = FileReadString(fh); \ s = line.Find("="); \ if(s == -1) \ { \ FileClose(fh); \ LogError(StringFormat("Se estuvo busncado el = en la linea:\n%s", line), FUNCION_ACTUAL); \ return false; \ } \ V = StringSubstr(line, s); \ StringTrimLeft(V); \ StringTrimRight(V); //--- Assing de basicos EXECUTION_TESTER_ASSING(m_expert_path) EXECUTION_TESTER_ASSING(m_main_folder) EXECUTION_TESTER_ASSING(m_pased_task_file_name) #undef EXECUTION_TESTER_ASSING //--- Obtenemos archivos a mover line = FileReadString(fh); s = line.Find("="); if(s == -1) { FileClose(fh); LogError(StringFormat("Se estuvo busncado el = en la linea:\n%s", line), FUNCION_ACTUAL); return false; } // Convert if(!StrTo::CstArray(m_files_common_to_move, StringSubstr(line, s), ',', true)) { FileClose(fh); LogError("Fallo al pasar cadena a string array", FUNCION_ACTUAL); return false; } // Final m_files_common_to_move_size = ::ArraySize(m_files_common_to_move); for(int i = 0; i < m_files_common_to_move_size; i++) { m_files_common_to_move[i] = m_main_folder + m_files_common_to_move[i]; } //--- FileClose(fh); return true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CExecutionTester::AddTask(ENUM_TIMEFRAMES tf, string symbol_real, string symbol_folder_name, string label, int label_id, string set_file, datetime start, datetime end) { if(::ArrayResize(m_task, m_task_size + 1) != m_task_size + 1) return false; //--- if(tf == PERIOD_CURRENT) tf = _Period; //--- m_task[m_task_size].timeframe = tf; m_task[m_task_size].symbol = symbol_real; m_task[m_task_size].label = label; m_task[m_task_size].label_id = label_id; m_task[m_task_size].symbol_folder = symbol_folder_name; m_task[m_task_size].start_date = start; m_task[m_task_size].end_date = end; m_task[m_task_size++].set_file = set_file; return true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CExecutionTester::SetSettingsForMTTester(INITDEINIT init_func, INITDEINIT end_func) { for(int i = 0; i < m_task_size; i++) { m_task[i].mtteser_id = TesterSettings.Add(m_expert_path, m_task[i].symbol, m_task[i].timeframe, m_task[i].start_date, m_task[i].end_date, init_func, end_func, m_task[i].set_file); if(m_task[i].mtteser_id == -1) { LogCriticalError("Fallo al añadir una configuracion al MTTester", FUNCION_ACTUAL); Remover(); return; } m_task[i].state = ; } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CExecutionTester::FindByMTTesterId(const int id) { for(int i = 0; i < m_task_size; i++) { if(m_task[i].mtteser_id == id) { return i; } } return -1; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CExecutionTester::OnEndTask(const int pos_idx) { //--- const int task_index = FindByMTTesterId(pos_idx); if(task_index == -1) { FastLog(FUNCION_ACTUAL, FATAL_ERROR_TEXT, ::StringFormat("No se encontro la tarea con indice = %d", pos_idx)); Remover(); return false; } //--- // Aqui movemos... string tf = ::EnumToString(m_task[task_index].timeframe); ::StringReplace(tf, "PERIOD_", ""); const string final_ubicaction_folder = ::StringFormat("%s\\%s\\%s\\%s_%d\\", m_main_folder, m_task[task_index].symbol_folder, tf, m_task[task_index].label, m_task[task_index].label_id); for(int i = 0; i < m_files_common_to_move_size; i++) { //--- Movemos ::ResetLastError(); if(!::FileMove(m_files_common_to_move[i], FILE_COMMON, final_ubicaction_folder, FILE_REWRITE | FILE_COMMON)) { LogError(::StringFormat("No se pudo mover el archivo =%s, a = %s, ultimo error = %d" , m_files_common_to_move[i], final_ubicaction_folder, ::GetLastError()), FUNCION_ACTUAL); return false; } //--- Copiamos el setfile const string out = ::TerminalInfoString(TERMINAL_COMMONDATA_PATH) + "\\" + final_ubicaction_folder; const string in = ::TerminalInfoString(TERMINAL_DATA_PATH) + "\\MQL5\\Profiles\\Tester\\" + m_task[i].set_file; if(!MTTESTER::FileMove(in, out, true)) { LogError(::StringFormat("Fallo al mover:\n%s\nA\n%s\nUltimo error en kernel32 = %d", out, in, kernel32::GetLastError()), FUNCION_ACTUAL); return false; } } //--- Eliminiamos por swap const int last = --m_task_size; if(last != task_index) { m_task[task_index] = m_task[last]; } ArrayResize(m_task, m_task_size); //--- Guardamos progreso if(m_pased_task_file_name != NULL) return m_saver.Save(m_pased_task_file_name, m_task, m_task_size); //--- return true; } //+------------------------------------------------------------------+ #endif /// AIDATAGENBYLEO_TASKRUNENER_BASE_MQH