211 lines
6.5 KiB
MQL5
211 lines
6.5 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| RunEA.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 WORKFLOWSBYLEO_STEPS_RUNEA_MQH
|
|
#define WORKFLOWSBYLEO_STEPS_RUNEA_MQH
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Include |
|
|
//+------------------------------------------------------------------+
|
|
#include <TSN\\ExtraCodes\\Expert.mqh>
|
|
#include <TSN\\MQLArticles\\Utils\\File.mqh>
|
|
#include "..\\Final\\Orquestador.mqh"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
class CWorkStepGenericRunEa : public CWorkflowStep
|
|
{
|
|
private:
|
|
MqlParam m_ea_params[];
|
|
const long m_current_chart_id;
|
|
ENUM_TIMEFRAMES m_timeframe;
|
|
string m_symbol;
|
|
uint8_t m_flags;
|
|
int m_timeout_segundos;
|
|
int m_ms_sincronizar;
|
|
string m_expert_name;
|
|
|
|
public:
|
|
CWorkStepGenericRunEa(void) : CWorkflowStep("RunEA", "Generic", false, 0), m_current_chart_id(ChartID()) {}
|
|
~CWorkStepGenericRunEa(void) {}
|
|
|
|
//---
|
|
bool Init(const CYmlNode& parameters) override final;
|
|
int Run() override final;
|
|
};
|
|
|
|
//---
|
|
WORKFLOWS_FACTORY_DEFINE_CREATOR(CWorkStepGenericRunEa, GenericRunEa, "RunEA", "Generic")
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
#define WORFFLOWSTEP_GENERIC_RUNEA_IDX_EXPERT (0)
|
|
#define WORFFLOWSTEP_GENERIC_RUNEA_IDX_SIMOLO (1)
|
|
#define WORFFLOWSTEP_GENERIC_RUNEA_IDX_TIMEFRAME (2)
|
|
|
|
//---
|
|
bool CWorkStepGenericRunEa::Init(const CYmlNode ¶meters)
|
|
{
|
|
//--- Parametros fijos
|
|
CYmlNode fixed = parameters["fixed"];
|
|
if(fixed.Size() < 2)
|
|
{
|
|
LogError("Como minimo se requiere 1 parametro, en el se ubica el nombre del expert relativo a MQL5\\", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
|
|
// Reserve
|
|
ArrayResize(m_ea_params, 1);
|
|
// EA Name
|
|
if(!m_wf.AssingMqlParam(m_ea_params[0], fixed["name"], TYPE_STRING))
|
|
{
|
|
LogError("No se pudo asignar el nombre del ea", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
m_expert_name = FileRemoveExtensionNoRef(GetPureFileName(m_ea_params[0].string_value));
|
|
|
|
// Symbol
|
|
m_symbol = m_wf.TranslateStr(fixed["symbol"], "_Symbol");
|
|
if(m_symbol == "_Symbol")
|
|
m_symbol = _Symbol;
|
|
|
|
// Timeframe
|
|
m_timeframe = m_wf.TranslateEnum<ENUM_TIMEFRAMES>(fixed["timeframe"], "_Period");
|
|
//Print(EnumToString(m_timeframe));
|
|
|
|
// Flags
|
|
m_flags = EXPERT::FlagsPermisosStrToFlags(m_wf.TranslateStr(fixed["run_flags"], ""), '|');
|
|
//Print(m_flags);
|
|
|
|
// MS sincronizacion
|
|
m_ms_sincronizar = m_wf.TranslateNumber<int>(fixed["ms_sincronizacion"], "1000");
|
|
|
|
// Timeout
|
|
m_timeout_segundos = m_wf.TranslateNumber<int>(fixed["timeout_segundos"], "0");
|
|
if(m_timeout_segundos == 0)
|
|
{
|
|
LogError("Timeout no valido, debe de ser mayor a 0", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//--- Parametros dinamicos Array
|
|
int k = 1;
|
|
CYmlNode ea_parameters_node = parameters["ea_params"];
|
|
ArrayResize(m_ea_params, (1 + ea_parameters_node.Size()));
|
|
CYmlIteratorArray it = ea_parameters_node.BeginArr();
|
|
// Print(ArraySize(m_ea_params) - 1);
|
|
//---
|
|
// los 3 primeros parametros
|
|
while(it.IsValid())
|
|
{
|
|
//---
|
|
CYmlNode parametro = it.Val();
|
|
|
|
//--- Objeto (implicito)
|
|
if(parametro.IsObject())
|
|
{
|
|
//---
|
|
// Movemos al key
|
|
// (no use next tokens por que quiero moverme posiciones)
|
|
// si uso next token me muevo hacia el siguinete obj (se salta todo el obj)
|
|
if(!parametro.MoveNextPositionsThis(1)) // [OBJ] -> [KEY base] (End se conserva)
|
|
{
|
|
LogError("Se intento mover al siguiente key pero no se pudo revise la sintazxis del yml", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
// Saltamos a val
|
|
// false dado que perdimos el contexto en
|
|
if(!parametro.MoveToNextToken()) // [KEYBASE][KEYINFO] a [ARR]
|
|
{
|
|
// Print(parametro.m_idx);
|
|
// Print(parametro.m_end);
|
|
//Print(EnumToString(parametro.GetType()));
|
|
LogError("Se intento mover al siguiente valor pero no se pudo revise la sintazxis del yml", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
}
|
|
// else: arr
|
|
|
|
//--- Asignamos
|
|
// [TYPE, VALOR]
|
|
//Print(parametro.Size());
|
|
if(!m_wf.AssingMqlParam(m_ea_params[k++], parametro.At(1), parametro.At(0).ToString())) // 1 = valor | 0 = tipo
|
|
{
|
|
ArrayResize(m_ea_params, 0); // En caso de ejeuccino dara fallo
|
|
LogError(StringFormat("Fallo al asingnar el valor al parametro, posible = %s tipo invalido", EnumToString(parametro.GetType())), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
// Print(EnumToString(m_ea_params[k - 1].type));
|
|
|
|
|
|
//---
|
|
it.Next();
|
|
}
|
|
|
|
//---
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
int CWorkStepGenericRunEa::Run(void)
|
|
{
|
|
//---
|
|
const long chart_id = OpenChartAndDevoler(m_current_chart_id, m_symbol, m_timeframe, m_ms_sincronizar);
|
|
|
|
//---
|
|
if(chart_id == -1)
|
|
{
|
|
LogError("No se pudo abrir un grafico", FUNCION_ACTUAL);
|
|
return 1;
|
|
}
|
|
|
|
//--- Lanza el EA
|
|
if(!EXPERT::Run(chart_id, m_ea_params, m_flags))
|
|
{
|
|
LogError("Fallo al ejecutar ea", FUNCION_ACTUAL);
|
|
ArrayPrint(m_ea_params);
|
|
//Print(TYPE_STRING);
|
|
::ChartClose(chart_id);
|
|
return 1;
|
|
}
|
|
|
|
//---
|
|
int c = 0;
|
|
bool is_t = false;
|
|
while(ChartGetString(chart_id, CHART_EXPERT_NAME) == m_expert_name)
|
|
{
|
|
Sleep(500);
|
|
if((++c >> 1) >= m_timeout_segundos)
|
|
{
|
|
is_t = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//---
|
|
::ChartClose(chart_id);
|
|
|
|
//---
|
|
if(is_t)
|
|
{
|
|
LogError(StringFormat("Ejecucion del EA %s, supero el timeout", m_expert_name), FUNCION_ACTUAL);
|
|
}
|
|
|
|
//---
|
|
return is_t;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
#endif // WORKFLOWSBYLEO_STEPS_RUNEA_MQH
|