forked from nique_372/AiDataGenByLeo
810 lines
46 KiB
MQL5
810 lines
46 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Complex.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_BASE_COMPLEX_MQH
|
|
#define AIDATAGENBYLEO_GENERIC_DATA_BASE_COMPLEX_MQH
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
#include "..\\Factory\\Main.mqh"
|
|
//---
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
// Solo para repartir el estado global
|
|
namespace TSN
|
|
{
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
class CAiLeoMulyiFeatureGen : public CLoggerBase
|
|
{
|
|
private:
|
|
// Parser yaml principal
|
|
ENUM_AIDATA_GEN_TYPE m_type;
|
|
|
|
//---
|
|
string m_name;
|
|
string m_header;
|
|
bool m_init;
|
|
|
|
//---
|
|
ulong m_cols;
|
|
ulong m_rows;
|
|
|
|
//---
|
|
string m_symbol;
|
|
double m_bid;
|
|
double m_ask;
|
|
|
|
|
|
//---
|
|
int m_idx_m1[];
|
|
int m_idx_m1_size;
|
|
|
|
//---
|
|
CAiDataLeoFeature* m_features[];
|
|
int m_features_size;
|
|
|
|
//---
|
|
void SetHeader();
|
|
bool InternaBuild(CYmlNode& root);
|
|
|
|
public:
|
|
CAiLeoMulyiFeatureGen();
|
|
~CAiLeoMulyiFeatureGen();
|
|
|
|
//---
|
|
void Clean();
|
|
|
|
//--- Iniciar
|
|
bool Init(CYmlNode& root);
|
|
bool Compile(CYmlNode& root, string& out);
|
|
|
|
//--- Obtener datos
|
|
void ObtenerDataEnMatrix(matrix& mtx, const datetime curr_time); // Obtiene un matrix
|
|
void ObtenerDataEnVector(vector& vct, const datetime curr_time); // Obtiene un vector
|
|
void ObtenerVectorAsMatrix(matrix& mtx, const datetime curr_time); // Obtiene un vector solo que como matrix
|
|
|
|
//--- Summary
|
|
void Summary() const;
|
|
|
|
//---
|
|
// CUIDADO puede dar errores..
|
|
// El headerva separado por , siempre debera de tener el mismo tamaño que COLS.. esa es la idea
|
|
// En caso no lo tenga la clase se abstiene a hacer comprobaciones... asi que
|
|
// Las modificaiones que se hagan al header.. ud debera de tener cuidado
|
|
__forceinline string Header() const { return m_header; }
|
|
void Header(const string& v) { m_header = v; }
|
|
|
|
//---
|
|
void OnNewBarM1(const datetime curr_time);
|
|
|
|
//---
|
|
static void GetDataCts(vector& res, const int &indexs[], const int indexs_size, const vector& v);
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
CAiLeoMulyiFeatureGen::CAiLeoMulyiFeatureGen()
|
|
: m_init(false), m_symbol(_Symbol), m_header(NULL)
|
|
{
|
|
m_features_size = ArrayResize(m_features, 0);
|
|
m_idx_m1_size = ArrayResize(m_idx_m1, 0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
CAiLeoMulyiFeatureGen::~CAiLeoMulyiFeatureGen(void)
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CAiLeoMulyiFeatureGen::Clean(void)
|
|
{
|
|
//---
|
|
m_cols = 0;
|
|
m_rows = 0;
|
|
m_type = WRONG_VALUE;
|
|
m_name = NULL;
|
|
m_init = false;
|
|
m_header = NULL;
|
|
|
|
//--- Eliminamos los puntos
|
|
for(int i = 0; i < m_features_size; i++)
|
|
{
|
|
if(CheckPointer(m_features[i]) == POINTER_DYNAMIC)
|
|
delete m_features[i];
|
|
}
|
|
m_features_size = ArrayResize(m_features, 0);
|
|
|
|
//---
|
|
m_idx_m1_size = ArrayResize(m_idx_m1, 0);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Funciones de inicilizacion |
|
|
//| 1. Funcion de incilizacion normal por src |
|
|
//| 2. Funcion de iniclziacion por file AIDATABYLEO_FILE_EXT |
|
|
//+------------------------------------------------------------------+
|
|
bool CAiLeoMulyiFeatureGen::Init(CYmlNode& root)
|
|
{
|
|
//--- Verificamos si esta iniciado
|
|
if(m_init)
|
|
{
|
|
LogWarning("Se esta limpiadno la clase, dado que ya esta iniciada", FUNCION_ACTUAL);
|
|
Clean();
|
|
}
|
|
|
|
//--- Parseamos
|
|
if(!InternaBuild(root))
|
|
return false;
|
|
|
|
//--- Seteamos el nombre (en el parse ya se setea el resto)
|
|
m_init = true; // Se inicio correctamente
|
|
|
|
//--- Construiimos...
|
|
ArrayResize(m_idx_m1, m_features_size); // Inicialmente el mismo tamaño..
|
|
for(int i = 0; i < m_features_size; i++)
|
|
{
|
|
if(m_features[i].m_use_on_new_bar_m1)
|
|
{
|
|
m_idx_m1[m_idx_m1_size++] = i;
|
|
}
|
|
}
|
|
|
|
//---
|
|
SetHeader();
|
|
|
|
//---
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CAiLeoMulyiFeatureGen::OnNewBarM1(const datetime curr_time)
|
|
{
|
|
//---
|
|
m_bid = SymbolInfoDouble(m_symbol, SYMBOL_BID);
|
|
m_ask = SymbolInfoDouble(m_symbol, SYMBOL_ASK);
|
|
|
|
//---
|
|
for(int i = 0; i < m_idx_m1_size; i++)
|
|
{
|
|
m_features[m_idx_m1[i]].OnNewBarM1(curr_time, m_bid, m_ask);
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Funciones para generar data |
|
|
//| Nota: |
|
|
//| - Recomiendo saber de ante mano cual llamar |
|
|
//+------------------------------------------------------------------+
|
|
void CAiLeoMulyiFeatureGen::ObtenerDataEnMatrix(matrix &mtx, const datetime curr_time)
|
|
{
|
|
//---
|
|
m_bid = SymbolInfoDouble(m_symbol, SYMBOL_BID);
|
|
m_ask = SymbolInfoDouble(m_symbol, SYMBOL_ASK);
|
|
|
|
//---
|
|
mtx.Resize(m_rows, m_cols);
|
|
ulong start_r = 0;
|
|
ulong end_r = 0;
|
|
ulong col = 0;
|
|
ulong k = 0;
|
|
|
|
//---
|
|
for(int i = 0; i < m_features_size; i++)
|
|
{
|
|
CAiDataLeoFeature* f = m_features[i];
|
|
col = f.MtxStartCol();
|
|
start_r = f.MtxStartRow();
|
|
end_r = f.MtxEndRow();
|
|
f.CalcValue(curr_time, m_bid, m_ask);
|
|
k = 0;
|
|
|
|
//---
|
|
for(ulong r = start_r; r <= end_r; r++)
|
|
{
|
|
mtx[r][col] = f.m_v[k++];
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
void CAiLeoMulyiFeatureGen::ObtenerDataEnVector(vector &vct, const datetime curr_time)
|
|
{
|
|
//---
|
|
m_bid = SymbolInfoDouble(m_symbol, SYMBOL_BID);
|
|
m_ask = SymbolInfoDouble(m_symbol, SYMBOL_ASK);
|
|
|
|
//---
|
|
vct.Resize(m_cols);
|
|
for(ulong i = 0; i < m_cols; i++)
|
|
{
|
|
m_features[i].CalcValue(curr_time, m_bid, m_ask);
|
|
vct[i] = m_features[i].m_v[0]; // Valor 0
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
void CAiLeoMulyiFeatureGen::ObtenerVectorAsMatrix(matrix &mtx, const datetime curr_time)
|
|
{
|
|
//---
|
|
m_bid = SymbolInfoDouble(m_symbol, SYMBOL_BID);
|
|
m_ask = SymbolInfoDouble(m_symbol, SYMBOL_ASK);
|
|
|
|
//---
|
|
mtx.Resize(m_rows, m_cols); // ROWS = 1
|
|
for(ulong i = 0; i < m_cols; i++)
|
|
{
|
|
m_features[i].CalcValue(curr_time, m_bid, m_ask);
|
|
mtx[i][0] = m_features[i].m_v[0]; // Valor 0
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CAiLeoMulyiFeatureGen::Summary(void) const
|
|
{
|
|
PrintFormat("---| Summary of = %s", m_name);
|
|
PrintFormat(" Type = %s", EnumToString(m_type));
|
|
PrintFormat(" Cols = %I64u", m_cols);
|
|
PrintFormat(" Rows = %I64u", m_rows);
|
|
Print(" --------- ");
|
|
for(int i = 0; i < m_features_size; i++)
|
|
{
|
|
Print(m_features[i].Summary() + "\n");
|
|
}
|
|
Print("--- Fin");
|
|
}
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CAiLeoMulyiFeatureGen::SetHeader(void)
|
|
{
|
|
//---
|
|
m_header = "";
|
|
|
|
//---
|
|
if(m_type == AIDATALEO_GEN_VECTOR)
|
|
{
|
|
//--- Vector usa nombres reales
|
|
for(ulong i = 0; i < m_cols; i++)
|
|
{
|
|
m_header += m_features[i].FullName();
|
|
if(i < m_cols - 1)
|
|
m_header += AILEO_COMPLEX_HEADER_SEP;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//--- Matrix usa nombres genericos
|
|
for(ulong i = 0; i < m_cols; i++)
|
|
{
|
|
m_header += AILEO_COMPLEX_GENERIC_COL_NAME + string(i);
|
|
if(i < m_cols - 1)
|
|
m_header += AILEO_COMPLEX_HEADER_SEP;
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool CAiLeoMulyiFeatureGen::Compile(CYmlNode &root, string &out)
|
|
{
|
|
//---
|
|
out = "";
|
|
m_init = true;
|
|
|
|
//-- Base
|
|
m_name = root["name"].ToString("MyFeatureGenerator");
|
|
m_cols = (int)root["config"]["cols"].ToInt(0);
|
|
|
|
//---
|
|
CYmlNode output = root["output"];
|
|
m_type = CEnumRegAiLeo::GetValNoRef<ENUM_AIDATA_GEN_TYPE>(output["type"].ToString(), WRONG_VALUE); /// usar cenumreg...
|
|
if(m_type == WRONG_VALUE)
|
|
{
|
|
LogError("Tipo de output invalido", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
m_rows = (int)output["rows"].ToInt(1);
|
|
|
|
//---
|
|
if(!output["contexts"].IsArray())
|
|
return false;
|
|
|
|
//---
|
|
CYmlIteratorArray it = output["contexts"].BeginArr();
|
|
|
|
//---
|
|
int last_idx_arr_size = 0;
|
|
int fi = 0;
|
|
int rfi = 0;
|
|
|
|
//--- Array
|
|
if(m_type == AIDATALEO_GEN_VECTOR)
|
|
{
|
|
//---
|
|
rfi = int(m_cols);
|
|
|
|
//---
|
|
while(it.IsValid())
|
|
{
|
|
CYmlNode obj = it.Val();
|
|
|
|
//--- Por cada parametro...
|
|
CYmlIteratorArray ita = obj["data"].BeginArr();
|
|
while(ita.IsValid())
|
|
{
|
|
CYmlNode curr_obj = ita.Val();
|
|
|
|
//--- obtenemos ptr
|
|
const string name = curr_obj["class"].ToString();
|
|
if(!CAiDataGenFeatureFactory::s_hash_str_to_creator.Contains(name))
|
|
{
|
|
LogError(StringFormat("No existe class = '%s'", name), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
const string pref = curr_obj["prefix"].ToString("");
|
|
|
|
//---
|
|
out += name + pref + ",";
|
|
fi++;
|
|
|
|
//---
|
|
ita.Next();
|
|
}
|
|
|
|
//---
|
|
it.Next();
|
|
}
|
|
}
|
|
else // Matrix
|
|
{
|
|
//---
|
|
rfi = int(m_cols * m_rows);
|
|
ulong col = 0;
|
|
ulong row = 0;
|
|
|
|
//---
|
|
out += AILEO_COMPLEX_GENERIC_COL_NAME + "0,";
|
|
while(it.IsValid())
|
|
{
|
|
CYmlNode obj = it.Val();
|
|
|
|
//---
|
|
const int type = CEnumRegAiLeo::GetValNoRef<int8_t>(obj["mode"].ToString(""), -1);
|
|
switch(type)
|
|
{
|
|
case AILEO_MTX_TYPE_NORMAL: // normal [1,2,3] (misma features pero los indices para generar un vector)
|
|
case AILEO_MTX_TYPE_CUSTOM: // custom [1,2,3] (diferentens features)
|
|
{
|
|
last_idx_arr_size = obj["idx"].Size();
|
|
break;
|
|
}
|
|
case AILEO_MTX_TYPE_GENERATE: // [1,2,3] (misma feature pero con varios indices)
|
|
{
|
|
int temp[];
|
|
const int t = obj["idx"].ToArray(temp); // start,step,stop
|
|
if(t != 3)
|
|
{
|
|
LogError("Generate debe de tener exactamente 3 elementos", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
const int num = (temp[2] - temp[0]) / temp[1];
|
|
if(num < 1)
|
|
{
|
|
LogError("Numero de combinacion en generate menor a 1", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
//---
|
|
last_idx_arr_size = num;
|
|
break;
|
|
}
|
|
default:
|
|
LogError("Modo invalido", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
|
|
//---
|
|
CYmlIteratorArray ita = obj["data"].BeginArr();
|
|
while(ita.IsValid())
|
|
{
|
|
//---
|
|
CYmlNode curr_obj = ita.Val();
|
|
|
|
//--- obtenemos ptr
|
|
const string name = curr_obj["class"].ToString();
|
|
if(!CAiDataGenFeatureFactory::s_hash_str_to_creator.Contains(name))
|
|
{
|
|
LogError(StringFormat("No existe class = '%s'", name), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
if(type == AILEO_MTX_TYPE_CUSTOM) // Custom valores..
|
|
{
|
|
row++; // Siguiente elemento..
|
|
}
|
|
else // Vector completo..
|
|
{
|
|
//---
|
|
// 0 1 2
|
|
const ulong row_end = row + (last_idx_arr_size - 1);
|
|
if(row_end >= m_rows)
|
|
{
|
|
LogError("Una fila de datos ha superado el tamaño de fila para este col, divida esta col en varias..", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
row = row_end + 1; // Siguiente elemento..
|
|
}
|
|
|
|
//---
|
|
if(row >= m_rows)
|
|
{
|
|
row = 0;
|
|
col++;
|
|
out += AILEO_COMPLEX_GENERIC_COL_NAME + string(col) + ",";
|
|
}
|
|
|
|
//---
|
|
fi++;
|
|
|
|
//---
|
|
ita.Next();
|
|
}
|
|
|
|
//---
|
|
it.Next();
|
|
}
|
|
}
|
|
|
|
//--- Verificamos auqnue quizas no sea necesario dado qeu dara un array out range si se pasa de lo previsto...
|
|
const uint len = out.Length();
|
|
if(fi != rfi || !len)
|
|
{
|
|
LogError("El numero de features creadas no conicide.., o no hay features", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
StringSetLength(out, len - 1); //
|
|
|
|
//---
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool CAiLeoMulyiFeatureGen::InternaBuild(CYmlNode& root)
|
|
{
|
|
//-- Base
|
|
m_name = root["name"].ToString("MyFeatureGenerator");
|
|
m_cols = (int)root["config"]["cols"].ToInt(0);
|
|
|
|
//---
|
|
CYmlNode output = root["output"];
|
|
m_type = CEnumRegAiLeo::GetValNoRef<ENUM_AIDATA_GEN_TYPE>(output["type"].ToString(), WRONG_VALUE); /// usar cenumreg...
|
|
if(m_type == WRONG_VALUE)
|
|
{
|
|
LogError("Tipo de output invalido", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
m_rows = (int)output["rows"].ToInt(1);
|
|
|
|
//---
|
|
if(!output["contexts"].IsArray())
|
|
return false;
|
|
|
|
//---
|
|
CYmlIteratorArray it = output["contexts"].BeginArr();
|
|
|
|
//---
|
|
int last_idx_arr[];
|
|
int last_idx_arr_size = 0;
|
|
int fi = 0;
|
|
|
|
//--- Array
|
|
if(m_type == AIDATALEO_GEN_VECTOR)
|
|
{
|
|
m_features_size = ArrayResize(m_features, (int)m_cols);
|
|
|
|
//---
|
|
while(it.IsValid())
|
|
{
|
|
CYmlNode obj = it.Val();
|
|
|
|
//---
|
|
int p = 0;
|
|
const int type = CEnumRegAiLeo::GetValNoRef<int8_t>(obj["mode"].ToString(""), -1);
|
|
switch(type)
|
|
{
|
|
case AILEO_VECTOR_TYPE_NORMAL: // normal
|
|
{
|
|
ArrayResize(last_idx_arr, 1);
|
|
last_idx_arr[0] = (int)obj["idx"].ToInt(0);
|
|
break;
|
|
}
|
|
case AILEO_VECTOR_TYPE_CUSTOM:
|
|
{
|
|
last_idx_arr_size = obj["idx"].ToArray(last_idx_arr);
|
|
break;
|
|
}
|
|
default:
|
|
LogError("Modo invalido", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//--- Por cada parametro...
|
|
CYmlIteratorArray ita = obj["data"].BeginArr();
|
|
while(ita.IsValid())
|
|
{
|
|
CYmlNode curr_obj = ita.Val();
|
|
|
|
//--- obtenemos ptr
|
|
const string name = curr_obj["class"].ToString();
|
|
CAiDataLeoFeature* ptr = CAiDataGenFeatureFactory::GetFeature(name);
|
|
if(ptr == NULL)
|
|
{
|
|
LogError(StringFormat("Se obtuvo un puntero NULL, para la feature con nombre = '%s'", name), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
const bool support_idx = ptr.m_support_idx;
|
|
const int idx = (type == AILEO_VECTOR_TYPE_CUSTOM) ? (last_idx_arr[p++]) : (last_idx_arr[0]);
|
|
|
|
//---
|
|
if(!support_idx)
|
|
{
|
|
if(idx > 1) // Error
|
|
{
|
|
LogError(StringFormat("La feature con nombre = %s, no soporta indices > 1", name), FUNCION_ACTUAL);
|
|
delete ptr; // Lo eliminamos
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//--- Inicilizar
|
|
if(!ptr.Initialize(curr_obj["params"], idx))
|
|
{
|
|
delete ptr;
|
|
LogError(StringFormat("Fallo al inicio la feature = %s", name), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
const string pref = curr_obj["prefix"].ToString("");
|
|
ptr.Prefix(pref);
|
|
|
|
//---
|
|
m_features[fi++] = ptr;
|
|
|
|
//---
|
|
ita.Next();
|
|
}
|
|
|
|
//---
|
|
it.Next();
|
|
}
|
|
}
|
|
else // Matrix
|
|
{
|
|
m_features_size = ArrayResize(m_features, int(m_cols * m_rows));
|
|
ulong col = 0;
|
|
ulong row = 0;
|
|
|
|
//---
|
|
while(it.IsValid())
|
|
{
|
|
CYmlNode obj = it.Val();
|
|
|
|
//---
|
|
int p = 0;
|
|
const int type = CEnumRegAiLeo::GetValNoRef<int8_t>(obj["mode"].ToString(""), -1);
|
|
switch(type)
|
|
{
|
|
case AILEO_MTX_TYPE_NORMAL: // normal [1,2,3] (misma features pero los indices para generar un vector)
|
|
case AILEO_MTX_TYPE_CUSTOM: // custom [1,2,3] (diferentens features)
|
|
{
|
|
last_idx_arr_size = obj["idx"].ToArray(last_idx_arr);
|
|
break;
|
|
}
|
|
case AILEO_MTX_TYPE_GENERATE: // [1,2,3] (misma feature pero con varios indices)
|
|
{
|
|
int temp[];
|
|
const int t = obj["idx"].ToArray(temp); // start,step,stop
|
|
if(t != 3)
|
|
{
|
|
LogError("Generate debe de tener exactamente 3 elementos", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
const int num = (temp[2] - temp[0]) / temp[1];
|
|
if(num < 1)
|
|
{
|
|
LogError("Numero de combinacion en generate menor a 1", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
last_idx_arr_size = ArrayResize(last_idx_arr, num);
|
|
int x = temp[0];
|
|
int k = 0;
|
|
last_idx_arr[k++] = x;
|
|
|
|
//---
|
|
while(x < temp[2])
|
|
{
|
|
x += temp[1];
|
|
last_idx_arr[k++] = x;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
LogError("Modo invalido", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
|
|
//---
|
|
CYmlIteratorArray ita = obj["data"].BeginArr();
|
|
while(ita.IsValid())
|
|
{
|
|
//---
|
|
CYmlNode curr_obj = ita.Val();
|
|
|
|
//--- obtenemos ptr
|
|
const string name = curr_obj["class"].ToString();
|
|
CAiDataLeoFeature* ptr = CAiDataGenFeatureFactory::GetFeature(name);
|
|
if(ptr == NULL)
|
|
{
|
|
LogError(StringFormat("Se obtuvo un puntero NULL, para la feature con nombre = '%s'", name), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
const bool support_idx = ptr.m_support_idx;
|
|
|
|
//---
|
|
if(type == AILEO_MTX_TYPE_CUSTOM) // Custom valores..
|
|
{
|
|
const int idx = last_idx_arr[p++];
|
|
|
|
//----
|
|
if(!support_idx)
|
|
{
|
|
if(idx > 1) // Error
|
|
{
|
|
LogError(StringFormat("La feature con nombre = %s, no soporta indices > 1", name), FUNCION_ACTUAL);
|
|
delete ptr; // Lo eliminamos
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//----
|
|
if(!ptr.Initialize(curr_obj["params"], idx))
|
|
{
|
|
delete ptr;
|
|
LogError(StringFormat("Fallo al inicio la feature = %s", name), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
ptr.SetExtra(col, row, row); // Solo 1 dato aqui
|
|
row++; // Siguiente elemento..
|
|
}
|
|
else // Vector completo..
|
|
{
|
|
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, pos = %d, val = %d", name, k,
|
|
last_idx_arr[k]), FUNCION_ACTUAL);
|
|
delete ptr; // Lo eliminamos
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
//---
|
|
if(!ptr.Initialize(curr_obj["params"], last_idx_arr)) // Le pasamos el array esta vez generara un vector
|
|
{
|
|
delete ptr;
|
|
LogError(StringFormat("Fallo al inicio la feature = %s", name), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
// 0 1 2
|
|
const ulong row_end = row + (last_idx_arr_size - 1);
|
|
if(row_end >= m_rows)
|
|
{
|
|
LogError("Una fila de datos ha superado el tamaño de fila para este col, divida esta col en varias..", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
ptr.SetExtra(col, row, row_end); //
|
|
row = row_end + 1; // Siguiente elemento..
|
|
}
|
|
|
|
//---
|
|
if(row >= m_rows)
|
|
{
|
|
row = 0;
|
|
col++;
|
|
}
|
|
|
|
//---
|
|
const string pref = curr_obj["prefix"].ToString("");
|
|
ptr.Prefix(pref);
|
|
|
|
//---
|
|
m_features[fi++] = ptr;
|
|
|
|
//---
|
|
ita.Next();
|
|
}
|
|
|
|
//---
|
|
it.Next();
|
|
}
|
|
}
|
|
|
|
//--- Verificamos auqnue quizas no sea necesario dado qeu dara un array out range si se pasa de lo previsto...
|
|
if(fi != m_features_size)
|
|
{
|
|
LogError("El numero de features creadas no conicide..", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
static void CAiLeoMulyiFeatureGen::GetDataCts(vector& res, const int &indexs[], const int indexs_size, const vector& v)
|
|
{
|
|
//---
|
|
res.Resize(indexs_size);
|
|
|
|
//---
|
|
for(int i = 0; i < indexs_size; i++)
|
|
{
|
|
res[i] = v[indexs[i]];
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
#endif // AIDATAGENBYLEO_GENERIC_DATA_BASE_COMPLEX_MQH
|
|
//+------------------------------------------------------------------+
|