//+------------------------------------------------------------------+ //| ExtraFunctions.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 MQLARTICLES_UTILS_EXTRAFUNCTIONS_MQH #define MQLARTICLES_UTILS_EXTRAFUNCTIONS_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include "..\\..\\ExtraCodes\\MultiTester\\MTTester.mqh" #include "Basic.mqh" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void TerminalAutoTrading(bool enable) { //--- const bool e = (bool)TerminalInfoInteger(TERMINAL_TRADE_ALLOWED); if(e == enable) return; //--- HANDLE hwnd = MTTESTER::GetTerminalHandle(); if(!hwnd) return; //--- user32::SetForegroundWindow(hwnd); Sleep(50); //--- user32::keybd_event(0x11, 0, 0, 0); user32::keybd_event(0x45, 0, 0, 0); user32::keybd_event(0x45, 0, 2, 0); user32::keybd_event(0x11, 0, 2, 0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void ExtractLogLinesAsArray(const datetime log_file_date, const datetime start_dt, const datetime end_dt, string& arr_lines[]) { //--- Path al log de hoy static MqlDateTime dt; CTimeUtils::TimeToStructFast(log_file_date, dt); const string log_file_path = StringFormat("%s\\MQL5\\Logs\\%04d%02d%02d.log", TerminalInfoString(TERMINAL_DATA_PATH), dt.year, dt.mon, dt.day); //--- Abrimos via WinAPI const HANDLE h = kernel32::CreateFileW(log_file_path, 0x80000000, // GENERIC_READ 0x00000001 | 0x00000002, // FILE_SHARE_READ | FILE_SHARE_WRITE NULL, 3, // OPEN_EXISTING 0x80, // FILE_ATTRIBUTE_NORMAL 0); if(h == -1) { FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("No se pudo abrir el archivo, error=%d, file:\n%s", kernel32::GetLastError(), log_file_path)); return; } //--- Tamanio long file_size = 0; if(!kernel32::GetFileSizeEx(h, file_size) || file_size <= 2) { FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("Archivo vacio o fallo GetFileSizeEx | error=%d", kernel32::GetLastError())); kernel32::CloseHandle(h); return; } //--- Leemos const uint num_shorts = uint(file_size >> 1); ushort buffer[]; ArrayResize(buffer, num_shorts); uint bytes_read = 0; OVERLAPPED ov = {}; if(!kernel32::ReadFile(h, buffer, (uint)file_size, bytes_read, ov)) { FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("kernel32::ReadFile | error=%d", kernel32::GetLastError())); kernel32::CloseHandle(h); return; } kernel32::CloseHandle(h); //--- Convertimos saltando BOM const string content = ShortArrayToString(buffer, 1); string lines[]; const int total_lines = StringSplit(content, '\n', lines); ArrayResize(arr_lines, total_lines); // Valor inicial int t = 0; //--- Segundos del dia para comparar static MqlDateTime s_dt; static MqlDateTime e_dt; CTimeUtils::TimeToStructFast(start_dt, s_dt); CTimeUtils::TimeToStructFast(end_dt, e_dt); const int start_secs = s_dt.hour * 3600 + s_dt.min * 60 + s_dt.sec; const int end_secs = e_dt.hour * 3600 + e_dt.min * 60 + e_dt.sec; //--- Iteramos y filtramos int found = 0; for(int i = 0; i < total_lines; i++) { if(StringLen(lines[i]) < 10) // No cumple a cer candidado continue; //--- Buscamos el timestamp dinamicamente por el primer ':' const int colon_pos = StringFind(lines[i], ":"); if(colon_pos < 2) // Minimo se reuqiere el 2 por el (HH) continue; //--- Extraemos HH:MM:SS const string ts = StringSubstr(lines[i], colon_pos - 2, 8); const int hh = int(StringSubstr(ts, 0, 2)); const int mm = int(StringSubstr(ts, 3, 2)); const int ss = int(StringSubstr(ts, 6, 2)); const int secs = hh * 3600 + mm * 60 + ss; //--- if(secs >= start_secs && secs <= end_secs) { arr_lines[t++] = lines[i]; } } //--- ArrayResize(arr_lines, t); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void ExtractLogLinesAsStr(const datetime log_file_date, const datetime start_dt, const datetime end_dt, string& str, string sep = "\n") { //--- Path al log de hoy static MqlDateTime dt; CTimeUtils::TimeToStructFast(log_file_date, dt); const string log_file_path = StringFormat("%s\\MQL5\\Logs\\%04d%02d%02d.log", TerminalInfoString(TERMINAL_DATA_PATH), dt.year, dt.mon, dt.day); //--- Abrimos via WinAPI const HANDLE h = kernel32::CreateFileW(log_file_path, 0x80000000, // GENERIC_READ 0x00000001 | 0x00000002, // FILE_SHARE_READ | FILE_SHARE_WRITE NULL, 3, // OPEN_EXISTING 0x80, // FILE_ATTRIBUTE_NORMAL 0); if(h == -1) { FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("No se pudo abrir el archivo, error=%d, file:\n%s", kernel32::GetLastError(), log_file_path)); return; } //--- Tamanio long file_size = 0; if(!kernel32::GetFileSizeEx(h, file_size) || file_size <= 2) { FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("Archivo vacio o fallo GetFileSizeEx | error=%d", kernel32::GetLastError())); kernel32::CloseHandle(h); return; } //--- Leemos const uint num_shorts = uint(file_size >> 1); ushort buffer[]; ArrayResize(buffer, num_shorts); uint bytes_read = 0; OVERLAPPED ov = {}; if(!kernel32::ReadFile(h, buffer, (uint)file_size, bytes_read, ov)) { FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("kernel32::ReadFile | error=%d", kernel32::GetLastError())); kernel32::CloseHandle(h); return; } kernel32::CloseHandle(h); //--- Convertimos saltando BOM const string content = ShortArrayToString(buffer, 1); string lines[]; const int total_lines = StringSplit(content, '\n', lines); str = ""; //--- Segundos del dia para comparar static MqlDateTime s_dt; static MqlDateTime e_dt; CTimeUtils::TimeToStructFast(start_dt, s_dt); CTimeUtils::TimeToStructFast(end_dt, e_dt); const int start_secs = s_dt.hour * 3600 + s_dt.min * 60 + s_dt.sec; const int end_secs = e_dt.hour * 3600 + e_dt.min * 60 + e_dt.sec; //--- Iteramos y filtramos int found = 0; for(int i = 0; i < total_lines; i++) { if(StringLen(lines[i]) < 10) // No cumple a cer candidado continue; //--- Buscamos el timestamp dinamicamente por el primer ':' const int colon_pos = StringFind(lines[i], ":"); if(colon_pos < 2) // Minimo se reuqiere el 2 por el (HH) continue; //--- Extraemos HH:MM:SS const string ts = StringSubstr(lines[i], colon_pos - 2, 8); const int hh = int(StringSubstr(ts, 0, 2)); const int mm = int(StringSubstr(ts, 3, 2)); const int ss = int(StringSubstr(ts, 6, 2)); const int secs = hh * 3600 + mm * 60 + ss; //--- if(secs >= start_secs && secs <= end_secs) { str += lines[i] + sep; } } } //+------------------------------------------------------------------+ #endif // MQLARTICLES_UTILS_EXTRAFUNCTIONS_MQH