derivato da nique_372/MQLArticles
1775 righe
115 KiB
MQL5
1775 righe
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
|