MQLArticles/Utils/SetFiles/Main.mqh
Nique_372 1a974a7918
2026-02-19 12:52:23 -05:00

1775 satır
115 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 MQLARTICLES_UTILS_SETFILES_MAIN_MQH
#define MQLARTICLES_UTILS_SETFILES_MAIN_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "..\\Basic.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
enum ENUM_SETFILE_LINE_TYPE
{
SETFILE_LINE_TYPE_NOINPUT = 1,
SETFILE_LINE_TYPE_INPUT = 0
};
//---
string g_setfile_dyn_arr[5];
//---
struct SetFileParam
{
string name;
string value;
string start;
string step;
string stop;
//---
SetFileParam()
: value(NULL), start(NULL), step(NULL), stop(NULL)
{
}
//---
// si start == NULL signfiica que es invalido para optimizar
__forceinline string Format() { return start != NULL ? StringFormat("%s=%s||%s||%s||%s||N", name, value, start, step, stop) : (name + "=" + value); }
};
//---
struct pack(4) SetFileLine
{
ENUM_SETFILE_LINE_TYPE type;
int id;
};
//---
SetFileParam EMPTY_SETFILE_PARAM;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CSetFile : public CLoggerBase
{
private:
//---
CHashMap<string, int>* m_hashmap_params;
bool m_init;
//--- Lines
SetFileLine m_lines[];
int m_lines_size;
//--- Inputs
int m_params_size;
SetFileParam m_params[];
//--- Strings
int m_no_params_size;
string m_no_params[];
//--- Data
string m_expert_name;
datetime m_saved_time;
//---
void ChangeSavedTime(const datetime new_time);
public:
CSetFile(void);
~CSetFile(void);
//---
bool Init(const string& expert_name);
bool InitByFile(const string& file_name, int extra_file_flags, uint reserve);
bool InitBySrc(const string& src, ushort separator, uint reserve);
//---
bool Save(const string& file_name, int extra_file_flags);
//---
void Clean();
//---
void GetAsString(string &out) const;
int GetAsStringArray(string& out[]) const;
//---
void Summary() const;
void Imprimir() const;
void ImprimirLinesArray() const { ArrayPrint(m_lines, 2, "|"); }
void ImprimirParamsArray() const { ArrayPrint(m_params, 2, "|"); }
void ImprimirNoParamsArray() const { ArrayPrint(m_no_params, 2, "|"); }
//--- Getters \Setters
__forceinline int ParamsSize() const { return m_params_size; }
__forceinline SetFileParam GetParam(const int idx) const { return m_params[idx]; }
__forceinline SetFileParam GetParam(const string str) const;
__forceinline int GetParamIdx(const string str) const;
__forceinline int NoParamsSize() const { return m_no_params_size; }
__forceinline string GetNoParmas(const int idx) const { return m_no_params[idx]; }
__forceinline int LinesSize() const { return m_lines_size; }
__forceinline SetFileLine GetLine(const int idx) const { return m_lines[idx]; }
// Expert name
__forceinline string ExpertName() const { return m_expert_name; }
void ExpertName(const string& v) { m_expert_name = v; }
// Saved time
__forceinline datetime SavedTime() const { return m_saved_time; }
//--- Funciones para remover un alinea (idx indice en m_lines)
bool RemoveLine(const int idx);
//--- Funciones para trabajar con los parametros
//- Agrega un parametro (al final) (por defecto start, etc es null osea que noe s optimizable si se espeicfia los 3 valores entonces si es optimzable)
bool AddParamLineString(const string& name, const string& value);
// Number
template <typename TInteger>
bool AddParamLineNumber(const string& name, const TInteger value, const TInteger start, const TInteger step, const TInteger stop);
// Real
template <typename TNumber>
bool AddParamLineReal(const string& name, const TNumber value, int8_t presicion, const TNumber start, const TNumber step, const TNumber stop);
// Bool
bool AddParamLineBool(const string& name, const bool value);
// Enum
template <typename TEnum>
bool AddParamLineEnum(const string& name, const TEnum value, const TEnum start, const TEnum stop);
// Datetime
bool AddParamLineDatetime(const string& name, const datetime value, const datetime start, const long step_sec, const datetime stop);
// Color
bool AddParamLineColor(const string& name, const color value);
// Idx = indice del FILE
//- Inserta
bool InsertParamLineString(const int idx, const string& name, const string& value);
template <typename TInteger>
bool InsertParamLineNumber(const int idx, const string& name, const TInteger value, const TInteger start, const TInteger step, const TInteger stop);
template <typename TNumber>
bool InsertParamLineReal(const int idx, const string& name, const TNumber value, int8_t presicion, const TNumber start, const TNumber step, const TNumber stop);
bool InsertParamLineBool(const int idx, const string& name, const bool value);
template <typename TEnum>
bool InsertParamLineEnum(const int idx, const string& name, const TEnum value, const TEnum start, const TEnum stop);
bool InsertParamLineDatetime(const int idx, const string& name, const datetime value, const datetime start, const long step_sec, const datetime stop);
bool InsertParamLineColor(const int idx, const string& name, const color value);
//- Modificar
// Nombre de parametro
bool ModifyParamName(const string param_name, const string& new_name);
bool ModifyParamName(const int idx, const string& new_name);
// Valor de parametro (value)
template <typename TInteger> // Todo tipo de numero integer uinteger | datetime | color
bool ModifyParamValueNumber(const string param_name, const TInteger v);
template <typename TNumber> // Double float
bool ModifyParamValueRealNumber(const string param_name, const TNumber v, int8_t presicion);
bool ModifyParamValueBoolean(const string param_name, const bool v);
bool ModifyParamValueString(const string param_name, const string v);
template <typename TEnum> // Double float
bool ModifyParamValueEnum(const string param_name, const TEnum v);
bool ModifyParamValueDatetime(const string param_name, const datetime v);
bool ModifyParamValueColor(const string param_name, const color v);
// ModifyParamOptNumber
template <typename TInteger>
bool ModifyParamOptNumberStart(const string param_name, const TInteger start);
template <typename TInteger>
bool ModifyParamOptNumberStep(const string param_name, const TInteger step);
template <typename TInteger>
bool ModifyParamOptNumberStop(const string param_name, const TInteger stop);
// ModifyParamOptRealNumber
template <typename TNumber>
bool ModifyParamOptRealNumberStart(const string param_name, const TNumber start, int8_t presicion);
template <typename TNumber>
bool ModifyParamOptRealNumberStep(const string param_name, const TNumber step, int8_t presicion);
template <typename TNumber>
bool ModifyParamOptRealNumberStop(const string param_name, const TNumber stop, int8_t presicion);
// Modify opt datetime
bool ModifyParamOptDatetimeStart(const string param_name, const datetime start);
bool ModifyParamOptDatetimeStep(const string param_name, const long step_sec);
bool ModifyParamOptDatetimeStop(const string param_name, const datetime stop);
// ModifyParamOptEnum
template <typename TEnum>
bool ModifyParamOptEnumStart(const string param_name, const TEnum start);
template <typename TEnum>
bool ModifyParamOptEnumStop(const string param_name, const TEnum stop);
//- Verificar exisitencia
bool ParamExist(const string& param_name) { return m_hashmap_params.ContainsKey(param_name); }
//- Lectura
string ReadParamValueString(const string param_name) const;
template <typename TInteger>
TInteger ReadParamValueInteger(const string param_name) const;
template <typename TNumber>
TNumber ReadParamValueReal(const string param_name) const;
datetime ReadParamValueDatetime(const string param_name) const;
color ReadParamValueColor(const string param_name) const;
bool ReadParamValueBool(const string param_name) const;
//--- Funciones para trabajar con no parametyros
//- Añade al final
void AddNoParamsLine(const string& line);
// Mencionar que idx es el indice en el FILE
//- Inserta
void InsertNoParamLine(const int idx, const string& line);
//- Modifica
void ModifyNoParamLine(const int idx, const string& new_line);
//---
bool IsValidIdxLine(const int idx) { return idx >= 0 && idx < m_lines_size; }
//---
CHashMap<string, int>* HashMapPointer() { return m_hashmap_params; }
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CSetFile::CSetFile(void)
{
m_hashmap_params = new CHashMap<string, int>();
Clean(); // Inicilizacion
}
//+------------------------------------------------------------------+
CSetFile::~CSetFile()
{
if(CheckPointer(m_hashmap_params) == POINTER_DYNAMIC)
delete m_hashmap_params;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CSetFile::Clean(void)
{
m_hashmap_params.Clear();
m_lines_size = ArrayResize(m_lines, 0);
m_params_size = ArrayResize(m_params, 0);
m_no_params_size = ArrayResize(m_no_params, 0);
m_expert_name = NULL;
m_saved_time = 0;
m_init = false;
}
//+------------------------------------------------------------------+
//| Funciones de carga Load |
//+------------------------------------------------------------------+
bool CSetFile::Init(const string &expert_name)
{
//---
if(m_init)
{
LogWarning("Limpiando dado que se inicia denuevo", FUNCION_ACTUAL);
Clean();
}
//---
m_expert_name = expert_name;
m_saved_time = TimeLocal();
m_init = true;
//---
m_no_params_size = ArrayResize(m_no_params, 4);
m_no_params[0] = StringFormat("; saved on %s", TimeToString(m_saved_time, TIME_DATE | TIME_MINUTES | TIME_SECONDS));
m_no_params[1] = StringFormat("; this file contains input parameters for testing/optimizing %s expert advisor", m_expert_name);
m_no_params[2] = "; to use it in the strategy tester, click Load in the context menu of the Inputs tab";
m_no_params[3] = ";";
//---
m_lines_size = ArrayResize(m_lines, 4);
m_lines[0].type = SETFILE_LINE_TYPE_NOINPUT;
m_lines[0].id = 0;
m_lines[1].type = SETFILE_LINE_TYPE_NOINPUT;
m_lines[1].id = 1;
m_lines[2].type = SETFILE_LINE_TYPE_NOINPUT;
m_lines[2].id = 2;
m_lines[3].type = SETFILE_LINE_TYPE_NOINPUT;
m_lines[3].id = 3;
//---
return true;
}
//+------------------------------------------------------------------+
bool CSetFile::InitBySrc(const string &src, ushort separator, uint reserve)
{
//---
if(m_init)
{
LogWarning("Limpiando dado que se inicia denuevo", FUNCION_ACTUAL);
Clean();
}
//---
string arr[];
const int size = StringSplit(src, separator, arr);
if(size == -1)
{
LogError("Fallo al hacer split", FUNCION_ACTUAL);
return false;
}
//---
int ilec = 0;
//--- Reservamos para no params
reserve = fmax(3, reserve); // Como minimo un valor de 2
int cn = ArrayResize(m_no_params, reserve);
//---
int rl = ArrayResize(m_lines, reserve);
//--- Extramoes el tiempo de guardado
string line = arr[ilec++];
int len = StringLen(line);
int pos = 0;
while(line[pos] < '0' || line[pos] > '9') // Solo iterar mientras el caracter pos no sea un nuemro
{
pos++;
if(pos >= len)
{
LogError("En la primera linea debe de ubicarse un nuermo (fecha de creacion)", FUNCION_ACTUAL);
return false;
}
}
m_saved_time = StringToTime(StringSubstr(line, pos)); // Desde el inicio del numero hasta el fin del string
// Add
m_lines[m_lines_size].type = SETFILE_LINE_TYPE_NOINPUT;
m_lines[m_lines_size++].id = m_no_params_size;
m_no_params[m_no_params_size++] = line;
//--- Extraemos el nombre del bot
line = arr[ilec++];
len = StringLen(line);
pos = 0;
// Primero buscaremos /
while(line[pos] != '/')
{
pos++;
if(pos >= len)
{
LogError("En la segunda linea del archivo se debe de ubicar el caracter / ", FUNCION_ACTUAL);
return false;
}
}
// Avanzamos hasta el siguiente espacio
while(line[pos] != ' ')
{
pos++;
if(pos >= len)
{
LogError("En la segunda linea del archivo se debe de ubicar el caracter / ", FUNCION_ACTUAL);
return false;
}
}
pos++; // Luego del espacio (inicio del nombre del bot)
// Comenzamos desde el fin hasta el 2do espacio
int c = 2;
int end = len - 1;
while(c > 0)
{
end--;
if(end < 0)
{
LogError("En la segunda linea del archivo deben de al menos haber dos espacios empezados desde atras ", FUNCION_ACTUAL);
return false;
}
if(line[end] == ' ')
c--;
}
m_expert_name = StringSubstrRange(line, pos, end);
// Add
m_lines[m_lines_size].type = SETFILE_LINE_TYPE_NOINPUT;
m_lines[m_lines_size++].id = m_no_params_size;
m_no_params[m_no_params_size++] = line;
//---
c = ArrayResize(m_params, reserve);
//--- Cargamos todos los parametros
while(ilec < size)
{
line = arr[ilec++];
if(line == NULL)
continue;
//---
if(line[0] == ';') // Comentarios | Sinput
{
//---
m_lines[m_lines_size].type = SETFILE_LINE_TYPE_NOINPUT;
m_lines[m_lines_size++].id = m_no_params_size;
//---
m_no_params[m_no_params_size++] = line;
if(m_no_params_size >= cn)
{
cn <<= 1;
ArrayResize(m_no_params, cn);
}
}
else
{
//---
int vs = line.Find("=");
if(vs == -1)
{
LogWarning(StringFormat("Omitiendo linea corrupta:\n'%s'", line), FUNCION_ACTUAL);
continue;
}
//---
m_lines[m_lines_size].type = SETFILE_LINE_TYPE_INPUT;
m_lines[m_lines_size++].id = m_params_size;
//---
m_params[m_params_size].name = StringSubstr(line, 0, vs);
if(!m_hashmap_params.Add(m_params[m_params_size].name, m_params_size))
{
LogError(StringFormat("Fallo al agregar el parametro =%s al hashmap", m_params[m_params_size].name), FUNCION_ACTUAL);
return false;
}
//---
vs++;
//---
const int t = StringSplitStr(StringSubstr(line, vs), "||", g_setfile_dyn_arr, 5);
if(t < 1)
{
LogCriticalError("El split debe dar como minimo 1 cadena de resultado", FUNCION_ACTUAL);
return false;
}
//---
m_params[m_params_size].value = g_setfile_dyn_arr[0];
//---
if(t == 5 && g_setfile_dyn_arr[4].Find("N") >= 0) // Optimizable
{
m_params[m_params_size].start = g_setfile_dyn_arr[1];
m_params[m_params_size].step = g_setfile_dyn_arr[2];
m_params[m_params_size].stop = g_setfile_dyn_arr[3];
}
//---
m_params_size++;
//---
if(m_params_size >= c)
{
c <<= 1;
ArrayResize(m_params, c);
}
}
//---
if(m_lines_size >= rl)
{
rl <<= 1;
ArrayResize(m_lines, rl);
}
}
//--- Truncamos
ArrayResize(m_params, m_params_size);
ArrayResize(m_no_params, m_no_params_size);
ArrayResize(m_lines, m_lines_size);
//---
m_init = true;
//--- Exito
return true;
}
//+------------------------------------------------------------------+
bool CSetFile::InitByFile(const string &file_name, int extra_file_flags, uint reserve)
{
//---
if(m_init)
{
LogWarning("Limpiando dado que se inicia denuevo", FUNCION_ACTUAL);
Clean();
}
//---
ResetLastError();
const int fh = FileOpen(file_name, FILE_READ | FILE_TXT | extra_file_flags);
if(fh == INVALID_HANDLE)
{
LogError(StringFormat("Fallo al abrir el archivo '%s', ultimo error = %d", file_name, GetLastError()), FUNCION_ACTUAL);
return false;
}
//--- Reservamos para no params
reserve = fmax(3, reserve); // Como minimo un valor de 2
int cn = ArrayResize(m_no_params, reserve);
//---
int rl = ArrayResize(m_lines, reserve);
//--- Extramoes el tiempo de guardado
string line = FileReadString(fh);
int len = StringLen(line);
int pos = 0;
while(line[pos] < '0' || line[pos] > '9') // Solo iterar mientras el caracter pos no sea un nuemro
{
pos++;
if(pos >= len)
{
LogError("En la primera linea debe de ubicarse un nuermo (fecha de creacion)", FUNCION_ACTUAL);
return false;
}
}
m_saved_time = StringToTime(StringSubstr(line, pos)); // Desde el inicio del numero hasta el fin del string
// Add
m_lines[m_lines_size].type = SETFILE_LINE_TYPE_NOINPUT;
m_lines[m_lines_size++].id = m_no_params_size;
m_no_params[m_no_params_size++] = line;
//--- Extraemos el nombre del bot
line = FileReadString(fh);
len = StringLen(line);
pos = 0;
// Primero buscaremos /
while(line[pos] != '/')
{
pos++;
if(pos >= len)
{
LogError("En la segunda linea del archivo se debe de ubicar el caracter / ", FUNCION_ACTUAL);
return false;
}
}
// Avanzamos hasta el siguiente espacio
while(line[pos] != ' ')
{
pos++;
if(pos >= len)
{
LogError("En la segunda linea del archivo se debe de ubicar el caracter / ", FUNCION_ACTUAL);
return false;
}
}
pos++; // Luego del espacio (inicio del nombre del bot)
// Comenzamos desde el fin hasta el 2do espacio
int c = 2;
int end = len - 1;
while(c > 0)
{
end--;
if(end < 0)
{
LogError("En la segunda linea del archivo deben de al menos haber dos espacios empezados desde atras ", FUNCION_ACTUAL);
return false;
}
if(line[end] == ' ')
c--;
}
m_expert_name = StringSubstrRange(line, pos, end);
// Add
m_lines[m_lines_size].type = SETFILE_LINE_TYPE_NOINPUT;
m_lines[m_lines_size++].id = m_no_params_size;
m_no_params[m_no_params_size++] = line;
//---
c = ArrayResize(m_params, reserve);
//--- Cargamos todos los parametros
while(!FileIsEnding(fh))
{
line = FileReadString(fh);
if(line == NULL)
continue;
//---
if(line[0] == ';') // Comentarios | Sinput
{
//---
m_lines[m_lines_size].type = SETFILE_LINE_TYPE_NOINPUT;
m_lines[m_lines_size++].id = m_no_params_size;
//---
m_no_params[m_no_params_size++] = line;
if(m_no_params_size >= cn)
{
cn <<= 1;
ArrayResize(m_no_params, cn);
}
}
else
{
//---
int vs = line.Find("=");
if(vs == -1)
{
LogWarning(StringFormat("Omitiendo linea corrupta:\n'%s'", line), FUNCION_ACTUAL);
continue;
}
//---
m_lines[m_lines_size].type = SETFILE_LINE_TYPE_INPUT;
m_lines[m_lines_size++].id = m_params_size;
//---
m_params[m_params_size].name = StringSubstr(line, 0, vs);
if(!m_hashmap_params.Add(m_params[m_params_size].name, m_params_size))
{
LogError(StringFormat("Fallo al agregar el parametro =%s al hashmap", m_params[m_params_size].name), FUNCION_ACTUAL);
return false;
}
//---
vs++;
//---
const int t = StringSplitStr(StringSubstr(line, vs), "||", g_setfile_dyn_arr, 5);
if(t < 1)
{
LogCriticalError("El split debe dar como minimo 1 cadena de resultado", FUNCION_ACTUAL);
return false;
}
//---
m_params[m_params_size].value = g_setfile_dyn_arr[0];
//---
if(t == 5 && g_setfile_dyn_arr[4].Find("N") >= 0) // Optimizable
{
m_params[m_params_size].start = g_setfile_dyn_arr[1];
m_params[m_params_size].step = g_setfile_dyn_arr[2];
m_params[m_params_size].stop = g_setfile_dyn_arr[3];
}
//---
m_params_size++;
//---
if(m_params_size >= c)
{
c <<= 1;
ArrayResize(m_params, c);
}
}
//---
if(m_lines_size >= rl)
{
rl <<= 1;
ArrayResize(m_lines, rl);
}
}
//--- Truncamos
ArrayResize(m_params, m_params_size);
ArrayResize(m_no_params, m_no_params_size);
ArrayResize(m_lines, m_lines_size);
//--- Cerramos
FileClose(fh);
//---
m_init = true;
//--- Exito
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CSetFile::Save(const string &file_name, int extra_file_flags)
{
//---
ResetLastError();
const int fh = FileOpen(file_name, FILE_WRITE | FILE_TXT | extra_file_flags);
if(fh == INVALID_HANDLE)
{
LogError(StringFormat("Fallo al abrir el archivo = %s, ultimo error = %d", file_name, GetLastError()), FUNCION_ACTUAL);
return false;
}
//---
ChangeSavedTime(TimeLocal());
//---
for(int i = 0; i < m_lines_size; i++)
{
if(m_lines[i].type == SETFILE_LINE_TYPE_INPUT)
{
FileWrite(fh, m_params[m_lines[i].id].Format());
}
else
{
FileWrite(fh, m_no_params[m_lines[i].id]);
}
}
//---
FileClose(fh);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CSetFile::GetAsString(string &out) const
{
//ArrayPrint(m_lines);
for(int i = 0; i < m_lines_size; i++)
{
if(m_lines[i].type == SETFILE_LINE_TYPE_INPUT)
{
//Print(m_lines[i].id);
out += m_params[m_lines[i].id].Format() + "\n";
}
else
{
out += m_no_params[m_lines[i].id] + "\n";
}
}
if(m_lines_size > 0)
out.Truncate(out.Length() - 1);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CSetFile::GetAsStringArray(string &out[]) const
{
int s = ArrayResize(out, m_lines_size);
for(int i = 0; i < m_lines_size; i++)
{
if(m_lines[i].type == SETFILE_LINE_TYPE_INPUT)
{
out[i] = m_params[m_lines[i].id].Format();
}
else
{
out[i] = m_no_params[m_lines[i].id];
}
}
return s;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CSetFile::Summary(void) const
{
Print("---- Expert name: ", m_expert_name);
Print(" Saved time: ", m_saved_time);
Print(" Total lines: ", m_lines_size);
Print(" Total params: ", m_params_size);
Print(" Total no params: ", m_no_params_size);
}
//+------------------------------------------------------------------+
void CSetFile::Imprimir(void) const
{
string str = "";
GetAsString(str);
Print(str);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
__forceinline SetFileParam CSetFile::GetParam(const string str) const
{
//---
static int real_idx;
((CSetFile*)&this).m_hashmap_params.TryGetValue(str, real_idx);
return m_params[real_idx]; // Sin comprobacion en caso de error INVALID
// La idea es que si el parametro es invalido (no existe) y se llame a esta funcion entonces de error
// En caso de las demas funcoines se retonan un bool (por algo) para saber si se modifico o no
// En cambio aqui retonamos directamente un valor
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
__forceinline int CSetFile::GetParamIdx(const string str) const
{
//---
int real_idx = INVALID_INDEX;
((CSetFile*)&this).m_hashmap_params.TryGetValue(str, real_idx);
return real_idx;
}
//+------------------------------------------------------------------+
//| Modificar el nombre del parametro |
//+------------------------------------------------------------------+
bool CSetFile::ModifyParamName(const int idx, const string &new_name)
{
//---
const int real_idx = m_lines[idx].id;
//---
if(!m_hashmap_params.Remove(m_params[real_idx].name))
{
LogError(StringFormat("No se pudo remover del hashmap, param name = %s", m_params[real_idx].name), FUNCION_ACTUAL);
return false;
}
//---
m_params[real_idx].name = new_name;
//---
if(m_hashmap_params.Add(new_name, real_idx))
{
return true;
}
else
{
LogError(StringFormat("No se pudo agregatr el parametro con nombre = %s, al hashamp", new_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
bool CSetFile::ModifyParamName(const string param_name, const string &new_name)
{
//---
static int real_idx;
//---
if(!m_hashmap_params.TryGetValue(param_name, real_idx))
{
LogError(StringFormat("El parametro = %s, no existe", param_name), FUNCION_ACTUAL);
return false;
}
//---
if(!m_hashmap_params.Remove(m_params[real_idx].name))
{
LogError(StringFormat("No se pudo remover del hashmap, param name = %s", m_params[real_idx].name), FUNCION_ACTUAL);
return false;
}
//---
m_params[real_idx].name = new_name;
//---
if(m_hashmap_params.Add(new_name, real_idx))
{
return true;
}
else
{
LogError(StringFormat("No se pudo agregatr el parametro con nombre = %s, al hashamp", new_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
//| Modify value |
//+------------------------------------------------------------------+
template <typename TInteger>
bool CSetFile::ModifyParamValueNumber(const string param_name, const TInteger v)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].value = string(v);
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
template <typename TNumber>
bool CSetFile::ModifyParamValueRealNumber(const string param_name, const TNumber v, int8_t presicion)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].value = DoubleToString(v, presicion);
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
bool CSetFile::ModifyParamValueBoolean(const string param_name, const bool v)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].value = v ? "true" : "false";
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
bool CSetFile::ModifyParamValueString(const string param_name, const string v)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].value = v;
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
template <typename TEnum>
bool CSetFile::ModifyParamValueEnum(const string param_name, const TEnum v)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].value = string((int)v);
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
bool CSetFile::ModifyParamValueDatetime(const string param_name, const datetime v)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].value = string(long(v));
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
bool CSetFile::ModifyParamValueColor(const string param_name, const color v)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].value = string((int)v);
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
//| Modify datetime |
//+------------------------------------------------------------------+
bool CSetFile::ModifyParamOptDatetimeStart(const string param_name, const datetime start)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].start = string(long(start));
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
bool CSetFile::ModifyParamOptDatetimeStep(const string param_name, const long step_sec)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].step = string(step_sec);
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
bool CSetFile::ModifyParamOptDatetimeStop(const string param_name, const datetime stop)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].stop = string(long(stop));
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
//| Modificar Number Opt |
//+------------------------------------------------------------------+
template <typename TInteger>
bool CSetFile::ModifyParamOptNumberStart(const string param_name, const TInteger start)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].start = string(start);
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
template <typename TInteger>
bool CSetFile::ModifyParamOptNumberStep(const string param_name, const TInteger step)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].step = string(step);
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
template <typename TInteger>
bool CSetFile::ModifyParamOptNumberStop(const string param_name, const TInteger stop)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].stop = string(stop);
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
//| Modificar Real Number Opt |
//+------------------------------------------------------------------+
template <typename TNumber>
bool CSetFile::ModifyParamOptRealNumberStart(const string param_name, const TNumber start, int8_t presicion)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].start = DoubleToString(start, presicion);
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
template <typename TNumber>
bool CSetFile::ModifyParamOptRealNumberStep(const string param_name, const TNumber step, int8_t presicion)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].step = DoubleToString(step, presicion);
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
template <typename TNumber>
bool CSetFile::ModifyParamOptRealNumberStop(const string param_name, const TNumber stop, int8_t presicion)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].stop = DoubleToString(stop, presicion);
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
//| Enum |
//+------------------------------------------------------------------+
template <typename TEnum>
bool CSetFile::ModifyParamOptEnumStart(const string param_name, const TEnum start)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].start = string((int)start);
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
template <typename TEnum>
bool CSetFile::ModifyParamOptEnumStop(const string param_name, const TEnum stop)
{
static int idx;
if(m_hashmap_params.TryGetValue(param_name, idx))
{
m_params[idx].stop = string((int)stop);
return true;
}
else
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
}
//+------------------------------------------------------------------+
//| Funcion general para remover una linea |
//+------------------------------------------------------------------+
bool CSetFile::RemoveLine(const int idx)
{
//---
const int ri = m_lines[idx].id;
const ENUM_SETFILE_LINE_TYPE type = m_lines[idx].type;
for(int i = idx; i < m_lines_size - 1; i++)
{
m_lines[i] = m_lines[i + 1];
}
ArrayResize(m_lines, (--m_lines_size));
//---
/*
S = Parametro REAl Pararm (params)
N = No paramero (no_params)
LTYPE= Tipo de linea, como valores toma 2 = [S, N]
# Ejemplo de array
m_lines m_params m_no_params
LTYPE PARAMIDX NOPARAMIDX
S 0 -
S 1 -
S 2 -
S 3 -
S 4 -
# Eliminamos linea 0
m_lines m_params m_no_params
LTYPE PARAMIDX NOPARAMIDX
S 1 -
S 2 -
S 3 -
S 4 -
# Aqui habria que reducir paramidx en los restantes?¿
Ahora mismo pasaria esto:
Hariamos un swap entre elemtno eliminamo y utlimo
asi que se camiba de posicon 4->0
asi que el indice sero apunta al 4
m_lines m_params m_no_params
LTYPE PARAMIDX NOPARAMIDX
S 1 -
S 2 -
S 3 -
S 0 -
# Vale enotnces deberimaos de ubicar y reponde "Donde se ubica el linea con real index = last" ?
# Una vez tengamos su indice poor ejemplo en nuestro ejemplo seria el indice 4 entonces modificamos m_lines[4].id = ri
*/
//---
if(type == SETFILE_LINE_TYPE_INPUT)
{
//---
if(!m_hashmap_params.Remove(m_params[ri].name))
{
LogError(StringFormat("Fallo al eliminar el parametro '%s' del hashmap", m_params[ri].name), FUNCION_ACTUAL);
return false;
}
//---
const int last = (--m_params_size);
if(ri != last) // Solo si no es igual no es 0 como minimo hayt 1 elemneo
{
m_params[ri] = m_params[last];
if(!m_hashmap_params.TrySetValue(m_params[ri].name, ri))
{
LogError(StringFormat("Error al modificar el valor de %s a idx = %d", m_params[ri].name, ri), FUNCION_ACTUAL);
return false;
}
}
//---
// Ahora su RI de ester parametro cambia ya no apunta a
for(int i = 0; i < m_lines_size; i++)
{
if(m_lines[i].type == SETFILE_LINE_TYPE_INPUT && m_lines[i].id == last) //
{
m_lines[i].id = ri;
break;
}
}
//---
ArrayResize(m_params, m_params_size);
}
else
{
int last = --m_no_params_size;
if(ri != last)
{
m_no_params[ri] = m_no_params[last];
for(int i = 0; i < m_lines_size; i++) // Redirigir la linea que apuntaba a last
{
if(m_lines[i].type == SETFILE_LINE_TYPE_NOINPUT && m_lines[i].id == last)
{
m_lines[i].id = ri;
break;
}
}
}
ArrayResize(m_no_params, m_no_params_size);
}
//---
return true;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Funciones para trabnajar con lineas no param |
//+------------------------------------------------------------------+
void CSetFile::AddNoParamsLine(const string &line)
{
ArrayResize(m_lines, m_lines_size + 1);
m_lines[m_lines_size].id = m_no_params_size;
m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_NOINPUT;
ArrayResize(m_no_params, m_no_params_size + 1);
m_no_params[m_no_params_size++] = line;
}
//+------------------------------------------------------------------+
void CSetFile::InsertNoParamLine(const int idx, const string &line)
{
ArrayResize(m_lines, m_lines_size + 1);
for(int i = m_lines_size; i > idx; i--)
m_lines[i] = m_lines[i - 1];
m_lines[idx].type = SETFILE_LINE_TYPE_NOINPUT;
m_lines[idx].id = m_no_params_size;
m_lines_size++;
ArrayResize(m_no_params, m_no_params_size + 1);
m_no_params[m_no_params_size++] = line;
}
//+------------------------------------------------------------------+
void CSetFile::ModifyNoParamLine(const int idx, const string &new_line)
{
// NO hay check de idx
m_no_params[m_lines[idx].id] = new_line;
}
//+------------------------------------------------------------------+
//| Añadir parametros al final |
//+------------------------------------------------------------------+
bool CSetFile::AddParamLineString(const string &name, const string &value)
{
ArrayResize(m_lines, m_lines_size + 1);
m_lines[m_lines_size].id = m_params_size;
m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_INPUT;
if(!m_hashmap_params.Add(name, m_params_size))
{
LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
return false;
}
ArrayResize(m_params, m_params_size + 1);
m_params[m_params_size].name = name;
m_params[m_params_size++].value = value;
return true;
}
//+------------------------------------------------------------------+
template <typename TInteger>
bool CSetFile::AddParamLineNumber(const string &name, const TInteger value, const TInteger start, const TInteger step, const TInteger stop)
{
ArrayResize(m_lines, m_lines_size + 1);
m_lines[m_lines_size].id = m_params_size;
m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_INPUT;
if(!m_hashmap_params.Add(name, m_params_size))
{
LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
return false;
}
ArrayResize(m_params, m_params_size + 1);
m_params[m_params_size].name = name;
m_params[m_params_size].value = string(value);
m_params[m_params_size].start = string(start);
m_params[m_params_size].step = string(step);
m_params[m_params_size++].stop = string(stop);
return true;
}
//+------------------------------------------------------------------+
template <typename TNumber>
bool CSetFile::AddParamLineReal(const string &name, const TNumber value, int8_t presicion, const TNumber start, const TNumber step, const TNumber stop)
{
ArrayResize(m_lines, m_lines_size + 1);
m_lines[m_lines_size].id = m_params_size;
m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_INPUT;
if(!m_hashmap_params.Add(name, m_params_size))
{
LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
return false;
}
ArrayResize(m_params, m_params_size + 1);
m_params[m_params_size].name = name;
m_params[m_params_size].value = DoubleToString(value, presicion);
m_params[m_params_size].start = DoubleToString(start, presicion);
m_params[m_params_size].step = DoubleToString(step, presicion);
m_params[m_params_size++].stop = DoubleToString(stop, presicion);
return true;
}
//+------------------------------------------------------------------+
bool CSetFile::AddParamLineBool(const string &name, const bool value)
{
ArrayResize(m_lines, m_lines_size + 1);
m_lines[m_lines_size].id = m_params_size;
m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_INPUT;
if(!m_hashmap_params.Add(name, m_params_size))
{
LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
return false;
}
ArrayResize(m_params, m_params_size + 1);
m_params[m_params_size].name = name;
m_params[m_params_size].value = value ? "true" : "false";
m_params[m_params_size].start = "false";
m_params[m_params_size].step = "0";
m_params[m_params_size++].stop = "true";
return true;
}
//+------------------------------------------------------------------+
template <typename TEnum>
bool CSetFile::AddParamLineEnum(const string &name, const TEnum value, const TEnum start, const TEnum stop)
{
ArrayResize(m_lines, m_lines_size + 1);
m_lines[m_lines_size].id = m_params_size;
m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_INPUT;
if(!m_hashmap_params.Add(name, m_params_size))
{
LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
return false;
}
ArrayResize(m_params, m_params_size + 1);
m_params[m_params_size].name = name;
m_params[m_params_size].value = string((int)value);
m_params[m_params_size].start = string((int)start);
m_params[m_params_size].step = "0";
m_params[m_params_size++].stop = string((int)stop);
return true;
}
//+------------------------------------------------------------------+
bool CSetFile::AddParamLineDatetime(const string &name, const datetime value, const datetime start, const long step_sec, const datetime stop)
{
ArrayResize(m_lines, m_lines_size + 1);
m_lines[m_lines_size].id = m_params_size;
m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_INPUT;
if(!m_hashmap_params.Add(name, m_params_size))
{
LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
return false;
}
ArrayResize(m_params, m_params_size + 1);
m_params[m_params_size].name = name;
m_params[m_params_size].value = string(long(value));
m_params[m_params_size].start = string(long(start));
m_params[m_params_size].step = string(step_sec);
m_params[m_params_size++].stop = string(long(stop));
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CSetFile::AddParamLineColor(const string &name, const color value)
{
ArrayResize(m_lines, m_lines_size + 1);
m_lines[m_lines_size].id = m_params_size;
m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_INPUT;
if(!m_hashmap_params.Add(name, m_params_size))
{
LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
return false;
}
ArrayResize(m_params, m_params_size + 1);
m_params[m_params_size].name = name;
m_params[m_params_size++].value = string((int)value);
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CSetFile::InsertParamLineString(const int idx, const string &name, const string &value)
{
ArrayResize(m_lines, m_lines_size + 1);
for(int i = m_lines_size; i > idx; i--)
m_lines[i] = m_lines[i - 1];
m_lines[idx].id = m_params_size;
m_lines[idx].type = SETFILE_LINE_TYPE_INPUT;
m_lines_size++;
if(!m_hashmap_params.Add(name, m_params_size))
{
LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
return false;
}
ArrayResize(m_params, m_params_size + 1);
m_params[m_params_size].name = name;
m_params[m_params_size++].value = value;
return true;
}
//+------------------------------------------------------------------+
template <typename TInteger>
bool CSetFile::InsertParamLineNumber(const int idx, const string &name, const TInteger value, const TInteger start, const TInteger step, const TInteger stop)
{
ArrayResize(m_lines, m_lines_size + 1);
for(int i = m_lines_size; i > idx; i--)
m_lines[i] = m_lines[i - 1];
m_lines[idx].id = m_params_size;
m_lines[idx].type = SETFILE_LINE_TYPE_INPUT;
m_lines_size++;
if(!m_hashmap_params.Add(name, m_params_size))
{
LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
return false;
}
ArrayResize(m_params, m_params_size + 1);
m_params[m_params_size].name = name;
m_params[m_params_size].value = string(value);
m_params[m_params_size].start = string(start);
m_params[m_params_size].step = string(step);
m_params[m_params_size++].stop = string(stop);
return true;
}
//+------------------------------------------------------------------+
template <typename TNumber>
bool CSetFile::InsertParamLineReal(const int idx, const string &name, const TNumber value, int8_t presicion, const TNumber start, const TNumber step, const TNumber stop)
{
ArrayResize(m_lines, m_lines_size + 1);
for(int i = m_lines_size; i > idx; i--)
m_lines[i] = m_lines[i - 1];
m_lines[idx].id = m_params_size;
m_lines[idx].type = SETFILE_LINE_TYPE_INPUT;
m_lines_size++;
if(!m_hashmap_params.Add(name, m_params_size))
{
LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
return false;
}
ArrayResize(m_params, m_params_size + 1);
m_params[m_params_size].name = name;
m_params[m_params_size].value = DoubleToString(value, presicion);
m_params[m_params_size].start = DoubleToString(start, presicion);
m_params[m_params_size].step = DoubleToString(step, presicion);
m_params[m_params_size++].stop = DoubleToString(stop, presicion);
return true;
}
//+------------------------------------------------------------------+
bool CSetFile::InsertParamLineBool(const int idx, const string &name, const bool value)
{
ArrayResize(m_lines, m_lines_size + 1);
for(int i = m_lines_size; i > idx; i--)
m_lines[i] = m_lines[i - 1];
m_lines[idx].id = m_params_size;
m_lines[idx].type = SETFILE_LINE_TYPE_INPUT;
m_lines_size++;
if(!m_hashmap_params.Add(name, m_params_size))
{
LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
return false;
}
ArrayResize(m_params, m_params_size + 1);
m_params[m_params_size].name = name;
m_params[m_params_size].value = value ? "true" : "false";
m_params[m_params_size].start = "false";
m_params[m_params_size].step = "0";
m_params[m_params_size++].stop = "true";
return true;
}
//+------------------------------------------------------------------+
template <typename TEnum>
bool CSetFile::InsertParamLineEnum(const int idx, const string &name, const TEnum value, const TEnum start, const TEnum stop)
{
ArrayResize(m_lines, m_lines_size + 1);
for(int i = m_lines_size; i > idx; i--)
m_lines[i] = m_lines[i - 1];
m_lines[idx].id = m_params_size;
m_lines[idx].type = SETFILE_LINE_TYPE_INPUT;
m_lines_size++;
if(!m_hashmap_params.Add(name, m_params_size))
{
LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
return false;
}
ArrayResize(m_params, m_params_size + 1);
m_params[m_params_size].name = name;
m_params[m_params_size].value = string((int)value);
m_params[m_params_size].start = string((int)start);
m_params[m_params_size].step = "0";
m_params[m_params_size++].stop = string((int)stop);
return true;
}
//+------------------------------------------------------------------+
bool CSetFile::InsertParamLineDatetime(const int idx, const string &name, const datetime value, const datetime start, const long step_sec, const datetime stop)
{
ArrayResize(m_lines, m_lines_size + 1);
for(int i = m_lines_size; i > idx; i--)
m_lines[i] = m_lines[i - 1];
m_lines[idx].id = m_params_size;
m_lines[idx].type = SETFILE_LINE_TYPE_INPUT;
m_lines_size++;
if(!m_hashmap_params.Add(name, m_params_size))
{
LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
return false;
}
ArrayResize(m_params, m_params_size + 1);
m_params[m_params_size].name = name;
m_params[m_params_size].value = string(long(value));
m_params[m_params_size].start = string(long(start));
m_params[m_params_size].step = string(step_sec);
m_params[m_params_size++].stop = string(long(stop));
return true;
}
//+------------------------------------------------------------------+
bool CSetFile::InsertParamLineColor(const int idx, const string &name, const color value)
{
ArrayResize(m_lines, m_lines_size + 1);
for(int i = m_lines_size; i > idx; i--)
m_lines[i] = m_lines[i - 1];
m_lines[idx].id = m_params_size;
m_lines[idx].type = SETFILE_LINE_TYPE_INPUT;
m_lines_size++;
if(!m_hashmap_params.Add(name, m_params_size))
{
LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
return false;
}
ArrayResize(m_params, m_params_size + 1);
m_params[m_params_size].name = name;
m_params[m_params_size++].value = string((int)value);
return true;
}
//+------------------------------------------------------------------+
//| Read value |
//+------------------------------------------------------------------+
string CSetFile::ReadParamValueString(const string param_name) const
{
static int idx;
if(!((CSetFile*)&this).m_hashmap_params.TryGetValue(param_name, idx))
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return NULL;
}
return m_params[idx].value;
}
//+------------------------------------------------------------------+
template <typename TInteger>
TInteger CSetFile::ReadParamValueInteger(const string param_name) const
{
static int idx;
if(!((CSetFile*)&this).m_hashmap_params.TryGetValue(param_name, idx))
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return (TInteger)0;
}
return TInteger(m_params[idx].value);
}
//+------------------------------------------------------------------+
template <typename TNumber>
TNumber CSetFile::ReadParamValueReal(const string param_name) const
{
static int idx;
if(!((CSetFile*)&this).m_hashmap_params.TryGetValue(param_name, idx))
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return (TNumber)0.0;
}
return TNumber(m_params[idx].value);
}
//+------------------------------------------------------------------+
datetime CSetFile::ReadParamValueDatetime(const string param_name) const
{
static int idx;
if(!((CSetFile*)&this).m_hashmap_params.TryGetValue(param_name, idx))
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return 0;
}
return datetime(long(m_params[idx].value));
}
//+------------------------------------------------------------------+
color CSetFile::ReadParamValueColor(const string param_name) const
{
static int idx;
if(!((CSetFile*)&this).m_hashmap_params.TryGetValue(param_name, idx))
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return clrNONE;
}
return color(int(m_params[idx].value));
}
//+------------------------------------------------------------------+
bool CSetFile::ReadParamValueBool(const string param_name) const
{
static int idx;
if(!((CSetFile*)&this).m_hashmap_params.TryGetValue(param_name, idx))
{
LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
return false;
}
return m_params[idx].value == "true";
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CSetFile::ChangeSavedTime(const datetime new_time)
{
if(m_lines_size < 1)
{
LogCriticalError("SetFile vacio", FUNCION_ACTUAL);
return;
}
//---
const int ri = m_lines[0].id;
//---
int len = StringLen(m_no_params[ri]);
int pos = 0;
while(m_no_params[ri][pos] < '0' || m_no_params[ri][pos] > '9') // Solo iterar mientras el caracter pos no sea un nuemro
{
pos++;
if(pos >= len)
{
LogError("En la primera linea debe de ubicarse un nuermo (fecha de creacion)", FUNCION_ACTUAL);
return;
}
}
// Truincamos el nombre del string hasta el pos (la idea es eliminar el time)
m_no_params[ri].Truncate(pos);
m_no_params[ri] += TimeToString(new_time, TIME_MINUTES | TIME_DATE | TIME_SECONDS);
}
//+------------------------------------------------------------------+
#endif // MQLARTICLES_UTILS_SETFILES_MAIN_MQH