English Русский 中文 Deutsch 日本語 Português 한국어 Français Italiano Türkçe
Cambiar los Parámetros del Asesor Experto desde el Panel de Usuario "Sobre la Marcha"

Cambiar los Parámetros del Asesor Experto desde el Panel de Usuario "Sobre la Marcha"

MetaTrader 5Ejemplos | 28 mayo 2014, 09:13
3 521 0
Anatoli Kazharski
Anatoli Kazharski

Contenidos

Introducción
1. Asuntos en el Punto de Mira
2. Estructura del Asesor Experto
3. Interacción con el Panel de Usuario
Conclusión


Introducción

Al desarrollar Asesores Expertos complejos, el número de parámetros externos puede ser muy grande. Y la configuración debe cambiarse manualmente muy a menudo, lo que hace el proceso entero muy largo en los casos de listas masivas de parámetros. Por supuesto, un usuario puede preparar conjuntos por adelantado y guardarlos, pero puede que no sean exactamente lo que se requiere en algunos casos. Aquí es donde MQL5 puede resultar de utilidad, como siempre.

Creemos un panel de usuario que nos permita cambiar los parámetros de un Asesor Experto "sobre la marcha" durante el proceso de trading. Esto podría ser relevante para aquellos que realizan operaciones de trading manualmente o en modo semi-automático. Al realizar cualquier cambio, los parámetros se escribirán en un archivo desde donde los leerá el Asesor Experto para mostrarlos después en el panel.


1. Asuntos en el Punto de Mira

Para ilustrar esto, desarrollaremos un EA (Asesor Experto) sencillo que abrirá una posición en la dirección del indicador JMA. El EA funcionará en barras completas del símbolo e intervalo cronológico actual. Los parámetros externos incluirán Indicator Period, Stop Loss, Take Profit, Reverse y Lot. Estas opciones serán más que suficientes para nuestro ejemplo.

Añadamos dos parámetros adicionales para poder encender y apagar el panel (el Panel On/Off) y activar/desactivar el modo de configuración de parámetros del Asesor Experto (configuración "On The Fly", o "Sobre la Marcha"). Allá donde el número de parámetros es grande siempre será más conveniente colocar opciones adicionales al principio o final de la lista para un acceso fácil y rápido.

Fig. 1. Panel de Información con parámetros del Asesor Experto.

Fig. 1. Panel de Información con parámetros del Asesor Experto.

El modo de configuración "On The Fly" está desactivado por defecto. Cuando active este modo por primera vez, el Asesor Experto creará un archivo para guardar todos los parámetros que tiene actualmente. Lo mismo ocurrirá si el archivo de elimina por accidente. El Asesor Experto detectará la eliminación y recreará el archivo. Con el modo de configuración "On The Fly" desactivado, el Asesor Experto se guiará por parámetros externos.

Si este modo está activado, el Asesor Experto leerá los parámetros del archivo y, simplemente haciendo click en cualquier parámetro en el panel de información, usted podrá seleccionar el valor requerido o introducir un nuevo valor en el cuadro de diálogo emergente. Los datos del archivo se actualizarán cada vez que se seleccione un nuevo valor.


2. Estructura del Asesor Experto

Aunque el programa es pequeño y todas las funciones podrían caber perfectamente en un archivo, es mucho más conveniente categorizar toda la información correctamente para tener un mejor acceso a ella después. Por tanto, es mejor categorizar las funciones por tipo y guardarlas en diferentes archivos desde el principio para incluirlas después en un archivo maestro. La figura de abajo muestra una carpeta de proyecto compartida con el Asesor Experto OnTheFly y todos los archivos include. Los archivos include se colocan en una carpeta separada (Include).

Fig. 2. Los archivos del proyecto en la ventana de navegador de MetaEditor

Fig. 2. Los archivos del proyecto en la ventana de navegador de MetaEditor

Cuando los archivos include están en la misma carpeta con el archivo maestro, el código tiene el siguiente aspecto:

//+------------------------------------------------------------------+
//| CUSTOM LIBRARIES                                                 |
//+------------------------------------------------------------------+
#include "Include/!OnChartEvent.mqh"
#include "Include/CREATE_PANEL.mqh"
#include "Include/FILE_OPERATIONS.mqh"
#include "Include/ERRORS.mqh"
#include "Include/ARRAYS.mqh"
#include "Include/TRADE_SIGNALS.mqh"
#include "Include/TRADE_FUNCTIONS.mqh"
#include "Include/GET_STRING.mqh"
#include "Include/GET_COLOR.mqh"
#include "Include/ADD_FUNCTIONS.mqh"

Puede encontrar más información sobre cómo incluir archivos en el material de Referencia MQL5.

Necesitaremos variables globales, copias de parámetros externos. Sus valores se asignarán desde los parámetros externos del archivo, dependiendo del modo del Asesor Experto. Estas variables se usan a través del código de programa entero, por ejemplo al mostrar valores en el panel de información, al operar con funciones, etc.

// COPY OF EXTERNAL PARAMETERS
int    gPeriod_Ind = 0;
double gTakeProfit = 0.0;
double gStopLoss   = 0.0;
bool   gReverse    = false;
double gLot        = 0.0;

Al igual que con todos los demás Asesores Expertos, tendremos las funciones principales: OnInit, OnTick y OnDeinit. Y también tendremos la función OnTimer. En cada segundo comprobará la existencia del archivo de parámetros y lo restaurará en caso de que haya sido eliminado por accidente. Como debemos interactuar con el panel de usuario, se usará también la función OnChartEvent. Esta función se ha colocado en un archivo separado (!OnChartEvent.mqh), junto con las otras funciones relacionadas.

El código base del archivo maestro tiene el siguiente aspecto:

#define szArrIP 5 // Size of the parameter array
#define NAME_EXPERT MQL5InfoString(MQL5_PROGRAM_NAME) // Name of EA
#define TRM_DP TerminalInfoString(TERMINAL_DATA_PATH) // Folder that contains the terminal data
//+------------------------------------------------------------------+
//| STANDARD LIBRARIES                                               |
//+------------------------------------------------------------------+
#include <Trade/SymbolInfo.mqh>
#include <Trade/Trade.mqh>
//+------------------------------------------------------------------+
//| CUSTOM LIBRARIES                                                 |
//+------------------------------------------------------------------+
#include "Include/!OnChartEvent.mqh"
#include "Include/CREATE_PANEL.mqh"
#include "Include/FILE_OPERATIONS.mqh"
#include "Include/ERRORS.mqh"
#include "Include/ARRAYS.mqh"
#include "Include/TRADE_SIGNALS.mqh"
#include "Include/TRADE_FUNCTIONS.mqh"
#include "Include/GET_STRING.mqh"
#include "Include/GET_COLOR.mqh"
#include "Include/ADD_FUNCTIONS.mqh"
//+------------------------------------------------------------------+
//| CREATING CLASS INSTANCES                                         |
//+------------------------------------------------------------------+
CSymbolInfo mysymbol; // CSymbolInfo class object 
CTrade      mytrade;  // CTrade class object
//+------------------------------------------------------------------+
//| EXTERNAL PARAMETERS                                              |
//+------------------------------------------------------------------+
input int    Period_Ind      = 10;    // Indicator Period
input double TakeProfit      = 100;   // Take Profit (p)
input double StopLoss        = 30;    // Stop Loss (p)
input bool   Reverse         = false; // Reverse Position
input double Lot             = 0.1;   // Lot
//---
input string slash="";       // * * * * * * * * * * * * * * * * * * *
sinput bool  InfoPanel       = true;  // On/Off Info Panel
sinput bool  SettingOnTheFly = false; // "On The Fly" Setting
//+------------------------------------------------------------------+
//| GLOBAL VARIABLES                                                 |
//+------------------------------------------------------------------+
int hdlSI=INVALID_HANDLE; // Signal indicator handle
double lcheck=0;  // For the check of parameter values
bool isPos=false; // Position availability
//--- COPY OF EXTERNAL PARAMETERS
int    gPeriod_Ind = 0;
double gTakeProfit = 0.0;
double gStopLoss   = 0.0;
bool   gReverse    = false;
double gLot        = 0.0;
//+------------------------------------------------------------------+
//| EXPERT ADVISOR INITIALIZATION                                    |
//+------------------------------------------------------------------+
void OnInit()
  {
   if(NotTest()) { EventSetTimer(1); } // If it's not the tester, set the timer
//---
   Init_arr_vparams(); // Initialization of the array of parameter values
   SetParameters(); // Set the parameters
   GetIndicatorsHandles(); // Get indicator handles
   NewBar(); // New bar initialization
   SetInfoPanel(); // Info panel
  }
//+------------------------------------------------------------------+
//| CURRENT SYMBOL TICKS                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
// If the bar is not new, exit
   if(!NewBar()) { return; }
   else
     { TradingBlock(); }
  }
//+------------------------------------------------------------------+
//| TIMER                                                            |
//+------------------------------------------------------------------+
void OnTimer()
  {
   SetParameters(); SetInfoPanel();
  }
//+------------------------------------------------------------------+
//| EXPERT ADVISOR DEINITIALIZATION                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
// Get the deinitialization reason code
   if(NotTest()) {
     { Print(getUnitReasonText(reason)); }
//---
// When deleting from the chart
   if(reason==REASON_REMOVE)
     {
      // Delete all objects created by the Expert Advisor
      DeleteAllExpertObjects();
      //---
      if(NotTest()) { EventKillTimer(); } // Stop the timer
      IndicatorRelease(hdlSI); // Delete the indicator handle
     }
  }

También he incluido algunas funciones más en el archivo maestro:

  • GetIndicatorsHandles – obtiene el identificador del indicador.
  • NewBar – determina el evento de barra nueva.
  • SetParameters – configura los parámetros dependiendo del modo.
  • iZeroMemory – pone a cero algunas variables y arrays.
Los códigos fuente para estas funciones se pueden encontrar en los archivos adjuntos al artículo. Aquí solo revisaremos la función SetParameters (los comentarios explicativos se facilitan en el código):
//+------------------------------------------------------------------+
//| SETTING PARAMETERS IN TWO MODES                                  |
//+------------------------------------------------------------------+
// If this variable is set to false, the parameters in the file are read from the array
// where they are saved for quick access after they have been read for the first time.
// The variable is zeroed out upon the change in the value on the panel.
bool flgRead=false;
double arrParamIP[]; // Array where the parameters from the file are saved
//---
void SetParameters()
  {
// If currently in the tester or
// in real time but with the "On The Fly" Setting mode disabled
   if(!NotTest() || (NotTest() && !SettingOnTheFly))
     {
      // Zero out the variable and parameter array
      flgRead=false;
      ArrayResize(arrParamIP,0);
      //---
      // Check the Indicator Period for correctness
      if(Period_Ind<=0)
        { lcheck=10; }
      else { lcheck=Period_Ind; }
      gPeriod_Ind=(int)lcheck;
      //---
      gStopLoss=StopLoss;
      gTakeProfit=TakeProfit;
      gReverse=Reverse;
      //---
      // Check the Lot for correctness
      if(Lot<=0)
        { lcheck=0.1; }
      else { lcheck=Lot; }
      gLot=lcheck;
     }
   else // If "On The Fly" Setting mode is enabled
     {
      // Check whether there is a file to write/read parameters to/from the file
      string lpath="";
      //---
      // If the folder exists
      if((lpath=CheckCreateGetPath())!="")
        {
         // Write or read the file
         WriteReadParameters(lpath);
        }
     }
  }

El código fuente para la función SetParameters es sencillo y directo. Echemos un vistazo más detallado a la función WriteReadParameters. Todo es bastante sencillo en este caso. Primero comprobaremos si existe el archivo con parámetros. Si existe, leeremos el archivo y escribiremos valores de parámetro en un array usando la función GetValuesParamsFromFile. Si el archivo no existe, se creará con los parámetros externos actuales escritos en él.

Abajo se encuentra el código con comentarios más detallados para la implementación de las acciones descritas arriba:

//+------------------------------------------------------------------+
//| WRITE DATA TO FILE                                               |
//+------------------------------------------------------------------+
void WriteReadParameters(string pth)
  {
   string nm_fl=pth+"ParametersOnTheFly.ini"; // File name and path
//---
// Get the file handle to read the file
   int hFl=FileOpen(nm_fl,FILE_READ|FILE_ANSI);
//---
   if(hFl!=INVALID_HANDLE) // If the handle has been obtained, the file exists
     {
      // Get parameters from the file
      if(!flgRead)
        {
         // Set the array size
         ArrayResize(arrParamIP,szArrIP);
         //---
         // Fill the array with values from the file
         flgRead=GetValuesParamsFromFile(hFl,arrParamIP);
        }
      //---
      // If the array size is correct,...
      if(ArraySize(arrParamIP)==szArrIP)
        {
         // ...set the parameters to the variables
         //---
         // Check the Indicator Period for correctness
         if((int)arrParamIP[0]<=0) { lcheck=10; }
         else { lcheck=(int)arrParamIP[0]; }
         gPeriod_Ind=(int)lcheck;
         //---
         gTakeProfit=arrParamIP[1];
         gStopLoss=arrParamIP[2];
         gReverse=arrParamIP[3];
         //---
         // Check the Lot for correctness
         if(arrParamIP[4]<=0)
           { lcheck=0.1; }
         else { lcheck=arrParamIP[4]; }
         gLot=lcheck;
        }
     }
   else // If the file does not exist
     {
      iZeroMemory(); // Zero out variables
      //---
      // When creating the file, write current parameters of the Expert Advisor
      //---
      // Get the file handle to write to the file
      int hFl2=FileOpen(nm_fl,FILE_WRITE|FILE_CSV|FILE_ANSI,"");
      //---
      if(hFl2!=INVALID_HANDLE) // If the handle has been obtained
        {
         string sep="=";
         //---
         // Parameter names and values are obtained from arrays in the ARRAYS.mqh file
         for(int i=0; i<szArrIP; i++)
           { FileWrite(hFl2,arr_nmparams[i],sep,arr_vparams[i]); }
         //---
         FileClose(hFl2); // Close the file
         //---
         Print("File with parameters of the "+NAME_EXPERT+" Expert Advisor created successfully.");
        }
     }
//---
   FileClose(hFl); // Close the file
  }

Las funciones WriteReadParameters y GetValuesParamsFromFile se pueden encontrar en el archivo FILE_OPERATIONS.mqh.

Algunas de las funciones ya se han descrito en mi artículo anterior "How to Prepare MetaTrader 5 Quotes for Other Applications" ("Cómo Preparar Cuotas de MetaTrader 5 para Otras Aplicaciones"), por tanto no insistiremos en ello aquí. Tampoco debería tener dificultades con funciones de trading, puesto que son muy claras y se comentan con detenimiento. Ahora nos centraremos en el tema principal de este artículo.


3. Interacción con el Panel de Usuario

El archivo !OnChartEvent.mqh contiene funciones para la interacción con el panel de usuario. Las variables y arrays que se usan en muchas funciones se declaran en el ámbito global al principio:

// Current value on the panel or
// entered in the input box
string currVal="";
bool flgDialogWin=false; // Flag for panel existence
int
szArrList=0,// Size of the option list array
number=-1; // Parameter number in the panel list
string
nmMsgBx="",  // Name of the dialog window
nmValObj=""; // Name of the selected object
//---
// Option list arrays in the dialog window
string lenum[],lenmObj[];
//---
// colors of the dialog window elements
color
clrBrdBtn=clrWhite,
clrBrdFonMsg=clrDimGray,clrFonMsg=C'15,15,15',
clrChoice=clrWhiteSmoke,clrHdrBtn=clrBlack,
clrFonHdrBtn=clrGainsboro,clrFonStr=C'22,39,38';

A esto le siguen las funciones principales que gestionan eventos. En nuestro ejemplo, necesitaremos gestionar dos eventos:

  • El evento CHARTEVENT_OBJECT_CLICK - click con el botón izquierdo en el objeto gráfico.
  • El evento CHARTEVENT_OBJECT_EDIT - final de edición de texto en el objeto gráfico Edit.

Puede leer más sobre otros eventos de MQL5 en el material de Referencia de MQL5.

Primero configuremos una comprobación de la gestión de eventos solo en tiempo real, siempre suponiendo que el modo de configuración "On The Fly" esté activado (SettingOnTheFly). La gestión de eventos se llevará a cabo con funciones separadas: ChartEvent_ObjectClick y ChartEvent_ObjectEndEdit.

//+------------------------------------------------------------------+
//| USER EVENTS                                                      |
//+------------------------------------------------------------------+
void OnChartEvent(const int     id,
                  const long   &lparam,
                  const double &dparam,
                  const string &sparam)
  {
// If the event is real time and the "On The Fly" setting mode is enabled
   if(NotTest() && SettingOnTheFly)
     {
      //+------------------------------------------------------------------+
      //| THE CHARTEVENT_OBJECT_CLICK EVENT                                |
      //+------------------------------------------------------------------+
      if(ChartEvent_ObjectClick(id,lparam,dparam,sparam)) { return; }
      //---
      //+------------------------------------------------------------------+
      //| THE CHARTEVENT_OBJECT_ENDEDIT EVENT                              |
      //+------------------------------------------------------------------+
      if(ChartEvent_ObjectEndEdit(id,lparam,dparam,sparam)) { return; }
     }
//---
   return;
  }

Al hacer click en el objeto que pertenece a la lista, aparecerá un cuadro de diálogo en el panel de información que le permitirá seleccionar otro valor o introducir un valor nuevo en el campo de entrada.

Fig. 3. Cuadro de diálogo para modificar el valor del parámetro seleccionado

Fig. 3. Cuadro de diálogo para modificar el valor del parámetro seleccionado

Echemos un vistazo más detallado a su funcionamiento. Al hacer click en un objeto gráfico, el programa usa primero la función ChartEvent_ObjectClick para comprobar por medio del identificador del evento si realmente se dio un click en un objeto gráfico.

Si desea que el cuadro de diálogo se abra en medio del gráfico, debe saber el tamaño del gráfico. Se puede obtener indicando las propiedades CHART_WIDTH_IN_PIXELS y CHART_HEIGHT_IN_PIXELS en la función ChartGetInteger. Entonces, el programa cambia al panel DialogWindowInfoPanel. Se puede familiarizar con todas las propiedades de los gráficos en el material de Referencia MQL5.

Abajo puede ver el código para la implementación de las acciones mencionadas:

//+------------------------------------------------------------------+
//| THE CHARTEVENT_OBJECT_CLICK EVENT                                |
//+------------------------------------------------------------------+
bool ChartEvent_ObjectClick(int id,long lparam,double dparam,string sparam)
  {
   // If there was an event of clicking on a graphical object
   if(id==CHARTEVENT_OBJECT_CLICK) // id==1
     {
      Get_STV(); // Get all data on the symbol
      //---
      string clickedChartObject=sparam; // Name of the clicked object
      //---
      // Get the chart size
      width_chart=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0);
      height_chart=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0);
      //---
      DialogWindowInfoPanel(clickedChartObject);
     }
//---
   return(false);
  }

Usando la función DialogWindowInfoPanel, comprobaremos primero si el cuadro de diálogo está actualmente abierto. Si el cuadro de diálogo no se encuentra, la función GetNumberClickedObjIP comprueba si el click se hizo en relación a un objeto de la lista en el panel de información. Si el objeto en el que ha hecho click es el objeto de la lista, la función devolverá el número de elemento relevante del array de objetos. Usando ese número, la función InitArraysAndDefault determinará a continuación el tamaño del array de lista en el cuadro de diálogo y valores por defecto. Si todas las acciones se realizan con éxito, el cuadro de diálogo aparecerá.

Si la función DialogWindowInfoPanel determina que el cuadro de diálogo ya está abierto, el programa comprobará si hubo un click en un objeto en el cuadro de diálogo. Por ejemplo, al abrir el cuadro de diálogo, la línea cuyo valor ya se muestra en el panel aparecerá como seleccionada. Si hace click en otra opción en la lista, el programa usará la función SelectionOptionInDialogWindow, que selecciona la opción de lista de cuadro de diálogo cliqueada.

Si hace click en la opción de lista que ya está seleccionada, este objeto se identificará como un objeto a editar, y aparecerá un campo de entrada para introducir un valor nuevo al hacer click en el campo. La función SetEditObjInDialogWindow es responsable de la configuración del campo de entrada.

Y finalmente, si se hizo click en el botón Apply (Aplicar), el programa comprobará si el valor se ha modificado. Si se modificó, el nuevo valor aparecerá en el panel y se escribirá en el archivo.

El código de la función principal del cuadro de diálogo se muestra a continuación:

//+------------------------------------------------------------------+
//| DIALOG WINDOW OF THE INFO PANEL                                  |
//+------------------------------------------------------------------+
void DialogWindowInfoPanel(string clickObj)
  {
// If there is currently no dialog window
   if(!flgDialogWin)
     {
      // Get the object number in the array
      // Exit if none of the parameters displayed on the panel has been clicked
      if((number=GetNumberClickedObjIP(clickObj))==-1) { return; }
      //---
      // Initialization of default values
      //and determination of the list array size
      if(!InitArraysAndDefault()) { return; }
      //---
      // Set the dialog window
      SetDialogWindow();
      //---
      flgDialogWin=true; // Mark the dialog window as open
      ChartRedraw();
     }
   else // If the dialog window is open
     {
      // Set the input box for the modification of the value
      SetEditObjInDialogWindow(clickObj);
      //---
      // If one of the buttons in the dialog box is clicked
      if(clickObj=="btnApply" || clickObj=="btnCancel")
        {
         // If the Apply button is clicked
         if(clickObj=="btnApply")
           {
            // Compare values on the panel with the ones on the list
            // If the value on the list is different from the one that is currently displayed on the panel 
            // (which means it is different from the one in the file),
            // ...change the value on the panel and update the file
            if(currVal!=ObjectGetString(0,nmValObj,OBJPROP_TEXT))
              {
               // Update the value on the panel
               ObjectSetString(0,nmValObj,OBJPROP_TEXT,currVal); ChartRedraw();
               //---
               // Read all data on the panel and write it to the file
               WriteNewData();
              }
           }
         //---
         DelDialogWindow(lenmObj); // Delete the dialog window
         iZeroMemory(); // Zero out the variables
         //---
         // Update the data
         SetParameters();
         GetHandlesIndicators();
         SetInfoPanel();
         //---
         ChartRedraw();
        }
      else // If neither Apply nor Cancel has been clicked
        {
         // Selection of the dialog window list option
         SelectionOptionInDialogWindow(clickObj);
         //---
         ChartRedraw();
        }
     }
  }

Cada vez que se introduce un nuevo valor en el campo de entrada, se genera el evento CHARTEVENT_OBJECT_EDIT, y el programa cambia a la función ChartEvent_ObjectEndEdit. Si el valor del cuadro de diálogo se modificó, el valor introducido se guardará, se revisará su corrección y se asignará al objeto en la lista. Puede verlo más en detalle en el código de abajo:

//+------------------------------------------------------------------+
//| THE CHARTEVENT_OBJECT_ENDEDIT EVENT                              |
//+------------------------------------------------------------------+
bool ChartEvent_ObjectEndEdit(int id,long lparam,double dparam,string sparam)
  {
   if(id==CHARTEVENT_OBJECT_ENDEDIT) // id==3
     {
      string editObject=sparam; // Name of the edited object
      //---
      // If the value has been entered in the input box in the dialog window
      if(editObject=="editValIP")
        {
         // Get the entered value
         currVal=ObjectGetString(0,"editValIP",OBJPROP_TEXT);
         //---
         // (0) Period Indicator
         if(number==0)
           {
            // Correct the value if it is wrong
            if(currVal=="0" || currVal=="" || SD(currVal)<=0) { currVal="1"; }
            //---
            // Set the entered value
            ObjectSetString(0,"enumMB0",OBJPROP_TEXT,currVal);
           }
         //---
         // (4) Lot
         if(number==4)
           {
            // Correct the value if it is wrong
            if(currVal=="0" || currVal=="" || SD(currVal)<=0) { currVal=DS(SS.vol_min,2); }
            //---
            // Set the entered value
            ObjectSetString(0,"enumMB0",OBJPROP_TEXT,DS2(SD(currVal)));
           }
         //---
         // (1) Take Profit (p)
         // (2) Stop Loss (p)
         if(number==1 || number==2)
           {
            // Correct the value if it is wrong
            if(currVal=="0" || currVal=="" || SD(currVal)<=0) { currVal="1"; }
            //---
            // Set the entered value
            ObjectSetString(0,"enumMB1",OBJPROP_TEXT,currVal);
           }
         //---         
         DelObjbyName("editValIP"); ChartRedraw();
        }
     }
//---
   return(false);
  }

Puede ver el Asesor Experto en acción en el vídeo de abajo:



Conclusión

Puede descargarse los archivos comprimidos al final del artículo para estudiarlos más a fondo.

Espero que este artículo sea de ayuda para aquellos que hayan empezado a estudiar MQL5 para encontrar respuestas rápidas a muchas preguntas usando los sencillos ejemplos dados. No incluí a propósito algunas comprobaciones de los fragmentos facilitados.

Por ejemplo, si cambia la altura/anchura del gráfico cuando el cuadro de diálogo está abierto, el cuadro de diálogo no se centrará automáticamente. Y si además usted lo complementa seleccionando otra opción de la lista, el objeto que sirve para seleccionar la línea relevante cambiará considerablemente. Estos serán sus deberes. Es muy importante practicar programación, y cuanto más practique, mejor hará las cosas.

¡Buena suerte!

Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/572

Archivos adjuntos |
onthefly_en.zip (26.38 KB)
Aprendizaje Automático: Cómo usar las Máquinas de Vectores de Soporte en Trading Aprendizaje Automático: Cómo usar las Máquinas de Vectores de Soporte en Trading
Las máquinas de vectores de soporte se usan desde hace mucho tiempo en campos como la bioinformática y matemáticas aplicadas para estudiar conjuntos de datos complejos y extraer patrones que se pueden usar para clasificar datos. Este artículo examina qué es una máquina de vectores de soporte, cómo funciona y por qué puede resultar muy útil a la hora de extraer patrones complejos. Después investigaremos cómo se puede aplicar al mercado y usar potencialmente para tomar decisiones de trading. Usando la Herramienta de Aprendizaje de Máquina de Vectores de Soporte, el artículo facilitará ejemplos listos que permitirán a los lectores experimentar con sus propias operaciones de trading.
Señales de Trading en MetaTrader 5: ¡Una Alternativa Mejor a las Cuentas PAMM! Señales de Trading en MetaTrader 5: ¡Una Alternativa Mejor a las Cuentas PAMM!
Nos complace anunciar que MetaTrader 5 ahora cuenta con Trading Signals (Señales de Trading), una poderosa herramienta para inversores y gestores. Mientras sigue las operaciones de un trader con éxito, ¡el terminal las reproducirá automáticamente en su cuenta!
Cómo Poner a Prueba un Robot de Trading antes de Comprarlo Cómo Poner a Prueba un Robot de Trading antes de Comprarlo
Comprar un robot de trading en el Mercado de MQL5 (Market) tiene un beneficio distintivo sobre todas las demás opciones similares: un sistema automatizado que se puede poner a prueba en profundidad en el terminal de MetaTrader 5. Antes de comprar un Asesor Experto (EA, por sus siglas en inglés) debería simularlo en todos sus modos poco favorables en el Probador de Estrategias incorporado para obtener un control absoluto del sistema.
Simulación Rápida de Ideas de Trading en el Gráfico Simulación Rápida de Ideas de Trading en el Gráfico
Este artículo describe el método de simulaciones rápidas virtuales de ideas de trading. El método se basa en la combinación de un gráfico de precio, un indicador de señal y un indicador de cálculo de saldo. Me gustaría compartir mi método de búsqueda de ideas de trading, así como el método que uso para la simulación rápida de estas ideas.