Librerías: Expert - página 13

 
fxsaber #:

Si hay algún problema, facilite archivos mq5 listos para reproducir.

#define  MT4ORDERS_LIBRARY
#include "../../utils/MT4Orders.mqh" 
// #define REPORT_BROWSER // Crear un informe con el inicio del navegador - requiere permiso DLL.
#define  TESTER_CUSTOM // Ejecutar el Asesor Experto en el Comprobador de Usuarios
#include "../../utils/fxsaber/Tester/Tester.mqh" // https://www.mql5.com/es/code/24848

#define  Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

#define  KEY_B 66
#define  KEY_S 83
#define  KEY_C 67

input int In1 = 1;
input group "label1"
input double In2 = 2.0;
// 
void OnChartEvent( const int id, const long &lparam, const double &dparam, const string &sparam ) {
  if (id == CHARTEVENT_KEYDOWN) {
    switch ((int)lparam) {
    case KEY_B: // comprar
      OrderSend(_Symbol, OP_BUY, 1, Ask, 100, 0, 0);
      break;
    case KEY_S: // vender
      OrderSend(_Symbol, OP_SELL, 1, Bid, 100, 0, 0);
      break;
    case KEY_C: // cerrar
      for (int i = OrdersTotal() - 1; i >= 0; i--)
        if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL))
          OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100);
    }
  }
}


void OnTick() {
  //Print(_Symbol, " ", SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE));
}
void OnTimer() { /* Comment(REPORT::OrdersToString(_Symbol, 0, 5)); */ }
int OnInit() {
  Print(_Symbol, " ", SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE));
  Print(_Symbol, " In2 = ", In2);
  return(INIT_SUCCEEDED);
}
//
void OnDeinit( const int ) {}
//
void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result) {

}
//+------------------------------------------------------------------+

El código de ejemplo utiliza el código de su biblioteca Tester. Después del arranque, la variable In2 es 0, no 2. Es decir, no se pueden recuperar todos los parámetros de entrada después del grupo.
 
hini #:

Esta situación no parece tenerse en cuenta. Cuando el parámetro es un grupo, no hay un valor específico y el valor obtenido será nulo, por lo que no se obtendrán parámetros después del grupo.

El siguiente código muestra que todo se maneja correctamente.

input int In1 = 1;
input group "label1"
input double In2 = 2.0;

#include <fxsaber\Expert.mqh> // https://www.mql5.com/es/code/19003

int GetAmountExperts()
{
  int Res = 0;
  
  for (long Chart = ChartFirst(); Chart != -1; Chart = ChartNext(Chart))
    Res += (ChartGetString(Chart, CHART_EXPERT_NAME) != "");
    
  return(Res);
}

void OnInit()
{
  if (GetAmountExperts() < 2)
  {
    MqlParam Params[];
    string Names[];
            
    const int Size = EXPERT::Parameters(0, Params, Names) - 1;
    
    ArrayPrint(Params);
    ArrayPrint(Names);
    
    for (uint i = Size; (bool)i--;)
      EXPERT::AddInputName(Params[i + 1], Names[i]);
            
    Params[Size].string_value = "7";
    EXPERT::Run(ChartOpen(_Symbol, _Period), Params);
  }
}


Resultado.

    [type] [integer_value] [double_value]      [string_value]
[0]     14               0           0.00 "Scripts\Test6.ex5"
[1]     14               1           1.00 "1"                
[2]     14               0           0.00 null               
[3]     14               2           2.00 "2.0"              
"In1" null  "In2"


Asesor Experto lanzado a través de Expert.mqh.

 
input bool InRun = true;
input group "label1"
input double In2 = 2.0;

#include <fxsaber\Expert.mqh> // https://www.mql5.com/es/code/19003


int GetAmountExperts()
{
  int Res = 0;
  
  for (long Chart = ChartFirst(); Chart != -1; Chart = ChartNext(Chart))
    Res += (ChartGetString(Chart, CHART_EXPERT_NAME) != "");
    
  return(Res);
}

void OnInit()
{
  if (InRun)
  {
    MqlParam Params[];
    string Names[];
            
    const int Size = EXPERT::Parameters(0, Params, Names) - 1;
    
    ArrayPrint(Params);
    ArrayPrint(Names);
    int nameSize = ArraySize(Names);
    for (int i = nameSize-1; i >= 0; i--) {
      if (Names[i] == "InRun")
        Params[i+1].string_value = "false";
      EXPERT::AddInputName(Params[i + 1], Names[i]);
    }  
            
    ArrayPrint(Params);
    ArrayPrint(Names);
    //Parámetros[Tamaño].valor_cadena = "7";
    EXPERT::Run(ChartOpen(_Symbol, _Period), Params);
    return;
  }
  Print("In2 = ", In2);
}

La función GetAmountExperts se ejecuta por una razón desconocida durante mucho tiempo sin ningún resultado. He cambiado un poco el código - por favor, ejecútelo de nuevo. No debe asignar el valor 7 al parámetro In2 (verá que hay 0, no 2).


 
hini #:

He cambiado el código un poco - por favor, ejecútelo de nuevo.

Este es un informe de error ejemplar: ejecuté el código conciso, que mostró inmediatamente el error.

Hecha la corrección, gracias.

 
fxsaber #:

Este es un informe de error ejemplar: ejecutó un código conciso que inmediatamente mostró un error.

He hecho la corrección, gracias.

Ya veo, en caso de problemas haré informes en el mismo formato.
 

Si se carga el script, parece que no se pueden cambiar los parámetros de entrada.

 //Test1.ex5
#property script_show_inputs
input string str = "test1" ;
//void OnInit() {
void OnStart () {
   Print (str);
}
 // Iniciar el Asesor Experto con los parámetros de entrada especificados
#property script_show_inputs

#include "Expert.mqh"

input bool CurrentChart = false ; // Ejecutar EA en gráfico actual(verdadero)/nuevo(falso)

string GetMyName( void ) {
   return ( StringSubstr ( MQLInfoString ( MQL_PROGRAM_PATH ), StringLen ( TerminalInfoString ( TERMINAL_DATA_PATH ) + "\\MQL5\\" )));
}

bool RunExpert( const long Chart ) {
   MqlParam Params[ 2 ];
  Params[ 0 ].string_value = "Experts\\Advisors\\Test1.ex5" ;
   // El primer parámetro de entrada del Asesor Experto
  Params[ 1 ].type = TYPE_STRING ;
  Params[ 1 ].string_value = "Hello World!" ;
   return (EXPERT::Run(Chart, Params));
}

#define  NAME __FILE__

void OnStart () {
   union UNION {
     double Double;
     long Long;
  } Chart;
   if (CurrentChart) {
    Chart.Long = ChartID ();
     GlobalVariableSet (NAME, Chart.Double);
     MqlParam Params[ 1 ];
     // Ruta a sí mismo (script)
    Params[ 0 ].string_value = GetMyName();
     // En el nuevo gráfico, nos lanzamos
    EXPERT::Run( ChartOpen ( _Symbol , _Period ), Params);
  } else if ( GlobalVariableCheck (NAME)) {
    Chart.Double = GlobalVariableGet (NAME);
     GlobalVariableDel (NAME);
    RunExpert(Chart.Long);
     ChartClose ();
  } else // La forma más fácil de ejecutar el Asesor Experto (con parámetros no predeterminados) no es en el gráfico actual
    RunExpert( ChartOpen ( _Symbol , _Period ));
}
//+------------------------------------------------------------------+
 
hini #:

Si se carga el script, parece que no se pueden cambiar los parámetros de entrada.

Tal es la arquitectura de MT5 que no se pueden establecer valores de parámetros de entrada para los scripts y no se pueden leer.

La biblioteca tiene un nombre elocuente.

 
fxsaber #:

Tal es la arquitectura de MT5 que no se pueden establecer valores de parámetros de entrada para los scripts y no se pueden leer.

La biblioteca tiene un nombre elocuente.

ok
 
Más sobre el tema del modo frame, cuando se lanza la optimización sin establecer intervalos de optimización.
#include <fxsaber\Expert.mqh> // https://www.mql5.com/es/code/19003

input group "Params"
input int inRange1 = 0;
input double inRange2 = 0;

// Comprueba si los intervalos de optimización están configurados.
bool OptimizationIsCorrect()
{
  bool Res = false;
  
  if (MQLInfoInteger(MQL_FRAME_MODE))
  {    
    MqlParam Parameters[];
    string Names[];

    EXPERT::Parameters(0, Parameters, Names);
  
    for (uint i = ArraySize(Names); !Res && (bool)i--;)
    {
      long S[4];
      
      ParameterGetRange(Names[i], Res, S[0], S[1], S[2], S[3]);
    }
  }
      
  return(Res);
}

void OnTesterInit()
{
  if (!OptimizationIsCorrect())
  {
    Alert("no optimized parameter selected, please check input(s) to be optimized and set start, step and stop values");
    
    ChartClose();
  }
}

void OnTesterDeinit() {}
Sin una solución de este tipo, un Asesor Experto en modo marco se queda colgado en el gráfico. Es especialmente crítico cuando se automatiza el Probador.