AiDataTaskRuner/Example/Backend.mqh
2026-02-25 11:10:14 -05:00

297 строки
11 КиБ
MQL5

//+------------------------------------------------------------------+
//| 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];
}
//+------------------------------------------------------------------+