AiDataGenByLeo/TaskRunner/Base.mqh
Nique_372 260751fe6e
2026-03-13 21:49:30 -05:00

334 líneas
22 KiB
MQL5

//+------------------------------------------------------------------+
//| 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