//+------------------------------------------------------------------+ //| AllFlows.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 AIDATATASKRUNNER_BACKEND_WORKFLOWS_FLOWS_ALLFLOWS_MQH #define AIDATATASKRUNNER_BACKEND_WORKFLOWS_FLOWS_ALLFLOWS_MQH //+------------------------------------------------------------------+ //| Include | //+------------------------------------------------------------------+ #include #include #include "..\\..\\Api\\Protocol\\Def.mqh" #include "..\\..\\Tester\\Def.mqh" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ const long g_first_chart_id = ChartID(); //+------------------------------------------------------------------+ //| Add task | //+------------------------------------------------------------------+ class CFlowAiDataAddTask : public CWorkflowStep { private: TaskTester m_task; string m_str; //--- long m_chart_id_p; public: CFlowAiDataAddTask(void) : CWorkflowStep("AddTask", "AiDataTaskRunner", true, WORKFLOWBYLEO_STEP_FLAG_ON_CHART_EVENT) {} ~CFlowAiDataAddTask(void) {} //--- bool Init(const CYmlNode& parameters) override final; int Run() override final; void ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) override final; }; //--- Registramos WORKFLOWS_FACTORY_DEFINE_CREATOR(CFlowAiDataAddTask, AiDataAddTask, "AddTask", "AiDataTaskRunner") //+------------------------------------------------------------------+ bool CFlowAiDataAddTask::Init(const CYmlNode ¶meters) { //--- if(!m_wf.Env().TryGetAs("chart_id", m_chart_id_p)) { LogError("Fallo al obtener chart id", FUNCION_ACTUAL); return false; } //--- m_task.symbol = m_wf.TranslateStr(parameters["symbol"], ""); m_task.timeframe = m_wf.TranslateEnum(parameters["timeframe"], "_Period"); m_task.start_date = StringToTime(m_wf.TranslateStr(parameters["start_date"], "")); m_task.end_date = StringToTime(m_wf.TranslateStr(parameters["end_date"], "")); m_task.symbol_folder = m_wf.TranslateStr(parameters["symbol_folder"], m_task.symbol); m_task.label = m_wf.TranslateStr(parameters["label"], ""); m_task.label_id = m_wf.TranslateNumber(parameters["label_id"], "0"); m_task.set_file = m_wf.TranslateStr(parameters["set_file"], ""); m_str = m_task.ToStringFile(); return true; } //+------------------------------------------------------------------+ int CFlowAiDataAddTask::Run(void) { if(!::EventChartCustom(m_chart_id_p, AIDATATASKRUNER_API_ON_PARAM_CHANGE, g_first_chart_id, double(AIDATATASKRUNER_API_ADD_TASK_TO_TABLE), AiDataTaskRunnerEmpaquetar("wf", m_str))) { LogError("Fallo al enviar evento de add task", FUNCION_ACTUAL); return 1; } return 0; } //+------------------------------------------------------------------+ void CFlowAiDataAddTask::ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) { if(id == CHARTEVENT_CUSTOM + AIDATATASKRUNER_API_ON_PARAM_CHANGE) { // De salida: (api responde al que le envio datos) // lparam=evento respondiido // dparam=resultado // sparam=info (empaquetada ToolId|Val) if(lparam == AIDATATASKRUNER_API_ADD_TASK_TO_TABLE) { const int res = (dparam < 0.00 ? 1 : 0); if(res == 1) { static string id_tool, val; if(!AiDataTaskRunnerDesempaquetar(sparam, id_tool, val)) { LogError(StringFormat("Formato invalido de empauqetacion de telegram [event_id=%I64d], mensaje recibido por UI Panel:\n%s", lparam, sparam), FUNCION_ACTUAL); return; } //--- LogError(StringFormat("Fallo al ejecutar step, val: ", val), FUNCION_ACTUAL); } m_wf._RecibedEvent(res); } } } //+------------------------------------------------------------------+ //| Run all task | //+------------------------------------------------------------------+ class CFlowAiDataRunAllTask : public CWorkflowStep { private: long m_chart_id_p; int m_idx[]; int m_curr_pos; int m_ms_pool; bool m_strict; // determian si continuar por mas que una tarea halla fallado (delas que se estan ejecutando) //--- void OnTaskProcces(const string& sparam, const int res); public: CFlowAiDataRunAllTask(void) : CWorkflowStep("RunAllTask", "AiDataTaskRunner", true, WORKFLOWBYLEO_STEP_FLAG_ON_CHART_EVENT | WORKFLOWBYLEO_STEP_FLAG_ON_TIMER_EVENT) {} ~CFlowAiDataRunAllTask(void) {} //--- bool Init(const CYmlNode& parameters) override final; int Run() override final; void ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) override final; void OnTimerEvent() override final; }; //--- Registramos WORKFLOWS_FACTORY_DEFINE_CREATOR(CFlowAiDataRunAllTask, AiDataRunAlTask, "RunAllTask", "AiDataTaskRunner") //+------------------------------------------------------------------+ bool CFlowAiDataRunAllTask::Init(const CYmlNode ¶meters) { //--- if(!m_wf.Env().TryGetAs("chart_id", m_chart_id_p)) { LogError("Fallo al obtener chart id", FUNCION_ACTUAL); return false; } // Nada m_strict = m_wf.TranslateBool(parameters["strict"], "true"); m_ms_pool = m_wf.TranslateNumber(parameters["ms_pool"], "1000"); return true; } //+------------------------------------------------------------------+ int CFlowAiDataRunAllTask::Run(void) { if(!::EventChartCustom(m_chart_id_p, AIDATATASKRUNER_API_ON_PARAM_CHANGE, g_first_chart_id, double(AIDATATASKRUNER_API_EXECUTE_ALL_TASK_OF_TABLE), AiDataTaskRunnerEmpaquetar("wf", ""))) { LogError("Fallo al enviar evento de add task", FUNCION_ACTUAL); return 1; } return 0; } //+------------------------------------------------------------------+ void CFlowAiDataRunAllTask::ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) { //--- if(id == CHARTEVENT_CUSTOM + AIDATATASKRUNER_API_ON_PARAM_CHANGE) { // De salida: (api responde al que le envio datos) // lparam=evento respondiido // dparam=resultado // sparam=info (empaquetada ToolId|Val) //--- if(lparam == AIDATATASKRUNER_API_EXECUTE_ALL_TASK_OF_TABLE) { const int res = (dparam < 0.00 ? 1 : 0); //--- static string id_tool, val; if(!AiDataTaskRunnerDesempaquetar(sparam, id_tool, val)) { LogError(StringFormat("Formato invalido de empauqetacion de telegram [event_id=%I64d], mensaje recibido por UI Panel:\n%s", lparam, sparam), FUNCION_ACTUAL); return; } //--- if(res == 0) // Exito { const int start = val.Find("[", 0) + 1; const int end = val.Find("]", start) - 1; if(!StrTo::CstArray(m_idx, StringSubstrRange(val, start, end), ',')) // Fallo al parsear { LogError("Formato invalido de indices ejectuados, error al obtener indices", FUNCION_ACTUAL); m_wf._RecibedEvent(1); } // Ya tenmso los indices que consultaremos ::EventSetMillisecondTimer(m_ms_pool); } else { // Fin LogError(StringFormat("Fallo al ejecutar step, val: ", val), FUNCION_ACTUAL); m_wf._RecibedEvent(1); // le pasmos m_strict por derfecto fallara de lo contirao sera silencionso con esta ejecucion } return; } //--- if(lparam == AIDATATASKRUNER_API_GET_TASK_STATUS) { OnTaskProcces(sparam, (dparam < 0.00 ? 1 : 0)); } } } //+------------------------------------------------------------------+ void CFlowAiDataRunAllTask::OnTimerEvent() { if(!::EventChartCustom(m_chart_id_p, AIDATATASKRUNER_API_ON_PARAM_CHANGE, g_first_chart_id, double(AIDATATASKRUNER_API_GET_TASK_STATUS) , AiDataTaskRunnerEmpaquetar("wf", string(m_curr_pos)))) { LogError("Fallo al enviar evento de peticion de task", FUNCION_ACTUAL); } } //+------------------------------------------------------------------+ void CFlowAiDataRunAllTask::OnTaskProcces(const string &sparam, const int res) { //--- static string id_tool, val; if(!AiDataTaskRunnerDesempaquetar(sparam, id_tool, val)) { LogError(StringFormat("Formato invalido de empauqetacion de telegram [event_id=%I64d], mensaje recibido por UI Panel:\n%s", AIDATATASKRUNER_API_GET_TASK_STATUS, sparam), FUNCION_ACTUAL); return; } //--- if(res == 0) { const ENUM_AIEXECUTOR_TASK_STATE state = ENUM_AIEXECUTOR_TASK_STATE(int(val)); //--- if(state == AIEXECUTOR_TASK_STATE_FAILED) { if(m_strict) { LogError("Una tarea a fallado", FUNCION_ACTUAL); ::EventKillTimer(); m_wf._RecibedEvent(1); return; } else { // La elimianmos, no hacemos mas nada¿ DeleteArrayByIndex(m_idx, m_curr_pos++); } } else if(state == AIEXECUTOR_TASK_STATE_FINISHED) // Exito { // Eliminamos el indice actual que estabamos consultando DeleteArrayByIndex(m_idx, m_curr_pos++); } // Aun se ejecuta o es pendiente //--- if(::ArraySize(m_idx) < 1) { // Pasado entonces retornamos 0 ::EventKillTimer(); m_wf._RecibedEvent(0); } } else { LogError(StringFormat("Error al recibir estado de tarea, val:\n%s", val), FUNCION_ACTUAL); ::EventKillTimer(); m_wf._RecibedEvent(1); } } //+------------------------------------------------------------------+ //| Save task in file | //+------------------------------------------------------------------+ class CFlowAiDataSaveTaskInFile : public CWorkflowStep { private: string m_file_name; bool m_append; long m_chart_id_p; public: CFlowAiDataSaveTaskInFile(void) : CWorkflowStep("SaveTaskInFile", "AiDataTaskRunner", true, WORKFLOWBYLEO_STEP_FLAG_ON_CHART_EVENT) {} ~CFlowAiDataSaveTaskInFile(void) {} bool Init(const CYmlNode& parameters) override final; int Run() override final; void ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) override final; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ WORKFLOWS_FACTORY_DEFINE_CREATOR(CFlowAiDataSaveTaskInFile, AiDataSaveTaskInFile, "SaveTaskInFile", "AiDataTaskRunner") //+------------------------------------------------------------------+ bool CFlowAiDataSaveTaskInFile::Init(const CYmlNode ¶meters) { //--- if(!m_wf.Env().TryGetAs("chart_id", m_chart_id_p)) { LogError("Fallo al obtener chart id", FUNCION_ACTUAL); return false; } //--- m_file_name = m_wf.TranslateStr(parameters["file_name"], ""); m_append = m_wf.TranslateBool(parameters["only_no_proccesed"], "false"); return true; } //+------------------------------------------------------------------+ int CFlowAiDataSaveTaskInFile::Run(void) { const string val = StringFormat("%d%c%s", int(m_append), AIDATATASKRUNER_API_SEPARATOR_PARAM, m_file_name); if(!::EventChartCustom(m_chart_id_p, AIDATATASKRUNER_API_ON_PARAM_CHANGE, g_first_chart_id, double(AIDATATASKRUNER_API_SAVE_TASK_IN_FILE), AiDataTaskRunnerEmpaquetar("wf", val))) { LogError("Fallo al enviar evento de save task", FUNCION_ACTUAL); return 1; } return 0; } //+------------------------------------------------------------------+ void CFlowAiDataSaveTaskInFile::ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) { if(id == CHARTEVENT_CUSTOM + AIDATATASKRUNER_API_ON_PARAM_CHANGE) { if(lparam == AIDATATASKRUNER_API_SAVE_TASK_IN_FILE) { const int res = (dparam < 0.00 ? 1 : 0); if(res == 1) { static string id_tool, val; if(!AiDataTaskRunnerDesempaquetar(sparam, id_tool, val)) { LogError(StringFormat("Formato invalido [event_id=%I64d]:\n%s", lparam, sparam), FUNCION_ACTUAL); return; } LogError(StringFormat("Fallo al ejecutar step, val: %s", val), FUNCION_ACTUAL); } m_wf._RecibedEvent(res); } } } //+------------------------------------------------------------------+ //| Load task in file | //+------------------------------------------------------------------+ class CFlowAiDataLoadTaskInFile : public CWorkflowStep { private: string m_file_name; long m_chart_id_p; public: CFlowAiDataLoadTaskInFile(void) : CWorkflowStep("LoadTaskInFile", "AiDataTaskRunner", true, WORKFLOWBYLEO_STEP_FLAG_ON_CHART_EVENT) {} ~CFlowAiDataLoadTaskInFile(void) {} bool Init(const CYmlNode& parameters) override final; int Run() override final; void ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) override final; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ WORKFLOWS_FACTORY_DEFINE_CREATOR(CFlowAiDataLoadTaskInFile, AiDataLoadTaskInFile, "LoadTaskInFile", "AiDataTaskRunner") //+------------------------------------------------------------------+ bool CFlowAiDataLoadTaskInFile::Init(const CYmlNode ¶meters) { //--- if(!m_wf.Env().TryGetAs("chart_id", m_chart_id_p)) { LogError("Fallo al obtener chart id", FUNCION_ACTUAL); return false; } //--- m_file_name = m_wf.TranslateStr(parameters["file_name"], ""); return true; } //+------------------------------------------------------------------+ int CFlowAiDataLoadTaskInFile::Run(void) { if(!::EventChartCustom(m_chart_id_p, AIDATATASKRUNER_API_ON_PARAM_CHANGE, g_first_chart_id, double(AIDATATASKRUNER_API_LOAD_TASK_IN_FILE), AiDataTaskRunnerEmpaquetar("wf", m_file_name))) { LogError("Fallo al enviar evento de load task", FUNCION_ACTUAL); return 1; } return 0; } //+------------------------------------------------------------------+ void CFlowAiDataLoadTaskInFile::ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) { if(id == CHARTEVENT_CUSTOM + AIDATATASKRUNER_API_ON_PARAM_CHANGE) { if(lparam == AIDATATASKRUNER_API_LOAD_TASK_IN_FILE) { const int res = (dparam < 0.00 ? 1 : 0); if(res == 1) { static string id_tool, val; if(!AiDataTaskRunnerDesempaquetar(sparam, id_tool, val)) { LogError(StringFormat("Formato invalido [event_id=%I64d]:\n%s", lparam, sparam), FUNCION_ACTUAL); return; } LogError(StringFormat("Fallo al ejecutar step, val: %s", val), FUNCION_ACTUAL); } m_wf._RecibedEvent(res); } } } //+------------------------------------------------------------------+ //| Clean all task | //+------------------------------------------------------------------+ class CFlowAiDataCleanAllTask : public CWorkflowStep { private: long m_chart_id_p; public: CFlowAiDataCleanAllTask(void) : CWorkflowStep("CleanAllTask", "AiDataTaskRunner", true, WORKFLOWBYLEO_STEP_FLAG_ON_CHART_EVENT) {} ~CFlowAiDataCleanAllTask(void) {} bool Init(const CYmlNode& parameters) override final; int Run() override final; void ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) override final; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ WORKFLOWS_FACTORY_DEFINE_CREATOR(CFlowAiDataCleanAllTask, AiDataCleanAllTask, "CleanAllTask", "AiDataTaskRunner") //+------------------------------------------------------------------+ bool CFlowAiDataCleanAllTask::Init(const CYmlNode ¶meters) { //--- if(!m_wf.Env().TryGetAs("chart_id", m_chart_id_p)) { LogError("Fallo al obtener chart id", FUNCION_ACTUAL); return false; } return true; } //+------------------------------------------------------------------+ int CFlowAiDataCleanAllTask::Run(void) { if(!::EventChartCustom(m_chart_id_p, AIDATATASKRUNER_API_ON_PARAM_CHANGE, g_first_chart_id, double(AIDATATASKRUNER_API_CLEAN_ALL_TASK_OF_TABLE), AiDataTaskRunnerEmpaquetar("wf", ""))) { LogError("Fallo al enviar evento de clean all task", FUNCION_ACTUAL); return 1; } return 0; } //+------------------------------------------------------------------+ void CFlowAiDataCleanAllTask::ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) { if(id == CHARTEVENT_CUSTOM + AIDATATASKRUNER_API_ON_PARAM_CHANGE) { if(lparam == AIDATATASKRUNER_API_CLEAN_ALL_TASK_OF_TABLE) { const int res = (dparam < 0.00 ? 1 : 0); if(res == 1) { static string id_tool, val; if(!AiDataTaskRunnerDesempaquetar(sparam, id_tool, val)) { LogError(StringFormat("Formato invalido [event_id=%I64d]:\n%s", lparam, sparam), FUNCION_ACTUAL); return; } LogError(StringFormat("Fallo al ejecutar step, val: %s", val), FUNCION_ACTUAL); } m_wf._RecibedEvent(res); } } } //+------------------------------------------------------------------+ //| Load config in file | //+------------------------------------------------------------------+ class CFlowAiDataLoadConfigInFile : public CWorkflowStep { private: string m_file_name; long m_chart_id_p; public: CFlowAiDataLoadConfigInFile(void) : CWorkflowStep("LoadConfigInFile", "AiDataTaskRunner", true, WORKFLOWBYLEO_STEP_FLAG_ON_CHART_EVENT) {} ~CFlowAiDataLoadConfigInFile(void) {} bool Init(const CYmlNode& parameters) override final; int Run() override final; void ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) override final; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ WORKFLOWS_FACTORY_DEFINE_CREATOR(CFlowAiDataLoadConfigInFile, AiDataLoadConfigInFile, "LoadConfigInFile", "AiDataTaskRunner") //+------------------------------------------------------------------+ bool CFlowAiDataLoadConfigInFile::Init(const CYmlNode ¶meters) { //--- if(!m_wf.Env().TryGetAs("chart_id", m_chart_id_p)) { LogError("Fallo al obtener chart id", FUNCION_ACTUAL); return false; } //--- m_file_name = m_wf.TranslateStr(parameters["file_name"], ""); return true; } //+------------------------------------------------------------------+ int CFlowAiDataLoadConfigInFile::Run(void) { if(!::EventChartCustom(m_chart_id_p, AIDATATASKRUNER_API_ON_PARAM_CHANGE, g_first_chart_id, double(AIDATATASKRUNER_API_LOAD_CONFIG_IN_FILE), AiDataTaskRunnerEmpaquetar("wf", m_file_name))) { LogError("Fallo al enviar evento de load config", FUNCION_ACTUAL); return 1; } return 0; } //+------------------------------------------------------------------+ void CFlowAiDataLoadConfigInFile::ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) { if(id == CHARTEVENT_CUSTOM + AIDATATASKRUNER_API_ON_PARAM_CHANGE) { if(lparam == AIDATATASKRUNER_API_LOAD_CONFIG_IN_FILE) { const int res = (dparam < 0.00 ? 1 : 0); if(res == 1) { static string id_tool, val; if(!AiDataTaskRunnerDesempaquetar(sparam, id_tool, val)) { LogError(StringFormat("Formato invalido [event_id=%I64d]:\n%s", lparam, sparam), FUNCION_ACTUAL); return; } LogError(StringFormat("Fallo al ejecutar step, val: %s", val), FUNCION_ACTUAL); } m_wf._RecibedEvent(res); } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CFlowAiDataLoadConfigInPlace : public CWorkflowStep { private: string m_file_name; long m_chart_id_p; public: CFlowAiDataLoadConfigInPlace(void) : CWorkflowStep("LoadConfigInPlace", "AiDataTaskRunner", true, WORKFLOWBYLEO_STEP_FLAG_ON_CHART_EVENT) {} ~CFlowAiDataLoadConfigInPlace(void) {} bool Init(const CYmlNode& parameters) override final; int Run() override final; void ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) override final; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ WORKFLOWS_FACTORY_DEFINE_CREATOR(CFlowAiDataLoadConfigInPlace, AiDataLoadConfigInPlace, "LoadConfigInPlace", "AiDataTaskRunner") //+------------------------------------------------------------------+ bool CFlowAiDataLoadConfigInPlace::Init(const CYmlNode ¶meters) { //--- if(!m_wf.Env().TryGetAs("chart_id", m_chart_id_p)) { LogError("Fallo al obtener chart id", FUNCION_ACTUAL); return false; } bool comon; if(!m_wf.Env().TryGetBool("common_flag", comon)) { LogError("Fallo al obtener common flag", FUNCION_ACTUAL); return false; } //--- m_file_name = m_wf.TranslateStr(parameters["file_name"], ""); ::ResetLastError(); const int fh = FileOpen(m_file_name, FILE_WRITE | FILE_TXT | (comon ? FILE_COMMON : 0)); if(fh == INVALID_HANDLE) { LogError(StringFormat("Fallo al abrir el archivo = '%s', ultimo error = %d", m_file_name, ::GetLastError()), FUNCION_ACTUAL); return false; } //--- FileWrite(fh, m_wf.TranslateStr(parameters["progress_csv"], "")); FileWrite(fh, m_wf.TranslateStr(parameters["main_folder"], "")); FileWrite(fh, m_wf.TranslateStr(parameters["expert_path"], "")); FileWrite(fh, m_wf.TranslateStr(parameters["file_name_json_config"], "")); //--- FileClose(fh); //--- return true; } //+------------------------------------------------------------------+ int CFlowAiDataLoadConfigInPlace::Run(void) { if(!::EventChartCustom(m_chart_id_p, AIDATATASKRUNER_API_ON_PARAM_CHANGE, g_first_chart_id, double(AIDATATASKRUNER_API_LOAD_CONFIG_IN_FILE), AiDataTaskRunnerEmpaquetar("wf", m_file_name))) { LogError("Fallo al enviar evento de load config", FUNCION_ACTUAL); return 1; } return 0; } //+------------------------------------------------------------------+ void CFlowAiDataLoadConfigInPlace::ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) { if(id == CHARTEVENT_CUSTOM + AIDATATASKRUNER_API_ON_PARAM_CHANGE) { if(lparam == AIDATATASKRUNER_API_LOAD_CONFIG_IN_FILE) { const int res = (dparam < 0.00 ? 1 : 0); if(res == 1) { static string id_tool, val; if(!AiDataTaskRunnerDesempaquetar(sparam, id_tool, val)) { LogError(StringFormat("Formato invalido [event_id=%I64d]:\n%s", lparam, sparam), FUNCION_ACTUAL); return; } LogError(StringFormat("Fallo al ejecutar step, val: %s", val), FUNCION_ACTUAL); } m_wf._RecibedEvent(res); } } } //+------------------------------------------------------------------+ //| Save config in file | //+------------------------------------------------------------------+ class CFlowAiDataSaveConfigInFile : public CWorkflowStep { private: string m_file_name; long m_chart_id_p; public: CFlowAiDataSaveConfigInFile(void) : CWorkflowStep("SaveConfigInFile", "AiDataTaskRunner", true, WORKFLOWBYLEO_STEP_FLAG_ON_CHART_EVENT) {} ~CFlowAiDataSaveConfigInFile(void) {} bool Init(const CYmlNode& parameters) override final; int Run() override final; void ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) override final; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ WORKFLOWS_FACTORY_DEFINE_CREATOR(CFlowAiDataSaveConfigInFile, AiDataSaveConfigInFile, "SaveConfigInFile", "AiDataTaskRunner") //+------------------------------------------------------------------+ bool CFlowAiDataSaveConfigInFile::Init(const CYmlNode ¶meters) { //--- if(!m_wf.Env().TryGetAs("chart_id", m_chart_id_p)) { LogError("Fallo al obtener chart id", FUNCION_ACTUAL); return false; } //--- m_file_name = m_wf.TranslateStr(parameters["file_name"], ""); return true; } //+------------------------------------------------------------------+ int CFlowAiDataSaveConfigInFile::Run(void) { if(!::EventChartCustom(m_chart_id_p, AIDATATASKRUNER_API_ON_PARAM_CHANGE, g_first_chart_id, double(AIDATATASKRUNER_API_SAVE_CONFIG_IN_FILE), AiDataTaskRunnerEmpaquetar("wf", m_file_name))) { LogError("Fallo al enviar evento de save config", FUNCION_ACTUAL); return 1; } return 0; } //+------------------------------------------------------------------+ void CFlowAiDataSaveConfigInFile::ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) { if(id == CHARTEVENT_CUSTOM + AIDATATASKRUNER_API_ON_PARAM_CHANGE) { if(lparam == AIDATATASKRUNER_API_SAVE_CONFIG_IN_FILE) { const int res = (dparam < 0.00 ? 1 : 0); if(res == 1) { static string id_tool, val; if(!AiDataTaskRunnerDesempaquetar(sparam, id_tool, val)) { LogError(StringFormat("Formato invalido [event_id=%I64d]:\n%s", lparam, sparam), FUNCION_ACTUAL); return; } LogError(StringFormat("Fallo al ejecutar step, val: %s", val), FUNCION_ACTUAL); } m_wf._RecibedEvent(res); } } } //+------------------------------------------------------------------+ #endif // AIDATATASKRUNNER_BACKEND_WORKFLOWS_FLOWS_ALLFLOWS_MQH