//+------------------------------------------------------------------+ //| Backend.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 //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //--- Incluimos el frotend de la app #include "Main.mqh" //+------------------------------------------------------------------+ //| Implementacion mock de ITaskRunerAi para pruebas | //+------------------------------------------------------------------+ class CTaskRunerAiMock : public ITaskRunerAi { private: //--- TaskTester m_current_task; // Tarea actual en configuracion TaskTester m_tasks[]; // Array de tareas int m_tasks_size; // Cantidad de tareas CTaskSaver m_saver; // Guardado y carga de tareas public: //--- CTaskRunerAiMock() : m_tasks_size(0) {} ~CTaskRunerAiMock() {} //--- Configuracion de la tarea actual void OnCurrentTask_ModifyConfigMoveFile(const string str_files) override final; void OnCurrentTask_ModifyConfigExpertPath(const string str_files) override final; void OnCurrentTask_ModifyConfigProgresCsvFile(const string str_files) override final; void OnCurrentTask_ModifyConfigMainFolder(const string str_files) override final; //--- Modificacion de la tarea actual void OnCurrentTask_ModifyDateStart(const datetime new_start) override final; void OnCurrentTask_ModifyDateEnd(const datetime new_end) override final; void OnCurrentTask_ModifySimbolo(const string new_symbol) override final; void OnCurrentTask_ModifySimboloFolder(const string new_symbol_f) override final; void OnCurrentTask_ModifyTimeframe(const ENUM_TIMEFRAMES new_tf) override final; void OnCurrentTask_ModifyLabel(const string label) override final; void OnCurrentTask_ModifyLabelId(const int label_id) override final; void OnCurrentTask_ModifySetFile(const string set_file) override final; //--- Añadir tarea actual bool OnCurrentTask_Add() override final; //--- Tareas int CleanAllTask(int& out[]) override final; int RunAllTask(int& out[]) override final; //--- Guardado y carga bool SaveAllTaskInFile(const string& file_name) override final; bool SetTastByFile(const string& file_name) override final; //--- Getters TaskTester GetTaskByIndex(const int index) override final; inline int TaskSize() const override final { return m_tasks_size; } }; //+------------------------------------------------------------------+ //| Modificadores de configuracion de la tarea actual | //+------------------------------------------------------------------+ void CTaskRunerAiMock::OnCurrentTask_ModifyConfigMoveFile(const string str_files) { ::PrintFormat("[MOCK] ModifyConfigMoveFile = %s", str_files); } //+------------------------------------------------------------------+ void CTaskRunerAiMock::OnCurrentTask_ModifyConfigExpertPath(const string str_files) { ::PrintFormat("[MOCK] ModifyConfigExpertPath = %s", str_files); } //+------------------------------------------------------------------+ void CTaskRunerAiMock::OnCurrentTask_ModifyConfigProgresCsvFile(const string str_files) { ::PrintFormat("[MOCK] ModifyConfigProgresCsvFile = %s", str_files); } //+------------------------------------------------------------------+ void CTaskRunerAiMock::OnCurrentTask_ModifyConfigMainFolder(const string str_files) { ::PrintFormat("[MOCK] ModifyConfigMainFolder = %s", str_files); } //+------------------------------------------------------------------+ //| Modificadores de la tarea actual | //+------------------------------------------------------------------+ void CTaskRunerAiMock::OnCurrentTask_ModifyDateStart(const datetime new_start) { m_current_task.start_date = new_start; ::PrintFormat("[MOCK] ModifyDateStart = %s", ::TimeToString(new_start)); } //+------------------------------------------------------------------+ void CTaskRunerAiMock::OnCurrentTask_ModifyDateEnd(const datetime new_end) { m_current_task.end_date = new_end; ::PrintFormat("[MOCK] ModifyDateEnd = %s", ::TimeToString(new_end)); } //+------------------------------------------------------------------+ void CTaskRunerAiMock::OnCurrentTask_ModifySimbolo(const string new_symbol) { m_current_task.symbol = new_symbol; ::PrintFormat("[MOCK] ModifySimbolo = %s", new_symbol); } //+------------------------------------------------------------------+ void CTaskRunerAiMock::OnCurrentTask_ModifySimboloFolder(const string new_symbol_f) { m_current_task.symbol_folder = new_symbol_f; ::PrintFormat("[MOCK] ModifySimboloFolder = %s", new_symbol_f); } //+------------------------------------------------------------------+ void CTaskRunerAiMock::OnCurrentTask_ModifyTimeframe(const ENUM_TIMEFRAMES new_tf) { m_current_task.timeframe = new_tf; ::PrintFormat("[MOCK] ModifyTimeframe = %s", ::EnumToString(new_tf)); } //+------------------------------------------------------------------+ void CTaskRunerAiMock::OnCurrentTask_ModifyLabel(const string label) { m_current_task.label = label; ::PrintFormat("[MOCK] ModifyLabel = %s", label); } //+------------------------------------------------------------------+ void CTaskRunerAiMock::OnCurrentTask_ModifyLabelId(const int label_id) { m_current_task.label_id = label_id; ::PrintFormat("[MOCK] ModifyLabelId = %d", label_id); } //+------------------------------------------------------------------+ void CTaskRunerAiMock::OnCurrentTask_ModifySetFile(const string set_file) { m_current_task.set_file = set_file; ::PrintFormat("[MOCK] ModifySetFile = %s", set_file); } //+------------------------------------------------------------------+ //| Añade la tarea actual al array de tareas | //+------------------------------------------------------------------+ bool CTaskRunerAiMock::OnCurrentTask_Add() { //--- Validacion basica if(m_current_task.symbol == NULL || m_current_task.symbol == "") { m_last_error_msg = "Simbolo no configurado"; return false; } if(m_current_task.timeframe == WRONG_VALUE) { m_last_error_msg = "Timeframe no configurado"; return false; } if(m_current_task.start_date >= m_current_task.end_date) { m_last_error_msg = "Fecha inicio debe ser menor a fecha fin"; return false; } //--- Agregar al array ::ArrayResize(m_tasks, m_tasks_size + 1); m_tasks[m_tasks_size] = m_current_task; m_tasks_size++; //--- ::PrintFormat("[MOCK] Tarea agregada: %s | %s | Total tareas = %d", m_current_task.symbol, ::EnumToString(m_current_task.timeframe), m_tasks_size); //--- Resetear tarea actual m_current_task = TaskTester(); return true; } //+------------------------------------------------------------------+ //| Limpia todas las tareas que se puedan limpiar | //+------------------------------------------------------------------+ int CTaskRunerAiMock::CleanAllTask(int &out[]) { //--- Sin tareas if(m_tasks_size <= 0) { m_last_error_msg = "No hay tareas para limpiar"; return 0; } //--- Buscar tareas limpiables (Pendiente o En cola) int cleaned_indexes[]; int cleaned_total = 0; //--- for(int i = 0; i < m_tasks_size; i++) { if(m_tasks[i].state == AIEXECUTOR_TASK_STATE_PENDIENTE || m_tasks[i].state == AIEXECUTOR_TASK_STATE_IN_QUEQE) { ::ArrayResize(cleaned_indexes, cleaned_total + 1); cleaned_indexes[cleaned_total++] = i; } } //--- Sin tareas limpiables if(cleaned_total <= 0) { m_last_error_msg = "No hay tareas pendientes o en cola para limpiar"; return 0; } //--- Eliminar del array interno (write/read index) int write = 0; for(int read = 0; read < m_tasks_size; read++) { bool is_removed = false; for(int k = 0; k < cleaned_total; k++) { if(cleaned_indexes[k] == read) { is_removed = true; break; } } if(!is_removed) m_tasks[write++] = m_tasks[read]; } //--- m_tasks_size = write; ::ArrayResize(m_tasks, m_tasks_size); //--- Devolver indices eliminados ::ArrayCopy(out, cleaned_indexes); ::PrintFormat("[MOCK] CleanAllTask: %d tareas limpiadas", cleaned_total); return cleaned_total; } //+------------------------------------------------------------------+ //| Pone en cola todas las tareas pendientes | //+------------------------------------------------------------------+ int CTaskRunerAiMock::RunAllTask(int &out[]) { //--- Sin tareas if(m_tasks_size <= 0) { m_last_error_msg = "No hay tareas para ejecutar"; return 0; } //--- Buscar tareas pendientes y ponerlas en cola int queued_total = 0; //--- for(int i = 0; i < m_tasks_size; i++) { if(m_tasks[i].state == AIEXECUTOR_TASK_STATE_PENDIENTE) { m_tasks[i].state = AIEXECUTOR_TASK_STATE_IN_QUEQE; ::ArrayResize(out, queued_total + 1); out[queued_total++] = i; } } //--- Sin tareas pendientes if(queued_total <= 0) { m_last_error_msg = "No hay tareas pendientes para ejecutar"; return 0; } //--- ::PrintFormat("[MOCK] RunAllTask: %d tareas puestas en cola", queued_total); return queued_total; } //+------------------------------------------------------------------+ //| Guarda todas las tareas en archivo | //+------------------------------------------------------------------+ bool CTaskRunerAiMock::SaveAllTaskInFile(const string &file_name) { if(!m_saver.Save(file_name, m_tasks, m_tasks_size)) { m_last_error_msg = StringFormat("Fallo al guardar archivo = %s", file_name); return false; } ::PrintFormat("[MOCK] Tareas guardadas en = %s", file_name); return true; } //+------------------------------------------------------------------+ //| Carga tareas desde archivo | //+------------------------------------------------------------------+ bool CTaskRunerAiMock::SetTastByFile(const string &file_name) { if(!m_saver.Load(file_name, m_tasks, m_tasks_size)) { m_last_error_msg = StringFormat("Fallo al cargar archivo = %s", file_name); return false; } ::PrintFormat("[MOCK] Tareas cargadas desde = %s | Total = %d", file_name, m_tasks_size); return true; } //+------------------------------------------------------------------+ //| Retorna una tarea por indice | //+------------------------------------------------------------------+ TaskTester CTaskRunerAiMock::GetTaskByIndex(const int index) { if(index < 0 || index >= m_tasks_size) { m_last_error_msg = StringFormat("Indice fuera de rango = %d", index); return TaskTester(); } return m_tasks[index]; } //+------------------------------------------------------------------+