//+------------------------------------------------------------------+ //| FolderTaskToCSV2.mq5 | //| Copyright 2026,Niquel Mendoza. | //| https://www.mql5.com/en/users/nique_372 | //+------------------------------------------------------------------+ #property copyright "Copyright 2026,Niquel Mendoza." #property link "https://www.mql5.com/en/users/nique_372" #property version "1.00" #property strict //+------------------------------------------------------------------+ //| Include | //+------------------------------------------------------------------+ #include "..\\Backend\\Tester\\Saver.mqh" #include //+------------------------------------------------------------------+ //| Inputs | //+------------------------------------------------------------------+ input string InpFolder = ""; input bool InpFolderIsInCommon = true; input string InpParamActiveGenerateName = "InpGenerateMode"; input datetime InpDataStartDate = 0; input datetime InpDataEndDate = 0; input string InpCsvFileNameOutput = "task.csv"; input bool InpCsvFileNameOutputIsInCommon = true; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- TaskTester tasks[]; int profundidad = 0; string sym = ""; ENUM_TIMEFRAMES tf = PERIOD_CURRENT; //--- ulong antes = GetTickCount64(); Print(ProccesFolder(InpFolder, tasks, profundidad, sym, tf)); ulong desp = GetTickCount64(); PrintFormat("res = %I64u ", (desp - antes)); //--- CTaskSaver saver; string ms; if(!saver.Save(InpCsvFileNameOutput, tasks, ArraySize(tasks), (InpFolderIsInCommon ? FILE_COMMON : 0), false, ms)) { Print(ms); } //--- return(INIT_FAILED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool ProccesFolder(const string& main_folder, TaskTester& taskes[], int& prof, string& curr_symbol, ENUM_TIMEFRAMES& curr_tf) { //--- string fn = ""; const long handle = FileFindFirst(main_folder + "*", fn, (InpFolderIsInCommon ? FILE_COMMON : 0)); if(handle == INVALID_HANDLE) { Print("No hay archivos en: ", main_folder); prof--; return true; } //--- do { const string full_path = main_folder + fn; //--- if(fn[StringLen(fn) - 1] == '\\') { prof++; if(prof == 1) { // Carpeta simbolo curr_symbol = fn; StringSetLength(curr_symbol, StringLen(curr_symbol) - 1); } else if(prof == 2) { string tf_name = fn; StringSetLength(tf_name, StringLen(tf_name) - 1); curr_tf = StrShortTimeframeToEnumNoRef(tf_name); } else { Print("No se procesa folder con mas de 2 de profundidad"); prof--; continue; } //--- if(!ProccesFolder(full_path, taskes, prof, curr_symbol, curr_tf)) { PrintFormat("Fallo al procesar path =%s", full_path); return false; } } else { //--- const int pos = ArraySize(taskes); ArrayResize(taskes, pos + 1); //--- taskes[pos].symbol = curr_symbol; taskes[pos].symbol_folder = curr_symbol; taskes[pos].timeframe = curr_tf; // TF desde carpeta, no desde setfile //--- if(!ProccesSetFile(full_path, taskes[pos])) { printf("Fallo al procesar set file path = %s, se omitira para no dañar", full_path); return false; } } } while(FileFindNext(handle, fn)); //--- FileFindClose(handle); //--- if(prof) { prof--; // Reseteamos TF al salir de carpeta timeframe if(prof == 1) curr_tf = WRONG_VALUE; // err else if(prof == 0) curr_symbol = ""; } //--- return true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool ProccesSetFile(const string& path, TaskTester& task) { //--- ::ResetLastError(); int fh = FileOpen(path, FILE_READ | FILE_BIN | (InpFolderIsInCommon ? FILE_COMMON : 0)); if(fh == INVALID_HANDLE) { PrintFormat("Fallo al abrir el archivo =%s, ultimo error = %d", path, ::GetLastError()); return false; } //--- const ulong size = FileSize(fh); string content = FileReadString(fh, int(size)); FileClose(fh); //--- TF ya asignado desde carpeta, solo completamos el resto task.label_id = 0; task.label = FileRemoveExtensionNoRef(GetPureFileName(path)); task.set_file = (InpFolderIsInCommon ? (TERMINAL_MT5_COMMON_PATH + "\\Files\\") : (TERMINAL_MT5_ROOT + "Files\\")) + path; task.start_date = InpDataStartDate; task.end_date = InpDataEndDate; //--- Modificamos el parametro de aidata gen int start_t = StringFind(content, InpParamActiveGenerateName); if(start_t == -1) { PrintFormat("No se encontrol el paramtro activar aidata: '%s', en setfile", InpParamActiveGenerateName); return false; } int start_e = StringFind(content, "=", start_t); if(start_e == -1) { Print("No se encontrol el ="); return false; } int end = StringFind(content, "|", start_e); if(end == -1) { Print("No se encontrol el |"); return false; } //--- start_e++; end--; //--- int pos = 0; //Inp=false| const static ushort short_arr_true[4] = {'t', 'r', 'u', 'e'}; for(int i = start_e; i <= end; i++) { if(pos >= 4) { DeleteFromStr(content, i, end); break; } content.SetChar(i, short_arr_true[pos++]); } //--- ::ResetLastError(); fh = FileOpen(path, FILE_WRITE | FILE_TXT | (InpFolderIsInCommon ? FILE_COMMON : 0), 0); if(fh == INVALID_HANDLE) { PrintFormat("Fallo al abrir el archivo =%s, ultimo error = %d", path, ::GetLastError()); return false; } ::FileWriteString(fh, content); FileClose(fh); //--- return true; } //+------------------------------------------------------------------+ // [a][b][c][d][e] void DeleteFromStr(string& str, int pos_from, int pos_to) { const int count = (pos_to - pos_from) + 1; const int total = StringLen(str) - count; for(int i = pos_from; i < total; i++) { str.SetChar(i, str[i + count]); } str.Truncate(total); } //+------------------------------------------------------------------+