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>
2026-04-30 16:09:33 -05:00
# include <TSN\\MQLArticles\\Utils\\StrMacth.mqh>
2026-04-16 12:28:07 -05:00
//+------------------------------------------------------------------+
//| 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 ;
2026-04-30 16:09:33 -05:00
input string InpStrMatchExcluyed = " " ;
input string InpStrMatchIncluyed = " *.set " ;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-07-15 14:10:22 -05:00
TSN : : CFolderOpsBase g_simple_str_math ;
2026-04-30 16:09:33 -05:00
2026-04-16 12:28:07 -05:00
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit ( )
{
2026-04-30 16:09:33 -05:00
//---
g_simple_str_math . SetArrExcluyed ( InpStrMatchExcluyed , ' | ' ) ;
g_simple_str_math . SetArrIncluyed ( InpStrMatchIncluyed , ' | ' ) ;
2026-04-16 12:28:07 -05:00
//---
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 ;
2026-04-30 16:09:33 -05:00
//---
if ( g_simple_str_math . IsFileExcluyed ( full_path ) )
continue ;
if ( ! g_simple_str_math . IsFileIncluyed ( full_path ) )
continue ;
2026-04-16 12:28:07 -05:00
//---
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 ) ;
}
//+------------------------------------------------------------------+