Uso de los recursos en MQL5

26 diciembre 2013, 08:53
MetaQuotes Software Corp.
0
990


La Importancia de la Interfaz en Programas Modernos

Hace mucho tiempo, el propósito de los programas informáticos era realizar cálculos matemáticos de gran complejidad y procesar grandes cantidades de datos. Pero con el avance en las capacidades de los ordenadores, las prioridades han cambiado. Ahora, entre dos programas con funcionalidad idéntica, un usuario elegirá el que sea más fácil de manejar.

Actualmente, no es suficiente escribir un programa de acuerdo con el algoritmo requerido de cálculo, sino que se debe facilitar también una interfaz gráfica sencilla. Incluso el análisis técnico surgió del deseo de los comerciantes de tener una representación visual del estado actual del mercado: líneas de tendencias, niveles de apoyo y resistencia... Se han desarrollado varios canales e indicadores técnicos para mostrar una imagen objetiva de lo que está ocurriendo.

El nuevo lenguaje MQL5 facilita ahora aún más herramientas para crear aplicaciones completamente funcionales que no requieren nada más que el Terminal de Cliente MetaTrader 5. En este artículo mostraremos cómo usar Recursos para crear un archivo EX5 ejecutable con una interfaz sencilla, y este archivo no requerirá operaciones rutinarias como instalaciones o inicio.


Las Posibilidades de MQL5

Ante todo, por supuesto, la posibilidad de trabajar con gráficos es muy importante. En estos artículo se pueden encontrar varios ejemplos; aquí tiene varios de ellos:

El uso de elementos gráficos es lo que hace un programa más interesante y fácil de controlar desde la perspectiva del usuario. Además de las herramientas clásicas para el Análisis Técnico, el terminal de MetaTrader 5 facilita un amplio espectro de objetos gráficos que se pueden usar como piezas para construir su propia interfaz gráfica.


Uso de Archivos de Imagen para Crear la Interfaz

Para crear una interfaz especial, se usa la mayoría de las imágenes de archivos gráficos. Esto permite conseguir un diseño único reconocible de varios elementos de control. El lenguaje MQL5 ofrece dos objetos gráficos que usan gráficos:

  • OBJ_BITMAP - el objeto Bitmappermite bajar una imagen de un archivo BMPe y mostrarlo en un gráfico;
  • OBJ_BITMAP_LABEL - la Etiqueta Gráfica es en realidad un botón cuya imagen depende de su estado (pulsado/no pulsado).

Estos dos objetos le permitirán crear una gran variedad de controles y compararlos al "click de ratón" de los controladores de Eventos (CHARTEVENT_OBJECT_CLICK). Para configurar la imagen deseada para OBJ_BITMAP or OBJ_BITMAP_LABEL,, especifique el archivo BMP deseado en la propiedad OBJPROP_BMPFILE. Esto se puede hacer manualmente en la pestaña "Parámetros" del objeto gráfico.


La segunda y principal forma en la que un programador de MQL5 puede especificar un nombre para la propiedad OBJPROP_BMPFILE es usando la función ObjectSetString(). Por ejemplo:

   //--- Load an image for the "Pressed" button state
   bool set=ObjectSetString(0,object_name,OBJPROP_BMPFILE,0,bmp_file_name);

Un algoritmo estándar del uso de OBJ_BITMAP or OBJ_BITMAP_LABEL:

  1. Crear un objeto usando la función ObjectCreate().
  2. Usando la función ObjectSetInteger(), ancle el objeto en la esquina del gráfico deseado, si es necesario. Las coordenadas X e Y del punto de ancla en píxeles se configurarán en relación a esta esquina.
  3. En ObjectSetInteger(), configure los valores de las coordenadas X e Y (OBJPROP_XDISTANCE and OBJPROP_YDISTANCE).
  4. Usando la función ObjectSetString(), estableza el valor de la propiedad OBJPROP_BMPFILE al objeto gráfico (uno para BITMAP o dos para OBJ_BITMAP_LABEL).
  5. Para el objeto OBJ_BITMAP_LABEL, usando ObjectSetInteger() puede configurar el estado inicial del botón, pulsado o no pulsado (OBJPROP_STATE es "true" o "false").

Tras crear y configurar el objeto, durante la ejecución del programa MQL5 puede cambiar dinámicamente no solo la posición y condición del objeto gráfico, sino también el valor de la propiedad OBJ_BITMAP_LABEL para que muestre imágenes. Así, la interfaz puede ser muy flexible y reconfigurable.


Reproducir Sonidos

Un elemento adicional muy demandado en programas es la capacidad de preguntar a un usuario sobre una acción en el evento de determinadas situaciones. Para implementar esta interacción invertida, a menudo se reproducen diferentes sonidos, dependiendo del evento. Esto evitará que el comerciante tenga que realizar una observación continua de los gráficos, llamando su atención solo en casos de necesidad. Para reproducir archivos de audio, se usa la función PlaySound() en MQL5.

PlaySound() es muy fácil de usar, y requiere solo la especificación de la ruta al archivo de sonido.

//--- The path to a sound file  
string wav_file_name="Ok.wav";
...
//--- Play a sound from the file terminal_directory\Sounds\Ok.wav
bool played=PlaySound(wav_file_name);
if(!played)
  //--- Failed to play the sound, notify of this
  {
   PrintFormat("Failed to play file %s. Error code=%d", wav_file_name, GetLastError());
  }


Dónde Localizar los Archivos de Sonido e Imagen

Las funciones ObjectSetString() y PlaySound() requieren la especificación de una ruta a un archivo. Por motivos de seguridad, todos los archivos que se usan en programas MQL5 están localizados en la "sandbox". Esto significa que los archivos solo se pueden almacenar en ciertos directorios, no se puede trabajar con archivos de otros directorios. En primer lugar, debe aprender qué directorios están disponibles para operaciones de archivo y funciones, y cómo se llaman.

Hay tres directorios diferentes:

  • Directorio de Terminal - el directorio de instalación del terminal de cliente. MetaTrader 5 se inicia desde este directorio. Para ver la carpeta, seleccione "Archivo"-"Abrir datos de terminal" en el menú del terminal.
  • Directorio de Datos del Terminal - la carpeta que almacena los datos de un usuario de Windows determinado. Los mecanismos protectores incluidos en el sistema operativo distinguen el acceso del usuario, para que los datos de cada usuario se almacenen aparte de los datos de los demás. De modo que, en este directorio, en la subcarpeta MQL5, están almacenados todos los indicadores, Asesores Expertos y scripts mostrados en la ventana Navegador.
  • La carpeta compartida de todos los terminales (todos los Terminales de Cliente de MetaTrader 5 instalados en el ordenador) - una carpeta para ejecutar operaciones de archivo usando la flag FILE_COMMON.

Para determinar la localización de estos directorios, puede usar el script WhereMyFolders.mq5:

//+------------------------------------------------------------------+
//|                                               WhereMyFolders.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- The folder from which the terminal is started - terminal_directory
   string terminal_path=TerminalInfoString(TERMINAL_PATH);
//--- The folder that stores the terminal data - terminal_data_directory
   string terminal_data_path=TerminalInfoString(TERMINAL_DATA_PATH);
//--- The shared folder of all client terminals - common_terminal_folder
   string common_data_path=TerminalInfoString(TERMINAL_COMMONDATA_PATH);   
   //--- Show all the paths 
   Print("TERMINAL_PATH(terminal_directory) = ",TerminalInfoString(TERMINAL_PATH));
   Print("TERMINAL_DATA_PATH(terminal_data_directory) = ",TerminalInfoString(TERMINAL_DATA_PATH));
   Print("TERMINAL_COMMONDATA_PATH(comon_terminal_folder) = ",TerminalInfoString(TERMINAL_COMMONDATA_PATH));   
  }

Importante: En algunos casos, las localizaciones de terminal_directory y terminal_data_directory pueden coincidir, pero es mejor no depender nunca de ello y, por tanto, no confundir estos conceptos.

Los archivos de imagen y sonido se buscan por el sistema de ejecución del terminal en la siguiente orden:

  • si el separador de barra inversa "\" (escrito "\\") se coloca al principio de la ruta, busca el recurso en relación al directorio terminal_data_directory\MQL5\;
  • si no hay barra invertida al principio de la ruta, el archivo se busca en relacion a la localización del archivo EX5, de donde se llama a la función ObjectSetString(... , OBJPROP_BMPFILE, ...) o PlaySound();
En el caso de la función PlaySound(), si el archivo no se ha encontrado usando los dos métodos anteriores, este archivo de sonido se busca en relación con terminal_directory\Sounds\.


Ejemplos de archivos de sonido:

  • El archivo one.wav se buscará en terminal_data_directory\MQL5\
    PlaySound("\\one.wav");
  • El archivo.wav se buscará en terminal_data_directory\MQL5\Files\
    PlaySound("\\Files\\two.wav");
  • El archivo three.wav se buscará en terminal_data_directory\MQL5\MySounds\
    PlaySound("\\MySounds\\three.wav");
  • El archivo four.wav se buscará en la carpeta de donde se ejecuta el EX5. Si el archivo no se encuentra en esta carpeta, entonces se intentará encontrar en la carpeta terminal_directory\Sounds\.
    PlaySound("four.wav");


Ejemplos de archivos de imagen:

  • El archivo bird.bmp se buscará en terminal_data_directory\MQL5\
    //--- Setting an image for the OBJ_BITMAP_LABEL object
    bool res=ObjectSetString(0,object_name,OBJPROP_BMPFILE,0,"bird.bmp");// Modifier 0 is specified
  • swan.bmp se buscará en terminal_data_directory\MQL5\Files\
    //--- Setting an image for the OBJ_BITMAP object
    bool set=ObjectSetString(0,object_name,OBJPROP_BMPFILE,"\\Files\\swan.bmp");// No modifier
  • dog.bmp se buscará en terminal_data_directory\MQL5\MyPictures\
    //--- Setting an image for OBJ_BITMAP
    bool done=ObjectSetString(0,object_name,OBJPROP_BMPFILE,"\\MyPictures\\dog.bmp");// No modifier
  • cat.bmp se buscará en la carpeta de donde se ejecuta el EX5.
    //--- Setting an image for OBJ_BITMAP
    bool result=ObjectSetString(0,object_name,OBJPROP_BMPFILE,"cat.bmp");// No modifier

Note que la doble barra inversa "\\" se usa como separador al escribir la ruta.

Importante: Al especificar una ruta, utilice siempre una doble barra inversa como separador, porque una barra inversa individual es un carácter de control para el compilador al analizar las filas constantes y constantes de caracteres en el código fuente de un programa.


Nuevas Posibilidades - Recursos

Para usar imágenes y sonidos en su programa MQL5, asegúrese de que todos los archivos que usa se encuentran en las carpetas correspondientes. Esto supone una desventaja a la hora de transferir un archivo compilado EX5 de un terminal a otro. Pero es posible solucionar este problema durante la fase de escritura del código. En tales casos, utilice recursos.

Para usar un recurso en un programa, debería declararse usando la directiva de compilación #resource.

 #resource path_to_resource_file

Ahora, este recurso se puede usar en lugar de una ruta de archivo. El comando #resource le dice al compilador que el recurso en la ruta path_to_resource_file especificada debería estar incluida en el archivo EX5 ejecutable. Por tanto, todas las imágenes y sonidos necesarios pueden localizarse directamente en el archivo EX5. Ahora, al iniciar un programa MQL5 en otro terminal, no necesitará transmitir todos los archivos usados en él.

Cualquier archivo EX5 puede contener recursos, y cualquier programa EX5 puede usar recursos de cualquier programa EX5. En otras palabras, un Asesor Experto puede usar los recursos que están localizados en un indicador o biblioteca EX5. Este es otro elemento conveniente del uso de recursos.

El uso de los recursos le permite obtener todo en uno: el archivo ejecutable mismo y todos los recursos que usa se empaquetan en un archivo EX5 durante la compilación de un código fuente.


Búsqueda de Recursos por un Compilador

Un recurso se especifica usando la directiva #resource "<ruta al archivo de recurso>"

 #resource "<path_to_resource_file>"
La longitud de la cadena de caracteres constante ><path_to_resource_file> no debe superar los 63 caracteres. El compilador busca un recurso en la ruta especificada en la siguiente secuencia:1
  • Si la barra invertida "\" se encuentra al principio de la ruta, el recurso se busca en relación a la carpeta terminal_data_directory\MQL5\,
  • Si no hay barra invertida, el recurso se busca en relación a la posición del archivo fuente , en el que se escribe este recurso.

Importante: En la ruta de recurso, no se acepta el uso de subcadenas de caracteres "..\\" y ":\\".

Ejemplos de recursos incluyendo los que hay en el tema de Ayuda Recursos:

//--- Correct specification of a resource
#resource "\\Images\\euro.bmp" // euro.bmp is located in terminal_data_directory\MQL5\Images\
#resource "picture.bmp"        // picture.bmp is locate in the same directory with the source file
#resource "Resource\\map.bmp"  // The resource is located in the folder source_file_directory\Resource\map.bmp
 
//--- incorrect specification of resources
#resource ":picture_2.bmp"     // Use of ":" is not allowed
#resource "..\\picture_3.bmp"  // Use of ".." is not allowed
#resource "\\Files\\Images\\Folder_First\\My_panel\\Labels\\too_long_path.bmp" //More than 63 characters


Nombres de Recursos

Tras la declaración de un recurso usando la directiva #resource, se puede usar en cualquier parte de un programa. Para el nombre del recurso, es su ruta sin barra invertida al principio de la cadena de caracteres que define la ruta para el recurso que se usará.

Ejemplos:

//---Examples of specifying resources and their names in the comments
#resource "\\Images\\cat.bmp"           // Resource name - Images\cat.bmp
#resource "dog.bmp"                     // Resource name - dog.bmp
#resource "Resource\\map.bmp"           // Resource name - Resource\map.bmp
#resource "\\Files\\Pictures\\bird.bmp" // Resource name - Files\Pictures\bird.bmp
#resource "\\Files\\good.wav"           // Resource name - Files\good.wav" 

Los nombres de los recursos no distinguen mayúsculas y minúsculas: para el compilador, los nombres dog.bmp y DOG.bmp significarán lo mismo.


Uso de Recursos Propios y de Terceros

Para usar un recurso, debe especificar su nombre. El nombre del recurso es su ruta sin la barra invertida al principio de la línea. Cuando usa su propio recurso, se debe añadir el atributo especial "::" antes del nombre del recurso.

//--- Use of resources
ObjectSetString(0,bitmap_name,OBJPROP_BMPFILE,0,"::Images\\cat.bmp");
...
ObjectSetString(0,my_bitmap,OBJPROP_BMPFILE,0,"::dog.bmp");
...
set=ObjectSetString(0,bitmap_label,OBJPROP_BMPFILE,1,"::Files\\Pictures\\bird.bmp");
...
PlaySound("::Files\\good.wav");
...
PlaySound("::Sounds\\thrill.wav");

Puede usar no solo sus propios recursos (de su archivo EX5), sino también los de cualquier biblioteca y módulo EX5. Por tanto, puede crear un repositorio de recursos y usarlos en muchos otros programas mql5.

Para usar recursos de otro archivo EX5, debe especificar el nombre del recurso en la forma <EX5_file_name_path>::<resource_name>. Imagine que el script Draw_Triangles_Script.mq5 contiene un recurso de imagen en el archivo triangle.bmp:

 #resource "\\Files\\triangle.bmp"

En ese caso, su nombre para su uso en el script mismo será "Files\triangle.bmp", y para usarlo, deberá añadir "::" al nombre del recurso - "::Files\triangle.bmp". Para usar el mismo recurso de otro programa, por ejemplo de un Asesor Experto, debemos añadir al nombre del recurso la ruta al archivo EX5 en relación a terminal_data_directory\MQL5\ y el nombre del archivo EX5 del script - Draw_Triangles_Script.ex5. Imagine que el script está localizado en la carpeta estándar terminal_data_directory\MQL5\Scripts\. La llamada, en este caso, se escribiría así:

//--- Use of a script resource in an Expert Advisor
ObjectSetString(0,my_bitmap_name,OBJPROP_BMPFILE,0,"\\Scripts\\Draw_Triangles_Script.ex5::Files\\triangle_1.bmp");

Si la ruta al archivo ejecutable no se especifica al llamar al recurso de otro EX5, el archivo ejecutable se buscará en la misma carpeta que contiene el programa que llama al recurso. Esto significa lo siguiente: Si un Asesor Experto está localizado en terminal_data_directory\MQL5\Experts\ y un recurso del archivo Draw_Triangles_Script.ex5 se solicita sin especificar una ruta, entonces el archivo se buscará en terminal_data_directory\MQL5\Experts\.

//--- Request for a resource from a script in an Expert Advisor without path specification
ObjectSetString(0,my_bitmap_name,OBJPROP_BMPFILE,0,"Draw_Triangles_Script.ex5::Files\\triangle_1.bmp");


Compresión de Recursos en Archivos EX5: ¿Cómo funciona?

Archivos BMP y WAV se comprimen automáticamente antes de ser incluidos en un archivo EX5 ejecutable. Esto significa que el uso de recursos no solo le permite crear programas MQL5 completos, sino que también reduce el tamaño de los archivos requeridos por el terminal al usar imágenes y sonidos, en comparación con la forma convencional de escribir programas MQL5.

El tamaño del archivo de recurso no puede sobrepasar los 16 Mb.

Importante: Una ventaja adicional de usar recursos es la compresión automática de archivos WAV y BMP al empaquetarlos en un archivo EX5 ejecutable. Esto reduce no solo la cantidad, sino también el tamaño de archivos usados por el programa.

Por ejemplo, veamos el pequeño programa Animals_EA.mq5. Abajo se muestra un pequeño bloque de código para el uso de recursos:

//+------------------------------------------------------------------+
//|                                                   Animals_EA.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//--- Declare image resources
#resource "\\Images\\cat.bmp"
#resource "\\Images\\dog.bmp"
#resource "\\Images\\cow.bmp"
#resource "\\Images\\bird.bmp"
//--- Declare sound resources
#resource "\\Files\\MySounds\\cat.wav"
#resource "\\Files\\MySounds\\dog.wav"
#resource "\\Files\\MySounds\\cow.wav"
#resource "\\Files\\MySounds\\bird.wav"
//--- Object names
string cat_dog="cat_dog";
string cow_bird="cow_bird";
string canvas="canvas";
string text="text";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Create a substrate
   CreateCanvas(canvas,50,50,500,500);
//--- Create buttons
   CreateObjectBITMAP_LABEL(cat_dog,110,120,"::Images\\cat.bmp","::Images\\dog.bmp");
   CreateObjectBITMAP_LABEL(cow_bird,110,330,"::Images\\cow.bmp","::Images\\bird.bmp");
   CreateText(text,"Click on any graphical object",200,90,clrTan);
//--- Give a command for an immediate refresh to see the object
   ChartRedraw();
//---
   return(0);
  }
//+------------------------------------------------------------------+
//|  Creating OBJ_BITMAP_LABEL with the specified images          |
//+------------------------------------------------------------------+
bool CreateObjectBITMAP_LABEL(string obj_name,int X,int Y,string res_name1,string res_name2)
  {
//--- If there is no such an object on the chart
   if(ObjectFind(0,obj_name)==-1)
     {
      //--- Create it
      bool res=ObjectCreate(0,obj_name,OBJ_BITMAP_LABEL,0,0,0);
      //--- Check the result
      if(!res)
        {
         PrintFormat("%s: Failed to create OBJ_BITMAP_LABEL with the name %s. Error code=%d",
                     __FUNCTION__,
                     GetLastError());
         return false;
        }
     }

//--- Set the coordinates
   ObjectSetInteger(0,obj_name,OBJPROP_XDISTANCE,X);
   ObjectSetInteger(0,obj_name,OBJPROP_YDISTANCE,Y);
//--- Disable display on the background
   ObjectSetInteger(0,obj_name,OBJPROP_BACK,false);
//--- Reset the error code
   ResetLastError();
//--- Set an image for the pressed condition
   bool res=ObjectSetString(0,obj_name,OBJPROP_BMPFILE,0,res_name1);
//--- Check the operation result
   if(!res)
     {
      PrintFormat("%s: Failed to upload an image from the resource %s. Error code=%d",
                  __FUNCTION__,
                  res_name1,
                  GetLastError());
      return false;
     }
//--- Set an image for the depressed state
   res=ObjectSetString(0,obj_name,OBJPROP_BMPFILE,1,res_name2);
//--- Check the operation result
   if(!res)
     {
      PrintFormat("%s: Failed to upload an image from the resource %s. Error code=%d",
                  __FUNCTION__,
                  res_name2,
                  GetLastError());
      return false;
     }
//--- Set the button pressed
   ObjectSetInteger(0,obj_name,OBJPROP_STATE,true);
   return true;
  }
//+------------------------------------------------------------------+

La tarea del programa es dibujar en un fondo azul (sustrato) dos gráficos de botón que cambian su apariencia con un click de ratón. Al hacer click en el sustrato, cambia su color de azul a beige, y viceversa. En cada cambio, suena un sonido. El evento del click de ratón se controla con la función OnChartEvent(). En la figura se muestra un gráfico inmediatamente después del inicio del Asesor Animals_EA.mq5.



Fíjese en las propiedades del objeto OBJ_BITMAP_LABEL; por ejemplo, cat_dog. Cambiar las propiedades de Bitmap File (On) y Bitmap File (Off) ahora es imposible a través de un cuadro de diálogo: estos campos están inaccesibles, y se muestran, por tanto, en colores atenuados.


Importante: En objetos gráficos, las imágenes cargadas de recursos se pueden cambiar solo programáticamente. El cambio manual de estas propiedades a través de la ventana de Propiedades del objeto pasa a ser inaccesible.

El volumen total de imágenes usado por el Asesor Experto Animals_EA.mq5 es de 430 kb.


Pero el tamaño del archivo ejecutable Animals_EA.ex5 resultante, que contiene todas estas imágenes, es de 339 kb. Por tanto, en lugar de 9 archivos (un archivo MQ5, cuatro archivos BMP y cuatro archivos WAV), ahora tenemos un archivo EX5 con todos los recursos necesarios para el programa.

Solo se pueden usar como recursos imágenes BMP de 24 o 32 bits. Un BMP de 32 bits puede contener composición alfa - en este caso, se aplicará a un gráfico con transparencia.

El archivo del Asesor Experto Animals_EA.mq5, las imágenes y sonidos se encuentran adjuntos a este artículo:

  • Las imágenes se deben descomprimir del archivo images.zip a terminal_data_directory\MQL5\Images\
  • Los sonidos deben descomprimirse de MySounds.zip a terminal_data_directory\MQL5\Files\MySounds\

Si desea probar este programa en su terminal, simplemente descárguese el Asesor Experto compilado adjunto Animals_EA.ex5, que contiene todos los recursos necesarios. En este caso, no necesita descargar e instalar los archivos de imagen y sonido.


Trabajo con los indicadores personalizados incluidos como recursos

Para el funcionamiento de los programas mql5 puede ser necesario uno o varios indicadores personalizados. Todos ellos pueden incluirse en el código del programa mql5 a ejecutar. La inclusión de los indicadores como recursos permite facilitar la distribución de la aplicación.

A continuación se muestra el ejemplo de inclusión y uso del indicador SampleIndicator.ex5 ubicado en la carpeta: directorio_de_datos_del_terminal\MQL5\Indicators\:

//+------------------------------------------------------------------+
//|                                                     SampleEA.mq5 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#resource "\\Indicators\\SampleIndicator.ex5"
int handle_ind;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   handle_ind=iCustom(_Symbol,_Period,"::Indicators\\SampleIndicator.ex5");
   if(handle_ind==INVALID_HANDLE)
     {
      Print("Expert: iCustom call: Error code=",GetLastError());
      return(INIT_FAILED);
     }
//--- ...
   return(INIT_SUCCEEDED);
  }

El caso cuando un indicador personalizado crea en la función OnInit() una o varias copias de sí mismo requiere un análisis más detenido. Recordemos que para el uso del recurso desde el programa mql5, hay que indicarlo como sigue: <ruta_nombre_del_archivo_EX5>::<nombre_del_recurso>.

Por ejemplo, si el indicador SampleIndicator.ex5 se incluye como recurso en el Asesor Experto SampleEA.ex5, la ruta hacia sí mismo especificada durante la llamada de iCustom() en la función de inicialización del indicador personalizado, tendrá la siguiente apariencia: "\\Experts\\SampleEA.ex5::Indicators\\SampleIndicator.ex5". Si esta ruta se establece de forma explícita, el indicador personalizado SampleIndicator.ex5 será vinculado rígidamente al Asesor Experto SampleEA.ex5 y perderá la capacidad de actuar independientemente.

La ruta hacia sí mismo se puede conseguir a través de la función GetRelativeProgramPath(), su ejemplo se muestra más abajo:

//+------------------------------------------------------------------+
//|                                              SampleIndicator.mq5 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_plots 0
int handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- modo incorrecto de indicar el vinculo hacia sн mismo
//--- string path="\\Experts\\SampleEA.ex5::Indicators\\SampleIndicator.ex5";   
//--- modo correcto de obtener el vinculo hacia sн mismo
  string path=GetRelativeProgramPath();
//--- indicator buffers mapping
   handle=iCustom(_Symbol,_Period,path,0,0);
   if(handle==INVALID_HANDLE)
     {
      Print("Indicator: iCustom call: Error code=",GetLastError());
      return(INIT_FAILED);
     }
   else Print("Indicator handle=",handle);
//---
   return(INIT_SUCCEEDED);
  }
///....
//+------------------------------------------------------------------+
//| GetRelativeProgramPath                                           |
//+------------------------------------------------------------------+
string GetRelativeProgramPath()
  {
   int pos2;
//--- obtenemos la ruta absoluta hacia la aplicaciуn
   string path=MQLInfoString(MQL_PROGRAM_PATH);
//--- buscamos la posiciуn de la subcadena "\MQL5\"
   int    pos =StringFind(path,"\\MQL5\\");
//--- subcadena no encontrada - error
   if(pos<0)
      return(NULL);
//--- saltamos la carpeta "\MQL5"
   pos+=5;
//--- saltamos los sнmbolos '\' que sobran
   while(StringGetCharacter(path,pos+1)=='\\')
      pos++;
//--- si es un recurso, devolvemos la ruta respecto al directorio MQL5
   if(StringFind(path,"::",pos)>=0)
      return(StringSubstr(path,pos));
//--- buscamos el divisor para el primer subdirectorio en MQL5 (por ejemplo, MQL5\Indicators)
//--- si no hay, devolvemos la ruta respecto al directorio MQL5
   if((pos2=StringFind(path,"\\",pos+1))<0)
      return(StringSubstr(path,pos));
//--- devolvemos la ruta respecto al subdirectorio (por ejemplo, MQL5\Indicators)
   return(StringSubstr(path,pos2+1));
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,        
                const double& price[])
  {
//--- return value of prev_calculated for next call
   return(rates_total);
  }


Guardar la Memoria del Terminal

Cada recurso se carga en la memoria del terminal solo una vez. Durante un uso normal, en cambio, cada acceso al archivo causa una carga adicional del archivo a la memoria. Por ejemplo, imagine que tenemos 50 objetos 50 OBJ_BITMAP, y cada uno de ellos contiene la misma imagen con un tamaño de 100 kb. En ese caso, durante un uso normal, estos 50 objetos requerirían la memoria 50*100kb=5Mb.

Si declaramos un recurso para la imagen cargada, entonces esta imagen se cargará en la memoria solo una vez, independientemente del número de objetos en los que se usa.

Importante: Los recursos se cargan en la memoria solo una vez, y pueden ahorrar memoria si se usan varias veces.


Conclusión

El uso de recursos facilita el uso y distribución de programas MQL5. Para crear herramientas modernas y cómodas para trading se requiere el uso de archivos multimedia de imagen y sonido. El concepto de recursos en MQL5 es sencillo y fácil de entender, de modo que anímese y pruébelo.

Las imágenes en el formato 32-bit BMP pueden contener composición alfa - en este caso, se aplicará a un gráfico con transparencia.

Los recursos facilitan las siguientes ventajas:

  • Compacidad - todos los archivos se empaquetan en un solo archivo ejecutable EX5, de modo que el programa es fácil de transmitir y ejecutar;
  • Ahorro de memoria - la memoria del terminal siempre contiene solo una instancia de cada recurso, independientemente de la frecuencia de su uso en un programa;
  • Almacenamiento conveniente - un archivo EX5 con todos los recursos es menor a la suma de los archivos de imagen y sonido originales.

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

Archivos adjuntos |
images.zip (214.29 KB)
mysounds.zip (65.89 KB)
animals_ea.ex5 (394.51 KB)
animals_ea.mq5 (18.92 KB)
wheremyfolders.mq5 (2.96 KB)
Operaciones de trading en MQL5 - Es fácil Operaciones de trading en MQL5 - Es fácil

Casi todos los operadores llegan al mercado para ganar dinero, pero algunos también disfrutan de ello. Sin embargo, no solo la operativa manual puede proporcionarle una experiencia apasionante. El desarrollo de sistemas de trading automatizados también puede ser fascinante. Crear un robot de trading puede ser tan interesante como leer una buena novela de misterio.

Algoritmos que generan ingresos empleando órdenes Trailing Stop Algoritmos que generan ingresos empleando órdenes Trailing Stop

El objetivo de este artículo es estudiar la rentabilidad de los algoritmos con diferentes entradas y salidas en el mercado usando órdenes Trailing Stop. Los tipos de entrada que se usaran son las entradas aleatorias y las entradas inversas. Las órdenes Stop que se usarán son las de tipo Trailing Stop y Trailing Take. El artículo describe los algoritmos generadores de ingresos con una rentabilidad en torno al 30% al año.

MQL5 Wizard: Nueva Versión MQL5 Wizard: Nueva Versión

Este artículo contiene descripciones de los nuevos elementos disponibles en el MQL5 Wizard actualizado. La arquitectura actualizada de señales nos permite crear robots de trading basados en la combinación de varios patrones de mercado. El ejemplo que contiene este artículo explica el procedimiento de creación interactiva de un Asesor Experto.

Cree sus propios paneles gráficos en MQL5 Cree sus propios paneles gráficos en MQL5

La funcionalidad del programa MQL5 viene determinada tanto por sus ricas características como por una interfaz de usuario muy desarrollada. A veces, la percepción visual es más importante que el funcionamiento rápido y estable. Esta es una guía paso a paso para que pueda crear por sí mismo paneles gráficos sobre la base de las clases de la librería estándar.