AiDataTaskRuner/Utils/FolderTaskToCSV2.mq5

251 lines
7.2 KiB
MQL5
Raw Permalink Normal View History

2026-04-16 12:28:07 -05:00
//+------------------------------------------------------------------+
//| 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 <TSN\\MQLArticles\\Utils\\File.mqh>
//+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+