AiDataTaskRuner/UI/Training/ConfigTab.mqh
Nique_372 adc7d722ba
2026-04-07 11:45:10 -05:00

1010 lines
35 KiB
MQL5

//+------------------------------------------------------------------+
//| ConfigTab.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 AIDATATASKRUNER_UI_TRAINING_CONFIGTAB_MQH
#define AIDATATASKRUNER_UI_TRAINING_CONFIGTAB_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "..\\Defines.mqh"
//--- Json para parsear (con el exe comunicador)
#include <TSN\\Json\\Json.mqh>
//--- Expert para lanzar eas
#include <TSN\\ExtraCodes\\Expert.mqh>
//--- Def para el procoolo de comunciaon
#include "..\\..\\Backend\\Training\\Def.mqh"
//--- Dll custom para filse eslec dialog con mas alcanzse
#include "..\\..\\DllFilseSelctDialog\\DllFilseSelctDialog\\Main.mqh"
/*
[CTrainingTabConfig]
//--- Parte general
m_label_titulo="Config"
m_label_name_file="Config file:"
m_label_name_file_val_tooltip="Selected config file"
m_btn_name_file_browse="Browse"
m_btn_name_file_browse_tooltip="Select config JSON file"
m_btn_open="Open"
m_btn_open_tooltip="Open file in default editor"
//--- Parte de python
m_label_tit_run_py="Run python"
m_label_py_file="Python file:"
m_label_py_file_val_tooltip="Path to the Python script or executable"
m_btn_py_file_browse="Browse"
m_btn_py_file_browse_tooltip="Select a .py script or .exe executable"
// Edit timeout
m_edit_py_max_tiemout="Tiemout for execute py:"
m_edit_py_max_tiemout_tooltup="Enter the value in seconds for the maximum time the py can run"
// Boton
m_btn_run_py="Run"
m_btn_run_py_tooltip="Click here to run python exe"
m_btn_run_py_running="Running..."
//--- Mensajes espeficiso por funcion
OnClickBottom_error_select_file="No file selected"
OnClickBottom_no_config_selected="No config file selected"
OnClickBottom_python_is_runing="Python is already running"
OnClickBottom_python_no_py_selected="No python\exe files selected"
// Error de laucher
OnClickBottom_python_launch_error_file="Failed to write in args.txt for launcher for python, last error = %d"
OnClickBottom_python_launch_error_exe="Failed to execute launcher, Check the terminal logs"
OnClickBottom_python_launch_python_launch_error_chart="Failed to open chart, last error = %d"
*/
//---
#define AIDATATASKRUNNER_TRAINING_NUM_C (80)
#define AIDATATASKRUNNER_FILENAME_ARGS_LAUNCHER ("LauncherPy\\args.txt")
#define AIDATATASKRUNNER_FILENAME_BAT_PY ("LauncherPy\\py.bat")
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class IRunPy : public CLoggerBase
{
public:
IRunPy(void) {}
~IRunPy(void) {}
//---
virtual void OnTrainingInit() {}
virtual void OnTrainingEnd() {}
virtual void OnTrainingNewResult(CJson* json) {}
//---
virtual __forceinline uint8_t EventsFlags() const = 0;
};
//---
#define TRAINING_RUNNER_PY_FLAG_ON_TRAINIG (1)
#define TRAINING_RUNNER_PY_FLAG_ON_INIT (2)
#define TRAINING_RUNNER_PY_FLAG_ON_DEINIT (4)
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CTrainingTabConfig : public CGuiBaseComponent<CLoggerBase>
{
private:
CTextLabel m_label_titulo;
CTextLabel m_label_name_file;
CTextLabel m_label_name_file_val;
CButton m_btn_name_file_browse;
CButton m_btn_open;
CButton m_btn_file_config_template;
//---
CTextLabel m_label_tit_run_py;
// Py file
CTextLabel m_label_py_file;
CTextLabel m_label_py_file_val;
CButton m_btn_py_file_browse;
// Log file
CTextLabel m_label_log_pyfile;
CTextLabel m_label_log_pyfile_val;
CButton m_btn_logpyfile_browse;
// Max timeout
CTextEdit m_edit_py_max_tiemout;
// Btn run final
CButton m_btn_run_py;
//---
string m_py_file_extension;
//---
bool m_py_is_run;
bool m_common_flag;
int m_extra_file_flags;
string m_base_terminal_files_path;
//---
string m_path_to_config_json;
string m_path_to_lock_bin;
string m_path_to_ea_launcher;
string m_path_to_log_py;
string m_path_py_interpete;
string m_python_path_env;
uint m_timeout_for_execute_py;
//---
IRunPy* m_runer_py_on_pass[];
int m_runer_py_on_pass_size;
IRunPy* m_runer_py_on_init[];
int m_runer_py_on_init_size;
IRunPy* m_runer_py_on_deinit[];
int m_runer_py_on_deinit_size;
//---
void OnTrainingFinish();
void OnTrainingStart();
public:
CTrainingTabConfig(void);
~CTrainingTabConfig(void);
//---
void AddRunnerPy(IRunPy* runer);
//---
void SetExtra(bool common_flag, const string& path_config_json, const string& path_lock, const string& path_ea_launcer, const string& path_py_inter, const string& py_path_env);
bool Create(CWndCreate* p, CWindow& main_window, int top_gap, int left_gap, int right_gap, int bottom_gap);
//---
bool OnClickBottom(const long lparam);
bool OnTextEdit(const long lparam);
bool OnClickDec(const long lparam);
bool OnClickInc(const long lparam);
//---
void OnLenguajeChange() override final;
//---
__forceinline string ConfigFilePath() const { return m_label_name_file_val.LabelText(); }
//---
// Se tendra que llamar a aesta funcion ojito
void OnFinishPy();
//---
void OnTimerEvent();
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CTrainingTabConfig::CTrainingTabConfig()
: CGuiBaseComponent<CLoggerBase>("CTrainingTabConfig"), m_py_is_run(false)
{
m_runer_py_on_deinit_size = ArrayResize(m_runer_py_on_deinit, 0);
m_runer_py_on_init_size = ArrayResize(m_runer_py_on_init, 0);
m_runer_py_on_pass_size = ArrayResize(m_runer_py_on_pass, 0);
}
//+------------------------------------------------------------------+
CTrainingTabConfig::~CTrainingTabConfig()
{
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTrainingTabConfig::SetExtra(bool common_flag, const string& path_config_json, const string& path_lock, const string& path_ea_launcer, const string& path_py_inter, const string& py_path_env)
{
//---
m_common_flag = common_flag;
m_extra_file_flags = (m_common_flag ? FILE_COMMON : 0);
m_path_py_interpete = path_py_inter;
//--- Estos arhcivos van tal cual no hay una carpeta base asi que se debe esopciifcar ruta completa (son relativos a Files\\) tal cual no de bsae_path
m_path_to_config_json = path_config_json;
m_path_to_lock_bin = path_lock;
m_path_to_ea_launcher = path_ea_launcer;
m_python_path_env = py_path_env;
//---
m_base_terminal_files_path = (m_common_flag ? TERMINAL_MT5_COMMON_PATH + "\\Files\\" : TERMINAL_MT5_DATA_PAH + "\\MQL5\\Files\\");
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTrainingTabConfig::Create(CWndCreate *p, CWindow &main_window, int top_gap, int left_gap, int right_gap, int bottom_gap)
{
//---
const int initial_x = left_gap + 5;
int x = left_gap + 5;
int y = top_gap + 10;
//--- Titulo
m_label_titulo.FontSize(14);
m_label_titulo.Font("Arial");
m_label_titulo.LabelColor(AIDATATASKRUNER_COLOR_TEXT_PRIMARY);
m_label_titulo.BackColor(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_PRESSED);
if(!p.CreateTextLabel(m_label_titulo, m_language[GUIBASE_COMPONENT_NAME(m_label_titulo)],
main_window, 0, m_base_tab, m_base_tab_idx, x, y, 200))
{
GUIBASE_ERROR_CREATION(m_label_titulo);
return false;
}
y += m_label_titulo.YSize() + 14;
//--- Label Config file:
m_label_name_file.FontSize(10);
m_label_name_file.Font("Arial");
m_label_name_file.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_label_name_file.BackColor(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_PRESSED);
if(!p.CreateTextLabel(m_label_name_file, m_language[GUIBASE_COMPONENT_NAME(m_label_name_file)],
main_window, 0, m_base_tab, m_base_tab_idx, x, y, 100, 25))
{
GUIBASE_ERROR_CREATION(m_label_name_file);
return false;
}
x += m_label_name_file.XSize() + 5;
//--- Label valor (ruta)
m_label_name_file_val.FontSize(10);
m_label_name_file_val.Font("Arial");
m_label_name_file_val.LabelColor(AIDATATASKRUNER_COLOR_TEXT_PRIMARY);
m_label_name_file_val.BackColor(AIDATATASKRUNER_COLOR_EDIT_BACK);
m_label_name_file_val.LabelXGap(5);
m_label_name_file_val.LabelYGap(3);
m_label_name_file_val.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_label_name_file_val)));
if(!p.CreateTextLabel(m_label_name_file_val, "",
main_window, 0, m_base_tab, m_base_tab_idx, x, y, 350, 25))
{
GUIBASE_ERROR_CREATION(m_label_name_file_val);
return false;
}
x = initial_x; // Reinit
y += m_label_name_file_val.YSize() + 8; // Bajamos (peude no caber la ruta)
//--- Browse
m_btn_name_file_browse.FontSize(10);
m_btn_name_file_browse.Font("Arial");
m_btn_name_file_browse.BackColor(AIDATATASKRUNER_COLOR_BTN_BACK);
m_btn_name_file_browse.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_btn_name_file_browse.BorderColor(AIDATATASKRUNER_COLOR_BTN_BORDER);
m_btn_name_file_browse.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_name_file_browse)));
if(!p.CreateButton(m_btn_name_file_browse, m_language[GUIBASE_COMPONENT_NAME(m_btn_name_file_browse)],
main_window, 0, m_base_tab, m_base_tab_idx, x, y, 80))
{
GUIBASE_ERROR_CREATION(m_btn_name_file_browse);
return false;
}
x += m_btn_name_file_browse.XSize() + 5;
//--- Open
m_btn_open.FontSize(10);
m_btn_open.Font("Arial");
m_btn_open.BackColor(AIDATATASKRUNER_COLOR_BTN_BACK);
m_btn_open.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_btn_open.BorderColor(AIDATATASKRUNER_COLOR_BTN_BORDER);
m_btn_open.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_open)));
if(!p.CreateButton(m_btn_open, m_language[GUIBASE_COMPONENT_NAME(m_btn_open)],
main_window, 0, m_base_tab, m_base_tab_idx, x, y, 80))
{
GUIBASE_ERROR_CREATION(m_btn_open);
return false;
}
x += m_btn_open.XSize() + 5;
//---
m_btn_file_config_template.FontSize(10);
m_btn_file_config_template.Font("Arial");
m_btn_file_config_template.BackColor(AIDATATASKRUNER_COLOR_BTN_BACK);
m_btn_file_config_template.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_btn_file_config_template.BorderColor(AIDATATASKRUNER_COLOR_BTN_BORDER);
m_btn_file_config_template.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_file_config_template)));
if(!p.CreateButton(m_btn_file_config_template, "?",
main_window, 0, m_base_tab, m_base_tab_idx, x, y, 50))
{
GUIBASE_ERROR_CREATION(m_btn_file_config_template);
return false;
}
//--- Label titulo Run Python
y += m_btn_open.YSize() + 21; // separacion visual de seccion
x = initial_x;
m_label_tit_run_py.FontSize(14);
m_label_tit_run_py.Font("Arial");
m_label_tit_run_py.LabelColor(AIDATATASKRUNER_COLOR_TEXT_PRIMARY);
m_label_tit_run_py.BackColor(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_PRESSED);
if(!p.CreateTextLabel(m_label_tit_run_py, m_language[GUIBASE_COMPONENT_NAME(m_label_tit_run_py)],
main_window, 0, m_base_tab, m_base_tab_idx, x, y, 200))
{
GUIBASE_ERROR_CREATION(m_label_tit_run_py);
return false;
}
y += m_label_tit_run_py.YSize() + 10;
//--- Label py file
m_label_py_file.FontSize(10);
m_label_py_file.Font("Arial");
m_label_py_file.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_label_py_file.BackColor(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_PRESSED);
if(!p.CreateTextLabel(m_label_py_file, m_language[GUIBASE_COMPONENT_NAME(m_label_py_file)],
main_window, 0, m_base_tab, m_base_tab_idx, x, y, 100, 25))
{
GUIBASE_ERROR_CREATION(m_label_py_file);
return false;
}
x += m_label_py_file.XSize() + 5;
//--- Label py file val
m_label_py_file_val.FontSize(10);
m_label_py_file_val.Font("Arial");
m_label_py_file_val.LabelColor(AIDATATASKRUNER_COLOR_TEXT_PRIMARY);
m_label_py_file_val.BackColor(AIDATATASKRUNER_COLOR_EDIT_BACK);
m_label_py_file_val.LabelXGap(5);
m_label_py_file_val.LabelYGap(2);
m_label_py_file_val.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_label_py_file_val)));
const int x_label_py_file_val = x;
if(!p.CreateTextLabel(m_label_py_file_val, "",
main_window, 0, m_base_tab, m_base_tab_idx, x, y, 425, 25))
{
GUIBASE_ERROR_CREATION(m_label_py_file_val);
return false;
}
x = initial_x;
y += m_label_py_file_val.YSize() + 8;
//--- Browse py file
m_btn_py_file_browse.FontSize(10);
m_btn_py_file_browse.Font("Arial");
m_btn_py_file_browse.BackColor(AIDATATASKRUNER_COLOR_BTN_BACK);
m_btn_py_file_browse.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_btn_py_file_browse.BorderColor(AIDATATASKRUNER_COLOR_BTN_BORDER);
m_btn_py_file_browse.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_py_file_browse)));
if(!p.CreateButton(m_btn_py_file_browse, m_language[GUIBASE_COMPONENT_NAME(m_btn_py_file_browse)],
main_window, 0, m_base_tab, m_base_tab_idx, x, y, 80))
{
GUIBASE_ERROR_CREATION(m_btn_py_file_browse);
return false;
}
//---
y += m_btn_py_file_browse.YSize() + 10; // separacion visual de seccion
x = initial_x;
//--- Label logpy file
m_label_log_pyfile.FontSize(10);
m_label_log_pyfile.Font("Arial");
m_label_log_pyfile.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_label_log_pyfile.BackColor(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_PRESSED);
if(!p.CreateTextLabel(m_label_log_pyfile, m_language[GUIBASE_COMPONENT_NAME(m_label_log_pyfile)],
main_window, 0, m_base_tab, m_base_tab_idx, x, y, 130, 25))
{
GUIBASE_ERROR_CREATION(m_label_py_file);
return false;
}
x = x_label_py_file_val; // mismo nivel
//--- Label logpy file val
m_label_log_pyfile_val.FontSize(10);
m_label_log_pyfile_val.Font("Arial");
m_label_log_pyfile_val.LabelColor(AIDATATASKRUNER_COLOR_TEXT_PRIMARY);
m_label_log_pyfile_val.BackColor(AIDATATASKRUNER_COLOR_EDIT_BACK);
m_label_log_pyfile_val.LabelXGap(5);
m_label_log_pyfile_val.LabelYGap(2);
m_label_log_pyfile_val.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_label_log_pyfile_val)));
if(!p.CreateTextLabel(m_label_log_pyfile_val, "",
main_window, 0, m_base_tab, m_base_tab_idx, x, y, 425, 25))
{
GUIBASE_ERROR_CREATION(m_label_log_pyfile_val);
return false;
}
x = initial_x;
y += m_label_log_pyfile_val.YSize() + 8;
//--- Browse logpy file
m_btn_logpyfile_browse.FontSize(10);
m_btn_logpyfile_browse.Font("Arial");
m_btn_logpyfile_browse.BackColor(AIDATATASKRUNER_COLOR_BTN_BACK);
m_btn_logpyfile_browse.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_btn_logpyfile_browse.BorderColor(AIDATATASKRUNER_COLOR_BTN_BORDER);
m_btn_logpyfile_browse.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_logpyfile_browse)));
if(!p.CreateButton(m_btn_logpyfile_browse, m_language[GUIBASE_COMPONENT_NAME(m_btn_logpyfile_browse)],
main_window, 0, m_base_tab, m_base_tab_idx, x, y, 80))
{
GUIBASE_ERROR_CREATION(m_btn_logpyfile_browse);
return false;
}
//---
y += m_btn_logpyfile_browse.YSize() + 10; // separacion visual de seccion
x = initial_x;
//---
const string texto = m_language[AIDATATASKRUNNERL_COMPONENT_NAME(m_edit_py_max_tiemout)];
m_edit_py_max_tiemout.FontSize(10);
m_edit_py_max_tiemout.Font("Arial");
m_edit_py_max_tiemout.CanvasFontSet();
const int width = m_edit_py_max_tiemout.m_canvas.TextWidth(texto);
m_edit_py_max_tiemout.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_edit_py_max_tiemout.BackColor(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_PRESSED);
m_edit_py_max_tiemout.GetTextBoxPointer().BackColor(AIDATATASKRUNER_COLOR_EDIT_BACK);
m_edit_py_max_tiemout.GetTextBoxPointer().BorderColor(AIDATATASKRUNER_COLOR_EDIT_BORDER);
m_edit_py_max_tiemout.GetTextBoxPointer().DefaultTextColor(AIDATATASKRUNER_COLOR_EDIT_TEXT_NORMAL);
m_edit_py_max_tiemout.GetTextBoxPointer().LabelColor(AIDATATASKRUNER_COLOR_EDIT_TEXT_NORMAL);
m_edit_py_max_tiemout.GetTextBoxPointer().SelectedBackColor(AIDATATASKRUNER_COLOR_EDIT_TEXT_SELECTED);
m_edit_py_max_tiemout.GetTextBoxPointer().SelectedTextColor(AIDATATASKRUNER_COLOR_EDIT_TEXT_HIGHLIGHT);
m_edit_py_max_tiemout.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_edit_py_max_tiemout)));
#define AIDATATASKRUNNER_TRAINING_EDITPY_MAX_VAL (double(UINT_MAX)/1000.0)
#define AIDATATASKRUNNER_TRAINING_EDITPY_DEF_VAL (1800)
if(!p.CreateTextEdit(m_edit_py_max_tiemout, texto,
main_window, 0, m_base_tab, m_base_tab_idx, false, x, y,
width + 10 + 200, 200, AIDATATASKRUNNER_TRAINING_EDITPY_MAX_VAL
, 1.0, 1.0, 0, double(AIDATATASKRUNNER_TRAINING_EDITPY_DEF_VAL))) // Min value = 1.0 | Step = 1.0 | 0 = Digitos | 1800 = valor por defecto (30 minutos)
{
AIDATATASKRUNER_ERROR_CREATION(m_edit_py_max_tiemout);
return false;
}
m_timeout_for_execute_py = AIDATATASKRUNNER_TRAINING_EDITPY_DEF_VAL * 1000; // 30 min default
//---
y += m_edit_py_max_tiemout.YSize() + 12;
x = initial_x;
//--- Boton Run
m_btn_run_py.FontSize(10);
m_btn_run_py.Font("Arial");
m_btn_run_py.BackColor(AIDATATASKRUNER_COLOR_BTN_BACK);
m_btn_run_py.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_btn_run_py.BorderColor(AIDATATASKRUNER_COLOR_BTN_BORDER);
m_btn_run_py.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_run_py)));
if(!p.CreateButton(m_btn_run_py, m_language[GUIBASE_COMPONENT_NAME(m_btn_run_py)],
main_window, 0, m_base_tab, m_base_tab_idx, x, y, 140))
{
GUIBASE_ERROR_CREATION(m_btn_run_py);
return false;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTrainingTabConfig::OnTextEdit(const long lparam)
{
if(m_edit_py_max_tiemout.Id() == lparam)
{
m_timeout_for_execute_py = uint(m_edit_py_max_tiemout.GetValue()) * 1000;
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTrainingTabConfig::OnClickDec(const long lparam)
{
if(m_edit_py_max_tiemout.Id() == lparam)
{
m_timeout_for_execute_py = uint(m_edit_py_max_tiemout.GetValue()) * 1000;
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTrainingTabConfig::OnClickInc(const long lparam)
{
if(m_edit_py_max_tiemout.Id() == lparam)
{
m_timeout_for_execute_py = uint(m_edit_py_max_tiemout.GetValue()) * 1000;
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTrainingTabConfig::OnClickBottom(const long lparam)
{
//---
if(m_btn_logpyfile_browse.Id() == lparam)
{
//---
string arr[];
if(FileSelectDialog(GUIBASE_MSG("flselect_logiflepy"), NULL, "Log files (*.log)|*.log", (m_common_flag ? FSD_COMMON_FOLDER : 0),
arr, NULL) != 1)
{
MessageBox(GUIBASE_MSG("error_select_file"), GUIBASE_MSG("error"), MB_ICONERROR | MB_OK);
return true;
}
//--- Guardamos la ruta y la extension
//Print(out_file_complete_path);
m_label_log_pyfile_val.LabelText(arr[0]); // ruta completa aqui
m_label_log_pyfile_val.Update(true);
//---
return true;
}
//---
if(m_btn_py_file_browse.Id() == lparam)
{
string out_file_complete_path = "";
if(!FileSelectDialogComplete(out_file_complete_path, 500, GUIBASE_MSG("flselect_py"),
"Python files (*.py)\0*.py\0Executable files (*.exe)\0*.exe\0\0", TERMINAL_MT5_DATA_PAH, // Base del temrinal NAME\\
OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST)) // EL FOLDER y archivo deben de sexisteir
{
//reciclamos el msg mismo que se usa en el browse deljson confgig
MessageBox(GUIBASE_MSG("error_select_file"), GUIBASE_MSG("error"), MB_ICONERROR | MB_OK);
return true;
}
//--- Guardamos la ruta y la extension
//Print(out_file_complete_path);
m_label_py_file_val.LabelText(out_file_complete_path); // ruta completa aqui
m_label_py_file_val.Update(true);
//---
m_py_file_extension = FileGetExtension(out_file_complete_path); // solo da la ext no con el .
return true;
}
//--- Config file
// Browse
if(m_btn_name_file_browse.Id() == lparam)
{
//---
string arr[];
if(FileSelectDialog("Configuration", NULL, "JSON files (*.json)|*.json", (m_common_flag ? FSD_COMMON_FOLDER : 0) | FSD_FILE_MUST_EXIST,
arr, NULL) != 1)
{
MessageBox(GUIBASE_MSG("error_select_file"), GUIBASE_MSG("error"), MB_ICONERROR | MB_OK);
return true;
}
//---
m_label_name_file_val.LabelText(arr[0]);
m_label_name_file_val.Update(true);
//---
return true;
}
// Template
if(m_btn_file_config_template.Id() == lparam)
{
//---
string arr[];
// para el temaplte usamos el common folder flag del panel dado que teamplestes se ubica ahi vale?¿
if(FileSelectDialog("Configuration", AIDATATASKRUNER_PATH_TEMPLATES, "JSON files (*.json)|*.json", AIDATATASK_RUNNER_FSD_COMON_FLAG | FSD_FILE_MUST_EXIST,
arr, AIDATATASKRUNER_FILENAME_TEMPLATES_PYCONFIG) != 1)
{
MessageBox(GUIBASE_MSG("error_select_file"), GUIBASE_COMMON("error"), MB_ICONERROR | MB_OK);
return true;
}
//---
m_label_name_file_val.LabelText(arr[0]);
m_label_name_file_val.Update(true);
//---
return true;
}
// Open
if(m_btn_open.Id() == lparam)
{
const string full_path = m_base_terminal_files_path + m_label_name_file_val.LabelText();
ShellExecuteW(0, "open", full_path, NULL, NULL, SW_SHOW); // no verificamos noe s critrico
return true;
}
//---
if(m_btn_run_py.Id() == lparam)
{
//---
if(m_py_is_run)
{
MessageBox(GUIBASE_MSG("python_is_runing"), GUIBASE_COMMON("warning"), MB_ICONWARNING | MB_OK);
return true;
}
//--- Check inicialzies
// Configuracion seleccionada
const string config = m_label_name_file_val.LabelText();
if(config.Length() < 1)
{
MessageBox(GUIBASE_MSG("no_config_selected"), GUIBASE_COMMON("error"), MB_ICONERROR | MB_OK);
return true;
}
// Archivos py selecionado
const string py = m_label_py_file_val.LabelText();
if(py.Length() < 1)
{
MessageBox(GUIBASE_MSG("no_py_selected"), GUIBASE_COMMON("error"), MB_ICONERROR | MB_OK);
return true;
}
//--- Abrimos el archivo de comuncionacion
const string fn = AIDATATASKRUNER_BASE_FOLDER + AIDATATASKRUNNER_FILENAME_ARGS_LAUNCHER;
::ResetLastError();
const int fh = FileOpen(fn, FILE_WRITE | FILE_TXT | AIDATATASK_RUNNER_COMON_FLAG, 0);
if(fh == INVALID_HANDLE)
{
MessageBox(StringFormat(GUIBASE_MSG("python_launch_error_file"), ::GetLastError()), GUIBASE_COMMON("error"), MB_ICONERROR | MB_OK);
return true;
}
//---
// Escritura
FileWrite(fh, m_label_log_pyfile_val.LabelText());
FileWrite(fh, py); // Py path to execute (ya da la ruyta completa)
FileWrite(fh, m_py_file_extension); // Extension
FileWrite(fh, m_path_py_interpete); // Interprete
FileWrite(fh, m_python_path_env);
::FileClose(fh);
//---
/*
input string InpFileNameArgs = "";
input int InpFileCommonFlag = 0;
input string InpArgsConfigJson = "";
input string InpArgsResJson = "";
input string InpArgsLockBin = "";
input string InpArgsBaseTerminalPath = "";
// 1 hora (3600 * 1000) en ms
input uint InpPyTimeoutMs = 3600000;
*/
//--- Lanzamos el ea
MqlParam params[9];
params[0].type = TYPE_STRING;
params[0].string_value = "Experts\\" + m_path_to_ea_launcher;
params[1].type = TYPE_STRING;
params[1].string_value = fn; // Nombre del archivo
params[2].type = TYPE_INT;
params[2].integer_value = AIDATATASK_RUNNER_COMON_FLAG; // Bandera common o no common
//---
// Paramemos de args como tal
params[3].type = TYPE_STRING;
params[3].string_value = config;
params[4].type = TYPE_STRING;
params[4].string_value = m_path_to_config_json;
params[5].type = TYPE_STRING;
params[5].string_value = m_path_to_lock_bin;
// Basew terminal path s
params[6].type = TYPE_STRING;
params[6].string_value = m_base_terminal_files_path;
//---
params[7].type = TYPE_UINT;
params[7].integer_value = m_timeout_for_execute_py;
//---
params[8].type = TYPE_STRING;
params[8].string_value = AIDATATASKRUNER_BASE_FOLDER + AIDATATASKRUNNER_FILENAME_BAT_PY;
//---
::ResetLastError();
const long bot_chart_id = OpenChartAndDevoler(ChartID(), _Symbol, _Period, 1500);
if(bot_chart_id == -1)
{
MessageBox(StringFormat(GUIBASE_MSG("python_launch_error_chart"), ::GetLastError()), GUIBASE_COMMON("error"), MB_ICONERROR | MB_OK);
return true;
}
//--- Check sincronizacion del grafico
while(ChartGetInteger(bot_chart_id, CHART_VISIBLE_BARS) < 1)
{
// Espera para la siguiente iteracion
Sleep(350);
}
if(!EXPERT::Run(bot_chart_id, params, EXPERT_PERMISOS_FLAG_DLL))
{
MessageBox(GUIBASE_MSG("python_launch_error_exe"), GUIBASE_COMMON("error"), MB_ICONERROR | MB_OK);
::ChartClose(bot_chart_id); // Cerramos
return true;
}
//--- Exito al lanzar el runner entonces comenzamos
OnTrainingStart();
//---
m_py_is_run = true;
//--- cambio de estado a running
m_btn_run_py.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_btn_run_py) + "_running"]);
m_btn_run_py.Update(true);
return true;
}
//---
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTrainingTabConfig::OnLenguajeChange(void)
{
//---
m_label_titulo.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_label_titulo)]);
m_label_titulo.Update(true);
//---
// Label
m_label_name_file.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_label_name_file)]);
m_label_name_file.Update(true);
// Val
m_label_name_file_val.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_label_name_file_val)));
// Browse
m_btn_name_file_browse.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_btn_name_file_browse)]);
m_btn_name_file_browse.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_name_file_browse)));
m_btn_name_file_browse.Update(true);
// Open
m_btn_open.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_btn_open)]);
m_btn_open.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_open)));
m_btn_open.Update(true);
// Teemplate ?
m_btn_file_config_template.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_file_config_template)));
//--- Titulo run py
m_label_tit_run_py.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_label_tit_run_py)]);
m_label_tit_run_py.Update(true);
//---
// Label
m_label_py_file.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_label_py_file)]);
m_label_py_file.Update(true);
// Val
m_label_py_file_val.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_label_py_file_val)));
// Browse
m_btn_py_file_browse.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_btn_py_file_browse)]);
m_btn_py_file_browse.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_py_file_browse)));
m_btn_py_file_browse.Update(true);
//---
// Label
m_label_log_pyfile.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_label_log_pyfile)]);
m_label_log_pyfile.Update(true);
// Val
m_label_log_pyfile_val.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_label_log_pyfile_val)));
// Browse
m_btn_logpyfile_browse.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_btn_logpyfile_browse)]);
m_btn_logpyfile_browse.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_logpyfile_browse)));
m_btn_logpyfile_browse.Update(true);
//--- Actulziamos el edit del py
const string key = GUIBASE_COMPONENT_NAME(m_edit_py_max_tiemout);
m_edit_py_max_tiemout.LabelText(m_language[key]);
m_edit_py_max_tiemout.Tooltip(m_language.Tooltip(key));
const string texto = m_edit_py_max_tiemout.LabelText();
m_edit_py_max_tiemout.CanvasFontSet();
const int width = m_edit_py_max_tiemout.m_canvas.TextWidth(texto);
// Ancho texto | Extra separacion entre texto y obj element| Ancho de elemento
m_edit_py_max_tiemout.XSize(width + 10 + 200);
m_edit_py_max_tiemout.Update(true);
//---
m_btn_run_py.Tooltip(m_language[GUIBASE_COMPONENT_NAME(m_btn_run_py)]); // toltip solo cambios
m_btn_run_py.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_btn_run_py) + (m_py_is_run ? "_running" : "")]);
m_btn_run_py.Update(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTrainingTabConfig::AddRunnerPy(IRunPy *runer)
{
//---
const uint8_t flags = runer.EventsFlags();
//---
if((flags & TRAINING_RUNNER_PY_FLAG_ON_INIT) != 0)
{
m_runer_py_on_init[ArrayResize(m_runer_py_on_init, (++m_runer_py_on_init_size)) - 1] = runer;
}
//---
if((flags & TRAINING_RUNNER_PY_FLAG_ON_TRAINIG) != 0)
{
m_runer_py_on_pass[ArrayResize(m_runer_py_on_pass, (++m_runer_py_on_pass_size)) - 1] = runer;
}
//---
if((flags & TRAINING_RUNNER_PY_FLAG_ON_DEINIT) != 0)
{
m_runer_py_on_deinit[ArrayResize(m_runer_py_on_deinit, (++m_runer_py_on_deinit_size)) - 1] = runer;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTrainingTabConfig::OnTrainingStart()
{
//---
LogWarning("El entremianeto a empezado", FUNCION_ACTUAL);
//--- Eliminamos los archvos anteriorres si es que existen
::FileDelete(m_path_to_lock_bin, m_extra_file_flags);
::FileDelete(m_path_to_config_json, m_extra_file_flags);
//---
for(int i = 0; i < m_runer_py_on_init_size; i++)
{
m_runer_py_on_init[i].OnTrainingInit();
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTrainingTabConfig::OnTrainingFinish()
{
//---
m_py_is_run = false;
//---
LogWarning("Training has finished", FUNCION_ACTUAL);
//---
for(int i = 0; i < m_runer_py_on_deinit_size; i++)
{
m_runer_py_on_deinit[i].OnTrainingEnd();
}
//---
const string run_key = GUIBASE_COMPONENT_NAME(m_btn_run_py) + (m_py_is_run ? "_running" : "");
m_btn_run_py.LabelText(m_language[run_key]);
m_btn_run_py.Update(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTrainingTabConfig::OnTimerEvent()
{
if(!m_py_is_run)
return;
static int8_t ct = 0;
if(ct++ > AIDATATASKRUNNER_TRAINING_NUM_C)
{
//---
ct = 0;
//---
if(::FileIsExist(m_path_to_lock_bin, m_extra_file_flags))
{
//--- Reinicio primero procemos luego
// Lo eliminamos denuevo para que esperemos la siguiente entrega
::FileDelete(m_path_to_lock_bin, m_extra_file_flags);
//---
LogInfo("Nuevo pase recibido de py", FUNCION_ACTUAL);
//---
CJson* json = new CJson();
//---
::ResetLastError();
const int fh = ::FileOpen(m_path_to_config_json, FILE_READ | FILE_BIN | m_extra_file_flags);
if(fh == INVALID_HANDLE)
{
LogWarning(::StringFormat("Fallo al abrir el archivo =%s, ultimo error = %d", m_path_to_config_json, ::GetLastError()), FUNCION_ACTUAL);
delete json; // Borramos el json
return;
}
//---
const ulong file_size = FileSize(fh);
string file_content = ::FileReadString(fh, int(file_size));
if(file_content.GetChar(0) == 0xFEFF) // check si el primero es boom
file_content.SetChar(0, ' ');
//Print(file_content);
//---
if(json.Parse(file_content))
{
//---
::FileClose(fh);
//---
if(json["finish"].IsValid())
{
const int res = int(json["finish"].ToInt());
if(res != AIDATATASKRUNNNER_TRAINIG_OUT_EXITO) // no es igual a exito hubo un fallo
{
const string str = AiDataTaskRunnerTrainingGetErr(res);
LogFatalError(StringFormat("Fallo al ejecutar el py, el EA launcher retonrno valor no igual a 0, valor de finish = %I64d, str = %s", res, str),
FUNCION_ACTUAL);
}
OnTrainingFinish();
delete json;
}
else
{
for(int i = 0; i < m_runer_py_on_pass_size; i++)
{
m_runer_py_on_pass[i].OnTrainingNewResult(json);
}
// Nota:
// Se garnatiza que en la otra tab haya un hook que vayue guradadno los json asi que noe s enceiso eliminar esa
// tab hook se encarga de eso
}
}
else
{
::FileClose(fh);
LogError(::StringFormat("Fallo al parsear json ultimo error = %s", ::EnumToString(EnumJsonError(json.GetLastError()))), FUNCION_ACTUAL);
delete json;
}
}
}
}
//---
#endif // AIDATATASKRUNER_UI_TRAINING_CONFIGTAB_MQH
//+------------------------------------------------------------------+