//+------------------------------------------------------------------+ //| Tools.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_TLGM_TOOLS_TOOLS_MQH #define AIDATATASKRUNNER_BACKEND_TLGM_TOOLS_TOOLS_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //--- Reciber #include #include //--- Protocolo de comunicacion con telegram #include "..\\Protocol\\Def.mqh" //--- Extra tools #include //+------------------------------------------------------------------+ //| Generador de id interno (correlacion con ChartEvent, no con el | //| id de tool_call del LLM: Run() es sincrono y ya no lo recibe) | //+------------------------------------------------------------------+ namespace TSN { //--- static int g_aitaskrunner_tool_counter = 0; //--- #define AiTaskRunnerGenId(name) StringFormat("tlg_aitaskruner_%s_%d", name, ++g_aitaskrunner_tool_counter) //+------------------------------------------------------------------+ //| name: aidatataskrunner_get_task_total | //| desc: Returns the total number of tasks in the table | //| params: none | //+------------------------------------------------------------------+ class CAiTaskRunnerToolGetTaskTotal : public CLLmTool { private: const long m_panel_chart_id; const long m_bot_chart_id; public: CAiTaskRunnerToolGetTaskTotal(const long panel_chart_id, const long bot_chart_id) : CLLmTool("aidatataskrunner_get_task_total"), m_panel_chart_id(panel_chart_id), m_bot_chart_id(bot_chart_id) {} ~CAiTaskRunnerToolGetTaskTotal() {} //--- void Run(CJsonNode ¶m, CJsonBuilderStr* &out) override final { out = m_shared_builder; const string id = AiTaskRunnerGenId(m_name); m_shared_builder.PutChar('"'); m_shared_builder.Obj(); if(!::EventChartCustom(m_panel_chart_id, AIDATATASKRUNER_API_ON_PARAM_CHANGE, m_bot_chart_id, double(AIDATATASKRUNER_API_TASK_TOTAL), AiDataTaskRunnerEmpaquetar(id, ""))) { m_shared_builder.KeyWV("ok").Val(false); m_shared_builder.KeyWV("error").ValS("Failed to dispatch get_task_total"); } else { m_shared_builder.KeyWV("ok").Val(true); m_shared_builder.KeyWV("result").ValS("Queued | Result will appear in chat"); } m_shared_builder.EndObj(); m_shared_builder.PutChar('"'); } }; //+------------------------------------------------------------------+ //| name: aidatataskrunner_clean_all_tasks | //| desc: Cleans all tasks from the table that are not running or | //| queued | //| params: none | //+------------------------------------------------------------------+ class CAiTaskRunnerToolCleanAllTasks : public CLLmTool { private: const long m_panel_chart_id; const long m_bot_chart_id; public: CAiTaskRunnerToolCleanAllTasks(const long panel_chart_id, const long bot_chart_id) : CLLmTool("aidatataskrunner_clean_all_tasks"), m_panel_chart_id(panel_chart_id), m_bot_chart_id(bot_chart_id) {} ~CAiTaskRunnerToolCleanAllTasks() {} //--- void Run(CJsonNode ¶m, CJsonBuilderStr* &out) override final { out = m_shared_builder; const string id = AiTaskRunnerGenId(m_name); m_shared_builder.PutChar('"'); m_shared_builder.Obj(); if(!::EventChartCustom(m_panel_chart_id, AIDATATASKRUNER_API_ON_PARAM_CHANGE, m_bot_chart_id, double(AIDATATASKRUNER_API_CLEAN_ALL_TASK_OF_TABLE), AiDataTaskRunnerEmpaquetar(id, ""))) { m_shared_builder.KeyWV("ok").Val(false); m_shared_builder.KeyWV("error").ValS("Failed to dispatch clean_all_tasks"); } else { m_shared_builder.KeyWV("ok").Val(true); m_shared_builder.KeyWV("result").ValS("Queued | Cleaning tasks, result will appear in chat"); } m_shared_builder.EndObj(); m_shared_builder.PutChar('"'); } }; //+------------------------------------------------------------------+ //| name: aidatataskrunner_execute_all_tasks | //| desc: Executes all pending tasks in the table | //| params: none | //+------------------------------------------------------------------+ class CAiTaskRunnerToolExecuteAllTasks : public CLLmTool { private: const long m_panel_chart_id; const long m_bot_chart_id; public: CAiTaskRunnerToolExecuteAllTasks(const long panel_chart_id, const long bot_chart_id) : CLLmTool("aidatataskrunner_execute_all_tasks"), m_panel_chart_id(panel_chart_id), m_bot_chart_id(bot_chart_id) {} ~CAiTaskRunnerToolExecuteAllTasks() {} //--- void Run(CJsonNode ¶m, CJsonBuilderStr* &out) override final { out = m_shared_builder; const string id = AiTaskRunnerGenId(m_name); m_shared_builder.PutChar('"'); m_shared_builder.Obj(); if(!::EventChartCustom(m_panel_chart_id, AIDATATASKRUNER_API_ON_PARAM_CHANGE, m_bot_chart_id, double(AIDATATASKRUNER_API_EXECUTE_ALL_TASK_OF_TABLE), AiDataTaskRunnerEmpaquetar(id, ""))) { m_shared_builder.KeyWV("ok").Val(false); m_shared_builder.KeyWV("error").ValS("Failed to dispatch execute_all_tasks"); } else { m_shared_builder.KeyWV("ok").Val(true); m_shared_builder.KeyWV("result").ValS("Queued | Executing all tasks, result will appear in chat"); } m_shared_builder.EndObj(); m_shared_builder.PutChar('"'); } }; //+------------------------------------------------------------------+ //| name: aidatataskrunner_get_main_folder | //| desc: Returns the main base folder path used by AiDataTaskRunner | //| params: none | //+------------------------------------------------------------------+ class CAiTaskRunnerToolGetMainFolder : public CLLmTool { private: const long m_panel_chart_id; const long m_bot_chart_id; public: CAiTaskRunnerToolGetMainFolder(const long panel_chart_id, const long bot_chart_id) : CLLmTool("aidatataskrunner_get_main_folder"), m_panel_chart_id(panel_chart_id), m_bot_chart_id(bot_chart_id) {} ~CAiTaskRunnerToolGetMainFolder() {} //--- void Run(CJsonNode ¶m, CJsonBuilderStr* &out) override final { out = m_shared_builder; const string id = AiTaskRunnerGenId(m_name); m_shared_builder.PutChar('"'); m_shared_builder.Obj(); if(!::EventChartCustom(m_panel_chart_id, AIDATATASKRUNER_API_ON_PARAM_CHANGE, m_bot_chart_id, double(AIDATATASKRUNER_API_MAIN_FOLDER), AiDataTaskRunnerEmpaquetar(id, ""))) { m_shared_builder.KeyWV("ok").Val(false); m_shared_builder.KeyWV("error").ValS("Failed to dispatch get_main_folder"); } else { m_shared_builder.KeyWV("ok").Val(true); m_shared_builder.KeyWV("result").ValS("Queued | Result will appear in chat"); } m_shared_builder.EndObj(); m_shared_builder.PutChar('"'); } }; //+------------------------------------------------------------------+ //| name: aidatataskrunner_get_task_folder | //| desc: Returns the tasks folder path used by AiDataTaskRunner | //| params: none | //+------------------------------------------------------------------+ class CAiTaskRunnerToolGetTaskFolder : public CLLmTool { private: const long m_panel_chart_id; const long m_bot_chart_id; public: CAiTaskRunnerToolGetTaskFolder(const long panel_chart_id, const long bot_chart_id) : CLLmTool("aidatataskrunner_get_task_folder"), m_panel_chart_id(panel_chart_id), m_bot_chart_id(bot_chart_id) {} ~CAiTaskRunnerToolGetTaskFolder() {} //--- void Run(CJsonNode ¶m, CJsonBuilderStr* &out) override final { out = m_shared_builder; const string id = AiTaskRunnerGenId(m_name); m_shared_builder.PutChar('"'); m_shared_builder.Obj(); if(!::EventChartCustom(m_panel_chart_id, AIDATATASKRUNER_API_ON_PARAM_CHANGE, m_bot_chart_id, double(AIDATATASKRUNER_API_TASK_FOLDER), AiDataTaskRunnerEmpaquetar(id, ""))) { m_shared_builder.KeyWV("ok").Val(false); m_shared_builder.KeyWV("error").ValS("Failed to dispatch get_task_folder"); } else { m_shared_builder.KeyWV("ok").Val(true); m_shared_builder.KeyWV("result").ValS("Queued | Result will appear in chat"); } m_shared_builder.EndObj(); m_shared_builder.PutChar('"'); } }; //+------------------------------------------------------------------+ //| name: aidatataskrunner_is_in_commonfolder | //| desc: Returns whether AiDataTaskRunner is using the MT5 common | //| folder | //| params: none | //+------------------------------------------------------------------+ class CAiTaskRunnerToolIsInCommonFolder : public CLLmTool { private: const long m_panel_chart_id; const long m_bot_chart_id; public: CAiTaskRunnerToolIsInCommonFolder(const long panel_chart_id, const long bot_chart_id) : CLLmTool("aidatataskrunner_is_in_commonfolder"), m_panel_chart_id(panel_chart_id), m_bot_chart_id(bot_chart_id) {} ~CAiTaskRunnerToolIsInCommonFolder() {} //--- void Run(CJsonNode ¶m, CJsonBuilderStr* &out) override final { out = m_shared_builder; const string id = AiTaskRunnerGenId(m_name); m_shared_builder.PutChar('"'); m_shared_builder.Obj(); if(!::EventChartCustom(m_panel_chart_id, AIDATATASKRUNER_API_ON_PARAM_CHANGE, m_bot_chart_id, double(AIDATATASKRUNER_API_IS_IN_COMMON_FOLDER), AiDataTaskRunnerEmpaquetar(id, ""))) { m_shared_builder.KeyWV("ok").Val(false); m_shared_builder.KeyWV("error").ValS("Failed to dispatch is_in_commonfolder"); } else { m_shared_builder.KeyWV("ok").Val(true); m_shared_builder.KeyWV("result").ValS("Queued | Result will appear in chat"); } m_shared_builder.EndObj(); m_shared_builder.PutChar('"'); } }; //+------------------------------------------------------------------+ //| name: aidatataskrunner_add_task | //| desc: Adds a new backtest task to the AiDataTaskRunner table | //| params (definir schema en JSON, requeridos: symbol, start_date, | //| end_date): | //| symbol string Trading symbol e.g. EURUSD, XAUUSD | //| start_date string Start date format YYYY.MM.DD HH:MM | //| end_date string End date format YYYY.MM.DD HH:MM | //| timeframe string enum: _Period,M1,M2,M3,M4,M5,M6,M10, | //| M12,M15,M20,M30,H1,H2,H3,H4,H6,H8,H12, | //| D1,W1,MN1 | //| set_file string Optional .set file path for EA params | //| symbol_folder string Optional subfolder name for grouping | //| label string Optional strategy name (folder prefix) | //| label_id string Optional variant id, default 0 | //+------------------------------------------------------------------+ class CAiTaskRunnerToolAddTask : public CLLmTool { private: const long m_panel_chart_id; const long m_bot_chart_id; public: CAiTaskRunnerToolAddTask(const long panel_chart_id, const long bot_chart_id) : CLLmTool("aidatataskrunner_add_task"), m_panel_chart_id(panel_chart_id), m_bot_chart_id(bot_chart_id) {} ~CAiTaskRunnerToolAddTask(void) {} void Run(CJsonNode ¶m, CJsonBuilderStr* &out) override final; }; //+------------------------------------------------------------------+ void CAiTaskRunnerToolAddTask::Run(CJsonNode ¶m, CJsonBuilderStr* &out) { out = m_shared_builder; const string symbol = param["symbol"].ToString(); const string start_date = param["start_date"].ToString(); const string end_date = param["end_date"].ToString(); const int timeframe = CEnumRegBasis::GetValNoRef(param["timeframe"].ToString("_Period"), _Period); const string set_file = param["set_file"].ToString(""); const string symbol_folder = param["symbol_folder"].ToString(""); const string label = param["label"].ToString(""); const string label_id = param["label_id"].ToString("0"); //--- /* //--- __forceinline string ToStringFile() { return StringFormat("%d|%s|%s|%s|%s|%s|%s|%d", int(timeframe), // [0] symbol, // [1] set_file, // [2] TimeToString(start_date), // [3] TimeToString(end_date), // [4] symbol_folder, // [5] label, // [6] label_id); // [7] } */ //--- const string val = StringFormat("%d|%s|%s|%s|%s|%s|%s|%s", timeframe, symbol, set_file, start_date, end_date, symbol_folder, label, label_id); //--- const string id = AiTaskRunnerGenId(m_name); m_shared_builder.PutChar('"'); m_shared_builder.Obj(); if(!::EventChartCustom(m_panel_chart_id, AIDATATASKRUNER_API_ON_PARAM_CHANGE, m_bot_chart_id, double(AIDATATASKRUNER_API_ADD_TASK_TO_TABLE), AiDataTaskRunnerEmpaquetar(id, val))) { m_shared_builder.KeyWV("ok").Val(false); m_shared_builder.KeyWV("error").ValS("Failed to dispatch add_task"); } else { m_shared_builder.KeyWV("ok").Val(true); m_shared_builder.KeyWV("result").ValS("Queued | Task added to table"); } m_shared_builder.EndObj(); m_shared_builder.PutChar('"'); } //+------------------------------------------------------------------+ //| name: aidatataskrunner_save_tasks_to_file | //| desc: Saves all tasks to a CSV file. Can filter to save only | //| unfinished tasks (pending, queued or in process) | //| params (requeridos: file_name, only_unfinished): | //| file_name string Absolute path inside MT5 Files\\ or | //| Common\\Files\\, extension .csv | //| only_unfinished boolean If true saves only pending/queued/in- | //| process tasks, else saves all | //+------------------------------------------------------------------+ class CAiTaskRunnerToolSaveTasksToFile : public CLLmTool { private: const long m_panel_chart_id; const long m_bot_chart_id; public: CAiTaskRunnerToolSaveTasksToFile(const long panel_chart_id, const long bot_chart_id) : CLLmTool("aidatataskrunner_save_tasks_to_file"), m_panel_chart_id(panel_chart_id), m_bot_chart_id(bot_chart_id) {} ~CAiTaskRunnerToolSaveTasksToFile(void) {} void Run(CJsonNode ¶m, CJsonBuilderStr* &out) override final; }; //+------------------------------------------------------------------+ void CAiTaskRunnerToolSaveTasksToFile::Run(CJsonNode ¶m, CJsonBuilderStr* &out) { out = m_shared_builder; const string file_name = param["file_name"].ToString(); const bool only_unfinished = param["only_unfinished"].ToBool(false); //--- const string val = StringFormat("%d|%s", int(only_unfinished), file_name); //--- const string id = AiTaskRunnerGenId(m_name); m_shared_builder.PutChar('"'); m_shared_builder.Obj(); if(!::EventChartCustom(m_panel_chart_id, AIDATATASKRUNER_API_ON_PARAM_CHANGE, m_bot_chart_id, double(AIDATATASKRUNER_API_SAVE_TASK_IN_FILE), AiDataTaskRunnerEmpaquetar(id, val))) { m_shared_builder.KeyWV("ok").Val(false); m_shared_builder.KeyWV("error").ValS("Failed to dispatch save_tasks_to_file"); } else { m_shared_builder.KeyWV("ok").Val(true); m_shared_builder.KeyWV("result").ValS("Queued | Saving tasks to file"); } m_shared_builder.EndObj(); m_shared_builder.PutChar('"'); } //+------------------------------------------------------------------+ //| name: aidatataskrunner_load_tasks_from_file | //| desc: Loads tasks from a CSV file into the table | //| params (requerido: file_name): | //| file_name string Absolute path inside MT5 Files\\ or | //| Common\\Files\\, extension .csv | //+------------------------------------------------------------------+ class CAiTaskRunnerToolLoadTasksFromFile : public CLLmTool { private: const long m_panel_chart_id; const long m_bot_chart_id; public: CAiTaskRunnerToolLoadTasksFromFile(const long panel_chart_id, const long bot_chart_id) : CLLmTool("aidatataskrunner_load_tasks_from_file"), m_panel_chart_id(panel_chart_id), m_bot_chart_id(bot_chart_id) {} ~CAiTaskRunnerToolLoadTasksFromFile(void) {} void Run(CJsonNode ¶m, CJsonBuilderStr* &out) override final; }; //+------------------------------------------------------------------+ void CAiTaskRunnerToolLoadTasksFromFile::Run(CJsonNode ¶m, CJsonBuilderStr* &out) { out = m_shared_builder; const string file_name = param["file_name"].ToString(); //--- const string id = AiTaskRunnerGenId(m_name); m_shared_builder.PutChar('"'); m_shared_builder.Obj(); if(!::EventChartCustom(m_panel_chart_id, AIDATATASKRUNER_API_ON_PARAM_CHANGE, m_bot_chart_id, double(AIDATATASKRUNER_API_LOAD_TASK_IN_FILE), AiDataTaskRunnerEmpaquetar(id, file_name))) { m_shared_builder.KeyWV("ok").Val(false); m_shared_builder.KeyWV("error").ValS("Failed to dispatch load_tasks_from_file"); } else { m_shared_builder.KeyWV("ok").Val(true); m_shared_builder.KeyWV("result").ValS("Queued | Loading tasks from file"); } m_shared_builder.EndObj(); m_shared_builder.PutChar('"'); } //+------------------------------------------------------------------+ //| name: aidatataskrunner_load_config | //| desc: Loads the panel configuration from a file | //| params (requerido: file_name): | //| file_name string Absolute path inside MT5 Files\\ or | //| Common\\Files\\, extension .txt | //+------------------------------------------------------------------+ class CAiTaskRunnerToolLoadConfig : public CLLmTool { private: const long m_panel_chart_id; const long m_bot_chart_id; public: CAiTaskRunnerToolLoadConfig(const long panel_chart_id, const long bot_chart_id) : CLLmTool("aidatataskrunner_load_config"), m_panel_chart_id(panel_chart_id), m_bot_chart_id(bot_chart_id) {} ~CAiTaskRunnerToolLoadConfig(void) {} void Run(CJsonNode ¶m, CJsonBuilderStr* &out) override final; }; //+------------------------------------------------------------------+ void CAiTaskRunnerToolLoadConfig::Run(CJsonNode ¶m, CJsonBuilderStr* &out) { out = m_shared_builder; const string file_name = param["file_name"].ToString(); //--- const string id = AiTaskRunnerGenId(m_name); m_shared_builder.PutChar('"'); m_shared_builder.Obj(); if(!::EventChartCustom(m_panel_chart_id, AIDATATASKRUNER_API_ON_PARAM_CHANGE, m_bot_chart_id, double(AIDATATASKRUNER_API_LOAD_CONFIG_IN_FILE), AiDataTaskRunnerEmpaquetar(id, file_name))) { m_shared_builder.KeyWV("ok").Val(false); m_shared_builder.KeyWV("error").ValS("Failed to dispatch load_config"); } else { m_shared_builder.KeyWV("ok").Val(true); m_shared_builder.KeyWV("result").ValS("Queued | Loading config from file"); } m_shared_builder.EndObj(); m_shared_builder.PutChar('"'); } //+------------------------------------------------------------------+ //| name: aidatataskrunner_save_config | //| desc: Saves the current panel configuration to a file | //| params (requerido: file_name): | //| file_name string Absolute path inside MT5 Files\\ or | //| Common\\Files\\, extension .txt | //+------------------------------------------------------------------+ class CAiTaskRunnerToolSaveConfig : public CLLmTool { private: const long m_panel_chart_id; const long m_bot_chart_id; public: CAiTaskRunnerToolSaveConfig(const long panel_chart_id, const long bot_chart_id) : CLLmTool("aidatataskrunner_save_config"), m_panel_chart_id(panel_chart_id), m_bot_chart_id(bot_chart_id) {} ~CAiTaskRunnerToolSaveConfig(void) {} void Run(CJsonNode ¶m, CJsonBuilderStr* &out) override final; }; //+------------------------------------------------------------------+ void CAiTaskRunnerToolSaveConfig::Run(CJsonNode ¶m, CJsonBuilderStr* &out) { out = m_shared_builder; const string file_name = param["file_name"].ToString(); //--- const string id = AiTaskRunnerGenId(m_name); m_shared_builder.PutChar('"'); m_shared_builder.Obj(); if(!::EventChartCustom(m_panel_chart_id, AIDATATASKRUNER_API_ON_PARAM_CHANGE, m_bot_chart_id, double(AIDATATASKRUNER_API_SAVE_CONFIG_IN_FILE), AiDataTaskRunnerEmpaquetar(id, file_name))) { m_shared_builder.KeyWV("ok").Val(false); m_shared_builder.KeyWV("error").ValS("Failed to dispatch save_config"); } else { m_shared_builder.KeyWV("ok").Val(true); m_shared_builder.KeyWV("result").ValS("Queued | Saving config to file"); } m_shared_builder.EndObj(); m_shared_builder.PutChar('"'); } //+------------------------------------------------------------------+ //| name: aidatataskrunner_get_task_by_index | //| desc: Returns the details of a task by its index in the table | //| params (requerido: index): | //| index integer Zero-based index of the task in the table. Use | //| aidatataskrunner_get_task_total to know total | //+------------------------------------------------------------------+ class CAiTaskRunnerToolGetTaskByIndex : public CLLmTool { private: const long m_panel_chart_id; const long m_bot_chart_id; public: CAiTaskRunnerToolGetTaskByIndex(const long panel_chart_id, const long bot_chart_id) : CLLmTool("aidatataskrunner_get_task_by_index"), m_panel_chart_id(panel_chart_id), m_bot_chart_id(bot_chart_id) {} ~CAiTaskRunnerToolGetTaskByIndex(void) {} void Run(CJsonNode ¶m, CJsonBuilderStr* &out) override final; }; //+------------------------------------------------------------------+ void CAiTaskRunnerToolGetTaskByIndex::Run(CJsonNode ¶m, CJsonBuilderStr* &out) { out = m_shared_builder; const string index = param["index"].ToString(); //--- const string id = AiTaskRunnerGenId(m_name); m_shared_builder.PutChar('"'); m_shared_builder.Obj(); if(!::EventChartCustom(m_panel_chart_id, AIDATATASKRUNER_API_ON_PARAM_CHANGE, m_bot_chart_id, double(AIDATATASKRUNER_API_GET_TASK_BY_INDEX), AiDataTaskRunnerEmpaquetar(id, index))) { m_shared_builder.KeyWV("ok").Val(false); m_shared_builder.KeyWV("error").ValS("Failed to dispatch get_task_by_index"); } else { m_shared_builder.KeyWV("ok").Val(true); m_shared_builder.KeyWV("result").ValS("Queued | Result will appear in chat"); } m_shared_builder.EndObj(); m_shared_builder.PutChar('"'); } } //+------------------------------------------------------------------+ #endif // AIDATATASKRUNNER_BACKEND_TLGM_TOOLS_TOOLS_MQH