AiDataGenByLeo/GenericData/Base/Complex.mqh

811 lines
46 KiB
MQL5
Raw Permalink Normal View History

2026-02-06 08:18:57 -05:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| 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
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-07-03 22:13:33 -05:00
#include "..\\Factory\\Main.mqh"
2026-02-06 08:18:57 -05:00
//---
2026-07-04 11:58:29 -05:00
2026-02-06 08:18:57 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
// Solo para repartir el estado global
2026-07-03 22:13:33 -05:00
namespace TSN
{
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-02-06 08:18:57 -05:00
class CAiLeoMulyiFeatureGen : public CLoggerBase
{
private:
2026-07-03 22:13:33 -05:00
// Parser yaml principal
ENUM_AIDATA_GEN_TYPE m_type;
2026-02-06 08:18:57 -05:00
//---
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();
2026-07-06 11:20:10 -05:00
bool InternaBuild(CYmlNode& root);
2026-02-06 08:18:57 -05:00
public:
CAiLeoMulyiFeatureGen();
~CAiLeoMulyiFeatureGen();
//---
void Clean();
//--- Iniciar
2026-07-06 11:20:10 -05:00
bool Init(CYmlNode& root);
2026-07-07 18:39:17 -05:00
bool Compile(CYmlNode& root, string& out);
2026-02-06 08:18:57 -05:00
//--- Obtener datos
2026-02-14 20:47:37 -05:00
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
2026-02-06 08:18:57 -05:00
//--- Summary
void Summary() const;
//---
// CUIDADO puede dar errores..
// El headerva separado por , siempre debera de tener el mismo tama<EFBFBD>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; }
//---
2026-02-14 20:47:37 -05:00
void OnNewBarM1(const datetime curr_time);
2026-02-06 08:18:57 -05:00
//---
2026-02-14 20:47:37 -05:00
static void GetDataCts(vector& res, const int &indexs[], const int indexs_size, const vector& v);
2026-02-06 08:18:57 -05:00
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
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 |
//+------------------------------------------------------------------+
2026-07-06 11:20:10 -05:00
bool CAiLeoMulyiFeatureGen::Init(CYmlNode& root)
2026-02-06 08:18:57 -05:00
{
//--- Verificamos si esta iniciado
if(m_init)
{
LogWarning("Se esta limpiadno la clase, dado que ya esta iniciada", FUNCION_ACTUAL);
Clean();
}
//--- Parseamos
2026-07-03 22:13:33 -05:00
if(!InternaBuild(root))
2026-02-06 08:18:57 -05:00
return false;
//--- Seteamos el nombre (en el parse ya se setea el resto)
m_init = true; // Se inicio correctamente
2026-07-03 22:13:33 -05:00
//--- Construiimos...
ArrayResize(m_idx_m1, m_features_size); // Inicialmente el mismo tama<EFBFBD>o..
2026-02-06 08:18:57 -05:00
for(int i = 0; i < m_features_size; i++)
{
2026-07-03 22:13:33 -05:00
if(m_features[i].m_use_on_new_bar_m1)
2026-02-06 08:18:57 -05:00
{
2026-07-03 22:13:33 -05:00
m_idx_m1[m_idx_m1_size++] = i;
2026-02-06 08:18:57 -05:00
}
}
//---
SetHeader();
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-02-14 20:47:37 -05:00
void CAiLeoMulyiFeatureGen::OnNewBarM1(const datetime curr_time)
2026-02-06 08:18:57 -05:00
{
//---
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 |
//+------------------------------------------------------------------+
2026-02-14 20:47:37 -05:00
void CAiLeoMulyiFeatureGen::ObtenerDataEnMatrix(matrix &mtx, const datetime curr_time)
2026-02-06 08:18:57 -05:00
{
//---
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++)
{
2026-07-03 22:13:33 -05:00
CAiDataLeoFeature* f = m_features[i];
col = f.MtxStartCol();
start_r = f.MtxStartRow();
end_r = f.MtxEndRow();
f.CalcValue(curr_time, m_bid, m_ask);
2026-02-06 08:18:57 -05:00
k = 0;
2026-07-03 22:13:33 -05:00
//---
2026-02-06 08:18:57 -05:00
for(ulong r = start_r; r <= end_r; r++)
{
2026-07-03 22:13:33 -05:00
mtx[r][col] = f.m_v[k++];
2026-02-06 08:18:57 -05:00
}
}
}
//+------------------------------------------------------------------+
2026-02-14 20:47:37 -05:00
void CAiLeoMulyiFeatureGen::ObtenerDataEnVector(vector &vct, const datetime curr_time)
2026-02-06 08:18:57 -05:00
{
//---
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++)
{
2026-07-03 22:13:33 -05:00
m_features[i].CalcValue(curr_time, m_bid, m_ask);
vct[i] = m_features[i].m_v[0]; // Valor 0
2026-02-06 08:18:57 -05:00
}
}
//+------------------------------------------------------------------+
2026-02-14 20:47:37 -05:00
void CAiLeoMulyiFeatureGen::ObtenerVectorAsMatrix(matrix &mtx, const datetime curr_time)
2026-02-06 08:18:57 -05:00
{
//---
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++)
{
2026-07-03 22:13:33 -05:00
m_features[i].CalcValue(curr_time, m_bid, m_ask);
mtx[i][0] = m_features[i].m_v[0]; // Valor 0
2026-02-06 08:18:57 -05:00
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
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++)
{
2026-02-06 11:25:48 -05:00
m_header += AILEO_COMPLEX_GENERIC_COL_NAME + string(i);
2026-02-06 08:18:57 -05:00
if(i < m_cols - 1)
m_header += AILEO_COMPLEX_HEADER_SEP;
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-07-07 18:39:17 -05:00
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<00>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;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-07-06 11:20:10 -05:00
bool CAiLeoMulyiFeatureGen::InternaBuild(CYmlNode& root)
2026-07-03 22:13:33 -05:00
{
//-- Base
m_name = root["name"].ToString("MyFeatureGenerator");
2026-07-06 11:28:10 -05:00
m_cols = (int)root["config"]["cols"].ToInt(0);
2026-07-03 22:13:33 -05:00
//---
2026-07-06 11:20:10 -05:00
CYmlNode output = root["output"];
2026-07-04 11:58:29 -05:00
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;
}
2026-07-03 22:13:33 -05:00
//---
m_rows = (int)output["rows"].ToInt(1);
//---
2026-07-04 11:58:29 -05:00
if(!output["contexts"].IsArray())
2026-07-03 22:13:33 -05:00
return false;
//---
CYmlIteratorArray it = output["contexts"].BeginArr();
//---
int last_idx_arr[];
2026-07-04 11:58:29 -05:00
int last_idx_arr_size = 0;
int fi = 0;
2026-07-03 22:13:33 -05:00
//--- Array
if(m_type == AIDATALEO_GEN_VECTOR)
{
2026-07-04 11:58:29 -05:00
m_features_size = ArrayResize(m_features, (int)m_cols);
//---
2026-07-03 22:13:33 -05:00
while(it.IsValid())
{
2026-07-06 11:20:10 -05:00
CYmlNode obj = it.Val();
2026-07-03 22:13:33 -05:00
//---
2026-07-04 11:58:29 -05:00
int p = 0;
const int type = CEnumRegAiLeo::GetValNoRef<int8_t>(obj["mode"].ToString(""), -1);
2026-07-03 22:13:33 -05:00
switch(type)
{
case AILEO_VECTOR_TYPE_NORMAL: // normal
{
ArrayResize(last_idx_arr, 1);
2026-07-04 11:58:29 -05:00
last_idx_arr[0] = (int)obj["idx"].ToInt(0);
2026-07-03 22:13:33 -05:00
break;
}
case AILEO_VECTOR_TYPE_CUSTOM:
{
2026-07-04 11:58:29 -05:00
last_idx_arr_size = obj["idx"].ToArray(last_idx_arr);
2026-07-03 22:13:33 -05:00
break;
}
2026-07-04 11:58:29 -05:00
default:
LogError("Modo invalido", FUNCION_ACTUAL);
return false;
2026-07-03 22:13:33 -05:00
}
//--- Por cada parametro...
CYmlIteratorArray ita = obj["data"].BeginArr();
while(ita.IsValid())
{
2026-07-06 11:20:10 -05:00
CYmlNode curr_obj = ita.Val();
2026-07-03 22:13:33 -05:00
//--- 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;
}
//---
2026-07-04 11:58:29 -05:00
const bool support_idx = ptr.m_support_idx;
2026-07-03 22:13:33 -05:00
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);
//---
2026-07-04 11:58:29 -05:00
m_features[fi++] = ptr;
//---
2026-07-03 22:13:33 -05:00
ita.Next();
}
//---
it.Next();
}
}
else // Matrix
{
2026-07-04 11:58:29 -05:00
m_features_size = ArrayResize(m_features, int(m_cols * m_rows));
ulong col = 0;
ulong row = 0;
//---
while(it.IsValid())
{
2026-07-06 11:20:10 -05:00
CYmlNode obj = it.Val();
2026-07-04 11:58:29 -05:00
//---
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())
{
//---
2026-07-06 11:20:10 -05:00
CYmlNode curr_obj = ita.Val();
2026-07-03 22:13:33 -05:00
2026-07-04 11:58:29 -05:00
//--- 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<00>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;
2026-07-03 22:13:33 -05:00
}
2026-07-04 11:58:29 -05:00
//---
return true;
2026-07-03 22:13:33 -05:00
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-02-14 20:47:37 -05:00
static void CAiLeoMulyiFeatureGen::GetDataCts(vector& res, const int &indexs[], const int indexs_size, const vector& v)
2026-02-06 08:18:57 -05:00
{
//---
res.Resize(indexs_size);
//---
for(int i = 0; i < indexs_size; i++)
{
res[i] = v[indexs[i]];
}
}
2026-07-03 22:13:33 -05:00
}
2026-02-06 08:18:57 -05:00
//+------------------------------------------------------------------+
#endif // AIDATAGENBYLEO_GENERIC_DATA_BASE_COMPLEX_MQH
//+------------------------------------------------------------------+
2026-07-03 22:13:33 -05:00