334 líneas
22 KiB
MQL5
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
|