forked from nique_372/AiDataGenByLeo
383 lines
28 KiB
MQL5
383 lines
28 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Main.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 AIDATAGENBYLEO_GENERIC_DATA_PARSER_PARSER_MQH
|
|
#define AIDATAGENBYLEO_GENERIC_DATA_PARSER_PARSER_MQH
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
//--- Clasificador
|
|
#include "Clasifier\\Main.mqh"
|
|
|
|
//--- Factory
|
|
#include "..\\Factory\\Main.mqh"
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
class CAiDataLeoFeaturesParser : public CLoggerBase
|
|
{
|
|
public:
|
|
CAiDataLeoFeaturesParser(void) {}
|
|
~CAiDataLeoFeaturesParser(void) {}
|
|
|
|
bool Parse(const string& src, CAiDataLeoFeature* &features[], int &features_size, ENUM_AIDATA_GEN_TYPE &type, ulong& cols, ulong &rows);
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
// Notas
|
|
// - Tener cudidad con que cols no sea mayor a int.. (valor) para evitar overflow.. aunque es muy improbable que pase
|
|
// - Uso ulong para compatilbidad con el tipo nativo matrix y vector (Cols, Rows, Size, retornrnan valores UL)
|
|
bool CAiDataLeoFeaturesParser::Parse(const string& src, CAiDataLeoFeature* &features[], int &features_size, ENUM_AIDATA_GEN_TYPE &type, ulong& cols, ulong &rows)
|
|
{
|
|
//---
|
|
string msg = "";
|
|
AiDataByLeoClasifierToken tokens[];
|
|
if(!CAiDataLeoFeaturesClasifiers::Clasificar(src, tokens, msg))
|
|
{
|
|
LogError(msg, FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
if(IsInfoLogEnabled())
|
|
CAiDataLeoFeaturesClasifiers::PrintTokens(tokens);
|
|
|
|
//---
|
|
const int total = ArraySize(tokens);
|
|
int last_feature_idx = -1;
|
|
|
|
// En caso que el contexto global sea MATRIX entonces deberemos de alamcnar el numero de filas EXACTo
|
|
// Que cada contexto local requiere
|
|
int mtx_global_row_size = 0;
|
|
int mtx_local_row_c = 0;
|
|
|
|
// Indices
|
|
int last_idx_arr[];
|
|
int last_idx_arr_size = -1;
|
|
|
|
// Contador en caso se use custom
|
|
int last_idx_arr_c = 0;
|
|
|
|
// Tipo final.. por defecto vector
|
|
type = AIDATALEO_GEN_VECTOR;
|
|
|
|
// Contexto global
|
|
int8_t ctx = -1;
|
|
|
|
// Este entero indica el numero de modelos que se VA ocupando en el contexto global
|
|
ulong counter_f = 0ULL;
|
|
|
|
// Este booleano indica si en este contexto local.. las varaibles se apilan
|
|
// Es algo complejo de explicar.. no encuntro las palabras
|
|
// Pero a este concepto lo llame custom (ver el clasificador) a difertencia de los "contextos" basicos aqui
|
|
// En vez de pasr indices como tal... "acoplamos" vairos modelos y les damos indices CUSTOM a cada uno..
|
|
// Esto es util por jemeplo si se quiere en un MATRIX una fila con diferentes modelos (normalmente todos compartiran el mismo INDEXES)
|
|
bool multi_f = false;
|
|
|
|
//--- Valores por defecto
|
|
rows = 0;
|
|
cols = 0;
|
|
|
|
//---
|
|
for(int i = 0; i < total; i++)
|
|
{
|
|
switch(tokens[i].type)
|
|
{
|
|
//--- Configuracion
|
|
case AIDATABYLEO_CLASIFIER_TOKEN_INIT:
|
|
{
|
|
cols = int(tokens[i].text);
|
|
break;
|
|
}
|
|
|
|
//--- Inicio de contexto
|
|
case AIDATABYLEO_CLASIFIER_TOKEN_CONTEXT:
|
|
{
|
|
//---
|
|
if(StringSplit(tokens[i].text, AIDATAFEATURES_PARSER_SEP_CHAR_U, g_ai_data_fetaures_leo_str_arr) < 2)
|
|
{
|
|
LogError("Contexto debe de tener como minimo 2 parametros", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
const int8_t abarca = int8_t(g_ai_data_fetaures_leo_str_arr[0]);
|
|
Print(abarca);
|
|
if(abarca == AIDATAFEATURE_CTX_GBL)
|
|
{
|
|
ctx = int8_t(g_ai_data_fetaures_leo_str_arr[1]); // Vecotr o Matrix
|
|
|
|
//---
|
|
if(ctx == AIDATAFEATURE_ROW_TYPE_ARRAY) // Matrix
|
|
{
|
|
mtx_global_row_size = int(g_ai_data_fetaures_leo_str_arr[2]) ; // Numero de filas que debera de tener cada matrix creada
|
|
// En este contexto
|
|
rows += mtx_global_row_size;
|
|
}
|
|
else
|
|
if(ctx == AIDATAFEATURE_ROW_TYPE_BASIC)
|
|
{
|
|
rows++;
|
|
}
|
|
|
|
|
|
//---
|
|
counter_f = 0; // Restablecemos el contador al numero de cols
|
|
}
|
|
else // Contexto local
|
|
{
|
|
//--- Check context
|
|
if(ctx < 0 || ctx > 1)
|
|
{
|
|
LogError(StringFormat("Contexto global = %d, es invalido", ctx), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//--- Es custom
|
|
if((multi_f = bool(int(g_ai_data_fetaures_leo_str_arr[1])))) // Continee si es multi o basic
|
|
last_idx_arr_c = 0; // En caso se multiple indice sutom reiniciamos contador
|
|
|
|
//--- Matrix
|
|
if(ctx == AIDATAFEATURE_ROW_TYPE_ARRAY) // Contexto global matrix
|
|
{
|
|
last_idx_arr_size = StringSplit(g_ai_data_fetaures_leo_str_arr[2], ',', g_ai_data_leo_dyn_arr);
|
|
if(last_idx_arr_size <= 0)
|
|
{
|
|
LogError("Fallo al hacer split no hay data", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//--- Reiniciamos el contador de rows
|
|
mtx_local_row_c = int(rows) - mtx_global_row_size; // Fila de inicio
|
|
|
|
//---
|
|
// El numero de datos esperados filas es invlaido
|
|
// Dado que debe de ser IGUAL al del matrix ctx global
|
|
if(mtx_global_row_size != last_idx_arr_size)
|
|
{
|
|
LogError(StringFormat("El contexto global mtx requiere = %d filas, el contexto local mtx tiene = %d, modifque el codigo",
|
|
mtx_global_row_size, last_idx_arr_size), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
}
|
|
else // Vector
|
|
if(ctx == AIDATAFEATURE_ROW_TYPE_BASIC) // Contexto global vector
|
|
{
|
|
//--- Convertimos los indices a array
|
|
// Aqui no verificamo el numero de indices en vecotr dado qeu peuyde ser variable
|
|
last_idx_arr_size = StringSplit(g_ai_data_fetaures_leo_str_arr[2], ',', g_ai_data_leo_dyn_arr);
|
|
if(last_idx_arr_size == -1)
|
|
{
|
|
LogError("Fallo al hacer split en row de vector", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//--- Str -> int array
|
|
Print("Tamaño de el: ", last_idx_arr_size);
|
|
ArrayResize(last_idx_arr, last_idx_arr_size);
|
|
for(int k = 0; k < last_idx_arr_size; k++)
|
|
{
|
|
last_idx_arr[k] = int(g_ai_data_leo_dyn_arr[k]);
|
|
if(last_idx_arr[k] < 0) // Check de valor
|
|
{
|
|
LogError(StringFormat("Valor invalido en [%d], valor = %d, el valor del indice debe de ser > 0", k, last_idx_arr[k]), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
//---
|
|
break;
|
|
}
|
|
|
|
//--- Fin de contexto
|
|
case AIDATABYLEO_CLASIFIER_TOKEN_END_CONTEXT:
|
|
{
|
|
break;
|
|
}
|
|
|
|
//--- Datos (features)
|
|
case AIDATABYLEO_CLASIFIER_TOKEN_DATA:
|
|
{
|
|
//---
|
|
if(counter_f >= cols) // Invalido ya no se permiten mas modelos en este contexto local
|
|
{
|
|
LogCriticalError(StringFormat("En el contexto local solo se permiten = %I64u modelos, usted puso mas de ese numero [%I64u] reduzcalo", cols, counter_f), FUNCION_ACTUAL);
|
|
return false; // SEREMOS estrictors no habra advertencias ni ocultaremos simplemente no se permite
|
|
}
|
|
|
|
//--- Split
|
|
if(StringSplit(tokens[i].text, AIDATAFEATURES_PARSER_SEP_CHAR_U, g_ai_data_fetaures_leo_str_arr) != 3)
|
|
{
|
|
LogError(StringFormat("Feature debe de tener 3 valores [Name][Prefijo][Parametros] feauture:\n%s", tokens[i].text), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//--- Creacion del puntero
|
|
CAiDataLeoFeature* ptr = CAiDataGenFeatureFactory::GetFeature(g_ai_data_fetaures_leo_str_arr[0], last_feature_idx);
|
|
if(ptr == NULL)
|
|
{
|
|
LogError(StringFormat("Se obtuvo un puntero NULL, para la feature con nombre = %s", g_ai_data_fetaures_leo_str_arr[0]), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//--- Soporta idx?
|
|
const bool support_idx = g_ai_data_leo_factory[last_feature_idx].support_idx;
|
|
|
|
|
|
//--- Evaluacion (MATRIX o VECTOR dependeido del contexto)
|
|
if(ctx == AIDATAFEATURE_ROW_TYPE_ARRAY) // MATRIX
|
|
{
|
|
//--- Nueva fil
|
|
if(mtx_local_row_c >= int(rows)) // Si es mayor o igual al rows
|
|
{
|
|
LogError(StringFormat("No se permiten mas de %d lenth por cada matrix local", mtx_global_row_size), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
|
|
//---
|
|
if(multi_f) // Se necestia atencion
|
|
{
|
|
//--- Indice
|
|
const int idx = multi_f ? (last_idx_arr[last_idx_arr_c++]) : (last_idx_arr[0]);
|
|
|
|
//--- Checkeo
|
|
if(!support_idx)
|
|
{
|
|
if(idx > 1) // Error
|
|
{
|
|
LogError(StringFormat("La feature con nombre = %s, no soporta indices > 1", g_ai_data_fetaures_leo_str_arr[0]), FUNCION_ACTUAL);
|
|
delete ptr; // Lo eliminamos
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//--- Inicilizar
|
|
if(!ptr.Initialize(g_ai_data_fetaures_leo_str_arr[2], idx))
|
|
{
|
|
delete ptr;
|
|
LogError(StringFormat("Fallo al inicio la feature = %s\nParametros:\n%s", g_ai_data_fetaures_leo_str_arr[0], g_ai_data_fetaures_leo_str_arr[2]), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//--- Seteamos
|
|
ptr.SetExtra(counter_f, ulong(mtx_local_row_c), ulong(mtx_local_row_c)); // Solo 1 dato aqui
|
|
}
|
|
else
|
|
{
|
|
//--- Checkeo
|
|
// Iteramos sobre todas los indices que debera de generar dicha feature
|
|
// SOlo en caso que NO se soporte vairos infdices, osea que si la feautre no puede soportar varios inices ocustom
|
|
// Haremos esa revision en caso se encuntren esos idnices, retonraremos false
|
|
if(!support_idx)
|
|
{
|
|
for(int k = 0; k < last_idx_arr_size; k++)
|
|
{
|
|
if(last_idx_arr[k] > 1)
|
|
{
|
|
LogError(StringFormat("La feature con nombre = %s, no soporta indices > 1", g_ai_data_fetaures_leo_str_arr[0]), FUNCION_ACTUAL);
|
|
delete ptr; // Lo eliminamos
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
//--- Inicilizar
|
|
if(!ptr.Initialize(g_ai_data_fetaures_leo_str_arr[2], last_idx_arr)) // Le pasamos el array esta vez generara un vector
|
|
{
|
|
delete ptr;
|
|
LogError(StringFormat("Fallo al inicio la feature = %s\nParametros:\n%s", g_ai_data_fetaures_leo_str_arr[0], g_ai_data_fetaures_leo_str_arr[2]), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//--- Seteamos
|
|
// Aqui geenramos desde una columan y desde el inciio de fila hasta el ultimo valor posible indice fila
|
|
ptr.SetExtra(counter_f, ulong(rows - last_idx_arr_size), ulong(rows - 1)); //
|
|
}
|
|
|
|
//--- Aumentamos el contador
|
|
mtx_local_row_c++;
|
|
}
|
|
else // VECTOR
|
|
{
|
|
//--- Obtencion del indice
|
|
// El indice es en base a multi_f
|
|
// Si es true entonces se coje el indice dado
|
|
// Si es false entonces es un indcei "constante"
|
|
const int idx = multi_f ? (last_idx_arr[last_idx_arr_c++]) : (last_idx_arr[0]);
|
|
|
|
//--- Checkeo
|
|
if(!support_idx)
|
|
{
|
|
if(idx > 1) // Error
|
|
{
|
|
LogError(StringFormat("La feature con nombre = %s, no soporta indices > 1", g_ai_data_fetaures_leo_str_arr[0]), FUNCION_ACTUAL);
|
|
delete ptr; // Lo eliminamos
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//--- Inicilizar
|
|
if(!ptr.Initialize(g_ai_data_fetaures_leo_str_arr[2], idx))
|
|
{
|
|
delete ptr;
|
|
LogError(StringFormat("Fallo al inicio la feature = %s\nParametros:\n%s", g_ai_data_fetaures_leo_str_arr[0], g_ai_data_fetaures_leo_str_arr[2]), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//---
|
|
ptr.SetExtra(counter_f, (rows - 1), (rows - 1)); // Siempre la ultima fila para vector (todo este grupo)
|
|
|
|
//--- Nueva feautre
|
|
features[ArrayResize(features, (++features_size)) - 1] = ptr;
|
|
|
|
//--- Para la siguiente
|
|
counter_f++;
|
|
|
|
//---
|
|
break;
|
|
}
|
|
default:
|
|
LogFatalError("Token desconocido", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//--- Chekeo final
|
|
// Numero de features valido
|
|
if(features_size < 1)
|
|
{
|
|
LogError("No hay features", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
// Obtenemos el tipo
|
|
/*Print("---- Tipo");
|
|
Print(rows);
|
|
Print(cols);*/
|
|
if(rows > 1) // Mas de un row
|
|
type = AIDATALEO_GEN_MATRIX; // Ahora sera del tipo MATRIX
|
|
|
|
//---
|
|
return true;
|
|
}
|
|
|
|
//--- Obejeto global
|
|
CAiDataLeoFeaturesParser g_ai_data_features_parser;
|
|
|
|
//+------------------------------------------------------------------+
|
|
#endif // AIDATAGENBYLEO_GENERIC_DATA_PARSER_PARSER_MQH
|