Libro de Recetas MQL5: Usar Diferentes Modos de Impresión

Anatoli Kazharski | 28 mayo, 2014


Introducción

Este es el primer artículo de la serie de Libros de Recetas MQL5. Comenzaré con ejemplos sencillos para permitir a aquellos que están dando sus primeros pasos en programación que se familiaricen poco a poco con el nuevo lenguaje. Recuerdo mis primeros esfuerzos para diseñar y programar sistemas de trading. Debo decir que fue bastante complicado, teniendo en cuenta el hecho de que fue el primer lenguaje de programación en mi vida. Hasta ese momento, solía pensar que yo no estaba hecho para esto, y que nunca sería capaz de entenderlo.

No obstante, resultó ser más fácil de lo que pensaba, y solo me costó unos pocos meses desarrollar un programa con una cierta complejidad. Puede leer más sobre el tema en el artículo titulado "Limitless Opportunities with MetaTrader 5 and MQL5" ("Oportunidades Ilimitadas con MetaTrader 5 y MQL5").

Aquí trataré de guiar a los creadores principiantes de Asesores Expertos a través del proceso de programación, avanzando de procesos más simples a más complicados. No voy a copiar aquí ninguna información que ya esté disponible en el material de Ayuda (Help) del menú de MetaEditor 5, de modo que prepárese para presionar la tecla F1 a menudo. Al mismo tiempo, esta serie de artículos le facilitará un buen número de ejemplos, funciones ya preparadas y esquemas que podrá usar en sus creaciones, tanto en formato original como de forma personalizada.

De modo que comencemos. En este artículo crearemos un script simple que imprimirá algunas de las propiedades de símbolo en varios modos. Al desarrollar un programa, especialmente en fases tempranas del proceso de aprendizaje, a menudo se darán situaciones en las que el programa no responde como esperamos. Si esto sucede, deberá comprobar los valores de ciertas variables involucradas en los cálculos. En nuestro caso, echaremos un vistazo más en detalle a tres métodos en los que usaremos las funciones Print(), Comment() y Alert(). Después, usted mismo podrá decidir por qué método le resulta más conveniente.


MQL5 Wizard

Mi estudio de MQL5 comenzó con scripts. Es bastante fácil y rápido. Cuando se carga el script, ejecuta la función que creó, y después se elimina del gráfico. Esto le permite experimentar sobre la marcha y ver en qué dirección debe seguir.

Si no se ha instalado todavía el terminal de trading MetaTrader 5, puede hacerlo ahora mismo. Tras la instalación, abra el terminal y MetaEditor 5 pulsando la tecla F4. Este botón se puede usar para cambiar de forma rápida entre el terminal de trading MetaTrader 5 y MetaEditor 5. También puede abrir MetaEditor 5 haciendo click en el botón correspondiente en la barra de herramientas del terminal. Asegúrese de estudiar la interfaz del programa muy bien usando la Ayuda (F1) en el terminal de trading y en MetaEditor 5, puesto que en algunos temas no iremos muy a fondo, si es que los tocamos.

Inicie MetaEditor 5 y pulse Ctrl+N o el botón New (Nuevo) debajo del menú principal en el panel de MetaEditor. Se abrirá una ventana de MQL5 Wizard donde podrá seleccionar el tipo de programa que desea crear. En nuestro caso, seleccionaremos Script y presionaremos Next (Siguiente):

Fig. 1. MQL5 Wizard - Script

Fig. 1. MQL5 Wizard - Script

A continuación deberá introducir el nombre de script (nombre de archivo). Por defecto, los scripts se crean en Metatrader 5\MQL5\Scripts\file_name.mq5. En este directorio puede crear otras carpetas para agrupar sus archivos por propósito.

Fig. 2. MQL5 Wizard - Nombre de archivo

Fig. 2. MQL5 Wizard - Nombre de archivo

Ahora puede añadir también parámetros de entrada si es necesario. Cuando todo esté listo, haga click en Finish (Finalizar). Se creará un nuevo documento usando la plantilla, y usted podrá proceder con el script:

//+------------------------------------------------------------------+
//|                                                   PrintModes.mq5 |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
    
  }
//+------------------------------------------------------------------+


Escribir un código

Todo lo que sigue a una barra doble es un comentario, y no afecta a la ejecución del programa. Siempre es recomendable facilitar comentarios detallados a sus códigos, puesto que hace considerablemente más fácil de entender la lógica del programa, especialmente tras una larga pausa.

Todo lo que va después de #property en las primeras tres líneas de código por encima tiene que ver con propiedades de programa. Puede encontrar más información sobre cada función y propiedad en el material de referencia de MQL. Para ver rápidamente la descripción de cualquier función concreta solo debe hacer doble click en la función para seleccionarla y pulsar la tecla F1. La ventana de Ayuda se abrirá con una descripción de la función seleccionada.

Le sigue la principal función del script, OnStart(), que es la que contiene todas las demás funciones y cálculos.

Debemos permitir la posibilidad de seleccionar un método para imprimir la información requerida antes de la ejecución del programa. Esto significa que debemos tener un parámetro externo que nos permita seleccionar el modo necesario de la lista desplegable. Además, debemos especificar otra propiedad (#property) que sea responsable de abrir una ventana con parámetros externos del script antes de la ejecución del programa. Esta propiedad es script_show_inputs. La añadiremos debajo de todas las demás propiedades que ya tenemos en nuestro código:

#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property script_show_inputs
//---

Para tener la lista desplegable en los parámetros externos, debemos crear la enumeración de todos los modos. Insertemos este código tras las propiedades de programa:

// ENUMERATION
enum ENUM_PRINT_MODE
  {
   PRINT   = 0,
   COMMENT = 1,
   ALERT   = 2
  };
//---

A esto le sigue el único parámetro externo en este script, PrintMode:

// INPUT PARAMETERS
input ENUM_PRINT_MODE printMode=PRINT; // Print mode

Los parámetros de entrada suelen encontrarse al principio del programa, con el modificador input que define el parámetro externo colocado antes del tipo de variable. Si ejecutamos el script ahora, se abrirá una ventana de programa y podremos seleccionar un modo de impresión de la lista desplegable del parámetro Print Mode:

Fig. 3. Ventana de los parámetros de script

Fig. 3. Ventana de los parámetros de script

Después crearemos variables y les asignaremos algunos valores (en nuestro caso, imprimiremos algunos datos de símbolo) para seguir imprimiéndolos usando el modo especificado por el usuario en el parámetro externo. Para ello deberemos preparar una función de usuario separada, PrintSymbolProperties(), que se llamará en la primera función OnStart().

Para crear la función, simplemente deberemos insertar el código tal y como se muestra abajo:

//+------------------------------------------------------------------+
//| PRINTING SYMBOL PROPERTIES                                       |
//+------------------------------------------------------------------+
void PrintSymbolProperties()
  {
    
  }

El tipo de valor que se devolverá se debería especificar antes del nombre de la función. Alternativamente, si la función no devuelve nada como en este caso, deberíamos poner void. Además, debemos escribir el resto del código en el cuerpo de la función PrintSymbolProperties(), entre los paréntesis. Creemos primero las variables:

string symb_symbol    = "";  // Symbol
int    symb_digits    = 0;   // Number of decimal places

int    symb_spread    = 0;   // Difference between the ask price and bid price (spread)
int    symb_stoplevel = 0;   // Stop levels
double symb_ask       = 0.0; // Ask price
double symb_bid       = 0.0; // Bid price

El tipo de variable dependerá del tipo de dato que se le asigne. Ahora asignemos valores a estas variables. Para obtener propiedades de símbolo, MQL5 facilita funciones especiales para cada tipo de dato.

symb_symbol    =Symbol();
symb_digits    =(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);
symb_spread    =(int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD);
symb_stoplevel =(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
symb_ask       =SymbolInfoDouble(_Symbol,SYMBOL_ASK);
symb_bid       =SymbolInfoDouble(_Symbol,SYMBOL_BID);
//---

Para asegurarse un buen aprendizaje, use el material de referencia de MQL para estudiar cada función y parámetros que se introduzcan. Todas las propiedades de símbolo se muestran en una tabla a la que tendrá que referirse a menudo.

Ahora que todas las variables ya tienen valores asignados, solo debemos escribir un código apropiado para cada modo de impresión. Este es su aspecto:

//---
// If it says to print to the journal
   if(printMode==PRINT)
     {
      Print("Symbol: ",symb_symbol,"\n",
            "Digits: ",symb_digits,"\n",
            "Spread: ",symb_spread,"\n",
            "Stops Level: ",symb_stoplevel,"\n",
            "Ask: ",symb_ask,"\n",
            "Bid: ",symb_bid
            );
     }
//---
// If it says to print to the chart
   if(printMode==COMMENT)
     {
      int mb_res=-1; // Variable with the option selected in the dialog box
      //---
      Comment("Symbol: ",symb_symbol,"\n",
              "Digits: ",symb_digits,"\n",
              "Spread: ",symb_spread,"\n",
              "Stops Level: ",symb_stoplevel,"\n",
              "Ask: ",symb_ask,"\n",
              "Bid: ",symb_bid
              );
      //---
      // Open a dialog box
      mb_res=MessageBox("Do you want to delete comments from the chart?",NULL,MB_YESNO|MB_ICONQUESTION);
      //---
      // If "Yes" is clicked, remove the comments from the chart 
      if(mb_res==IDYES) { Comment(""); }
      //---
      return;
     }
//---
// If it says to print to the alert window
   if(printMode==ALERT)
     {
      Alert("Symbol: "+symb_symbol+"\n",
            "Digits: "+IntegerToString(symb_digits)+"\n",
            "Spread: "+IntegerToString(symb_spread)+"\n",
            "Stops Level: "+IntegerToString(symb_stoplevel)+"\n",
            "Ask: "+DoubleToString(symb_ask,_Digits)+"\n",
            "Bid: "+DoubleToString(symb_bid,_Digits)
            );
     }
//---

Si selecciona PRINT para el parámetro externo del Asesor Experto, la información se imprimirá en el diario de Asesores Expertos (pestaña Toolbox (Caja de herramientas) - Experts):

Fig. 4. Pestaña Toolbox - Experts

Fig. 4. Pestaña Toolbox - Experts

Si selecciona COMMENT, la información se mostrará en la esquina superior izquierda del gráfico. Después de que la información aparezca en el gráfico, la función MessageBox() abrirá un cuadro de diálogo que le preguntará si desea eliminar comentarios del gráfico:

Fig. 5. Comentarios en la esquina superior izquierda del gráfico

Fig. 5. Comentarios en la esquina superior izquierda del gráfico

Si elige ALERT, tras ejecutarse el script aparecerá una ventana de alerta con información requerida, o un mensaje de usuario simple. En este caso, al igual que con la opción PRINT, la información también se imprimirá en el diario, pero se acompañará con una notificación sonora.

Fig. 6. Ventana de alerta

Fig. 6. Ventana de alerta

A continuación tiene el código de script completo:

//+------------------------------------------------------------------+
//|                                                   PrintModes.mq5 |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "Copyright 2012, MetaQuotes Software Corp."
#property link        "http://tol64.blogspot.com"
#property description "email: hello.tol64@gmail.com"
#property version     "1.00"
#property script_show_inputs
//---
//--- ENUMERATION
enum ENUM_PRINT_MODE
  {
   PRINT   = 0,
   COMMENT = 1,
   ALERT   = 2
  };
//---
// INPUT PARAMETERS
input ENUM_PRINT_MODE printMode=PRINT; // Print mode
//---
//+------------------------------------------------------------------+
//| MAIN FUNCTION                                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   PrintSymbolProperties();
  }
//+------------------------------------------------------------------+
//| PRINTING SYMBOL PROPERTIES                                       |
//+------------------------------------------------------------------+
void PrintSymbolProperties()
  {
   string symb_symbol    = "";  // Symbol
   int    symb_digits    = 0;   // Number of decimal places
   int    symb_spread    = 0;   // Difference between the ask price and bid price (spread)
   int    symb_stoplevel = 0;   // Stop levels
   double symb_ask       = 0.0; // Ask price
   double symb_bid       = 0.0; // Bid price
//---
   symb_symbol    =Symbol();
   symb_digits    =(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);
   symb_spread    =(int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD);
   symb_stoplevel =(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
   symb_ask       =SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   symb_bid       =SymbolInfoDouble(_Symbol,SYMBOL_BID);
//---
// If it says to print to the journal
   if(printMode==PRINT)
     {
      Print("Symbol: ",symb_symbol,"\n",
            "Digits: ",symb_digits,"\n",
            "Spread: ",symb_spread,"\n",
            "Stops Level: ",symb_stoplevel,"\n",
            "Ask: ",symb_ask,"\n",
            "Bid: ",symb_bid
            );
     }
//---
// If it says to print to the chart
   if(printMode==COMMENT)
     {
      int mb_res=-1; // Variable with the option selected in the dialog box
      //---
      Comment("Symbol: ",symb_symbol,"\n",
              "Digits: ",symb_digits,"\n",
              "Spread: ",symb_spread,"\n",
              "Stops Level: ",symb_stoplevel,"\n",
              "Ask: ",symb_ask,"\n",
              "Bid: ",symb_bid
              );
      //---
      // Open a dialog box
      mb_res=MessageBox("Do you want to delete comments from the chart?",NULL,MB_YESNO|MB_ICONQUESTION);
      //---
      // If "Yes" is clicked, remove the comments from the chart  
      if(mb_res==IDYES) { Comment(""); }
      //---
      return;
     }
//---
// If it says to print to the alert window
   if(printMode==ALERT)
     {
      Alert("Symbol: "+symb_symbol+"\n",
            "Digits: "+IntegerToString(symb_digits)+"\n",
            "Spread: "+IntegerToString(symb_spread)+"\n",
            "Stops Level: "+IntegerToString(symb_stoplevel)+"\n",
            "Ask: "+DoubleToString(symb_ask,_Digits)+"\n",
            "Bid: "+DoubleToString(symb_bid,_Digits)
            );
     }
  }

//+------------------------------------------------------------------+


Conclusión

Terminaremos aquí con este artículo. Además de los métodos descritos arriba, puede también escribir datos en un archivo. Puede ser un archivo de texto simple, o incluso un informe HTML con un bonito formato usando CSS. Pero estos métodos son mucho más complicados para principiantes, y los que hemos dado arriba deberían bastar para los primeros pasos.