297 строки
11 КиБ
MQL5
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];
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|