English Русский 中文 Deutsch 日本語 Português
Cambiar los parámetros externos de los programas de MQL4 sin reiniciar

Cambiar los parámetros externos de los programas de MQL4 sin reiniciar

MetaTrader 4Ejemplos | 20 abril 2016, 13:15
2 157 0
Alexey Koshevoy
Alexey Koshevoy

Introducción


Todo el que haya ejecutado un asesor experto o un indicador se ha enfrentado a la posibilidad de configurar inicialmente los parámetros que a menudo subyacen tras el éxito del programa. Existe la posibilidad de cambiar los parámetros durante el funcionamiento del programa. Pero ¿cómo puede hacerse esto sin un reinicio? En algunos casos, esto puede afectar a la gestión de las órdenes abiertas previamente. En este artículo intentaremos solucionar este problema con la mayor flexibilidad posible.

Planteamiento del problema

Consideraremos este problema para los asesores expertos en lugar de hacerlo para los indicadores. Para estos últimos, este problema no es tan agudo, aunque los métodos son universales y podemos aplicarlos a cualquier programa.

En la escritura clásica de asesores expertos, debe crearse el contexto en cada tick. Puede haber dos tipos de contextos: el contexto del estado y el del trading. El contexto del estado contiene los estados actuales de los indicadores y otros elementos subyacentes a la toma de decisiones sobre la apertura, cierre y modificación de órdenes. El contexto del trading contiene información sobre las órdenes abiertas, sus estados y cantidades. Después de haber iniciado el contexto del trading, los traders toman decisiones sobre qué hacer con sus órdenes. Los contextos se dividen por el tipo de forma condicional. Se introducido esta clasificación por comodidad.

Si puede restaurarse el contexto en cada tick, no surgirá el problema. Podemos cambiar libremente los parámetros externos y nuestro asesor experto seguirá funcionando de acuerdo con su lógica. En primer lugar, tendremos la inicialización, luego el asesor experto calculará los valores de los indicadores, "se ocupará" de las órdenes abiertas y realizará una serie de operaciones de acuerdo con la información recopilada. Todo es sencillo y transparente.

Ahora vamos a considerar la situación en la que es necesaria una tecnología de cambio del parámetro más precisa y que no producirá un reinicio completo del programa.

Ejemplo 1.
Entre nuestras órdenes abiertas, hay algunas procesadas de forma especial. Es decir, necesitamos encontrarlas entre otras órdenes abiertas por nuestro asesor experto. Para este propósito, usaremos algunos parámetros: Ticket, Magic Number (número mágico), Currency (moneda) y Comment (comentario). El número mágico se usa para separar nuestras órdenes para otras abiertas en el sistema por otros asesores expertos de forma manual. 'Currency', además del 'Magic Number', nos permite usar el mismo asesor experto para distintos pares de monedas. Solo quedan dos parámetros que pueden ser únicos para cada orden. 'Comment' es el más adecuado, ya que contiene cualquier información contextual, pero tiene un inconveniente: puede modificarse del lado del servidor, por ejemplo, en el cierre parcial. 'Ticket' es único para cada orden, pero el número del ticket solo no es suficiente para dividir las órdenes por clases, por lo que los tickets de las órdenes deben compararse con algún otro tipo de información. Como podemos ver, en esta situación sería más conveniente usar el parámetro 'Ticket' y guardar los tickets de acuerdo con las clases de la orden. En consecuencia, en el reinicio la matriz que contiene los tickets se perderá, por lo que no podremos restaurar la información sobre las clases virtuales de las órdenes.

Ejemplo 2.
Se desarrolla un mecanismo universal que nos permite analizar los cambios en los estados de las órdenes. Es decir, tenemos dos contextos de los estados de la orden. La primera lista está en el tick actual, mientras que la segunda está en el tick previo. Al analizar la información, podemos sacar conclusiones sobre qué orden ha sido abierta, modificada o cerrada y sobre las razones de dichas operaciones. Este método es muy cómodo para la depuración del asesor experto y el desarrollo de la lógica del trading. No obstante, tiene el inconveniente de que es necesario guardar los estados de la orden en el tick previo. En consecuencia, estos datos se perderán en el reinicio del asesor experto.

Ejemplo 3.
Un asesor experto recibe datos externos. No importa de qué forma o de dónde llegan los datos. Lo importante es que si necesitamos acumular estos datos para el procesamiento y no podemos solicitar su historial, tendremos que crear el contexto durante todo el funcionamiento del asesor experto. Cambiar los parámetros externos dará lugar al reinicio del sistema y tendremos que acumular los datos de una fuente externa de nuevo.

Ejemplo 4.
Un programa MQL4 se distribuye como archivo compilado. De este modo, los usuarios no pueden cambiar su código ni ver sus algoritmos. Es una gran protección de su propiedad intelectual. Sin embargo, el programa puede tener algunas variables externas, y no es muy cómodo cambiarlas cada vez en lugar de hacer de una sola vez y compilarlo con los nuevos valores. Aunque este ejemplo no está relacionado directamente con el problema del almacenamiento del contexto, es muy típico a la luz del problema a resolver aquí.

Cuando se crean asesores expertos, debemos construir nuestra lógica de tal forma que evitemos guardar el contexto durante las operaciones. Dicho desarrollo puede ser mucho más complejo, en este caso, aunque el sistema será tan estable como sea posible. Si, en cambio, no podemos evitar guardar el contexto, el método que estamos considerando nos ayudará a gestionar de forma flexible la configuración del asesor experto sin perder los datos en el cambio de sus parámetros.

Aplicación

Para resolver los problemas de los ejemplos anteriores, vamos a crear un sistema que gestione los parámetros externos de los programas de MQL4. ¿Qué puede hacerse cuando se usa dicho sistema?

Por definición, podemos cambiar todo tipo de parámetros externos:

• Entero
• Booleano
• Doble
• String
• Datetime

No obstante, no debemos estar satisfechos con lo que ya hemos logrado. Para ser conscientes de todo el potencial de este método, debemos tener en cuenta los principios de funcionamiento del sistema en un ejemplo muy sencillo.

El sistema funciona de la forma siguiente. En la fase de inicialización, el programa MQL4 guarda todos los valores que pueden ser cambiados por el usuario en el archivo correspondiente. El programa externo abre este archivo, lee los datos, los visualiza en pantalla y luego el usuario comienza a trabajar. Tan pronto como el usuario cambia uno de los parámetros en el programa externo, se modifica el archivo. Es decir, se escribirá el nuevo valor establecido por el usuario en lugar del antiguo. A continuación, el programa MQL4, en la llamada de la función 'start', comprobará los valores cambiados en el archivo de datos y, si encuentra algún cambio, llamará a las funciones correspondientes. Las funciones que procesan los cambios en los valores externos, ejecutan algunos algoritmos preestablecidos. En la mayoría de casos, será suficiente solo asignar los nuevos valores a la variable. Así es cómo funciona aproximadamente un ciclo del sistema de cambio de los parámetros externos.

A partir del ejemplo anterior podemos ver que la creación de un diálogo estable entre el programa MQL4 y un programa externo es más importante para que el sistema funcione correctamente. Ahora tenemos que elegir los medios y los métodos para organizar el diálogo. No obstante, incluso para el enfoque más simple sin usar DLL, podemos permitirnos algo más que solo cambiar los parámetros externos.

Vamos a considerar algunos ejemplos que revelan características adicionales de este enfoque. Como tenemos un diálogo bilateral, el programa de MQL4 puede responder a la solicitud de un programa externo.

Por ejemplo, el usuario cambia el valor de una variable. El programa externo escribe en un archivo el nuevo valor de la variable y cambia el estado de esta a "esperando una acción del programa MQL4". Cuando se procesa el archivo, el programa MQL4 solo tiene en cuenta las variables que tienen este estado, las demás no han cambiado. En el procesamiento de la variable encontrada, se cambia el estado para los "cambios aceptados". De este modo, en un programa externo podemos ver cuándo ha sido realizado un cambio directamente en el programa MQL4. Es una función útil para la monitorización

Vamos a intentar realizar la función de "acción". Necesitamos que el cambio de una variable en un parámetro externo no provoque el cambio de la variable correspondiente en un programa MQL4, sino la ejecución de una determinada acción una sola vez. Esto puede hacerse de la forma siguiente. Se cambia la variable en un programa externo. La variable puede tomar los valores de 0 y 1. Si el valor es 1, el programa MQL4 ejecuta una determinada acción y asigna el valor 0 a la variable. Ahora, es posible realizar de nuevo esta acción desde un programa externo. Esto es más que cambiar solo variables. Al usar las acciones podemos realizar funciones muy útiles. Las acciones son muy similares a los scripts de MQL4, aunque tienen una diferencia importante. Un script puede ejecutarse en cualquier momento del funcionamiento del terminal de cliente de MetaTrader4, mientras que una acción solo puede realizarse en la llamada de la función 'start', es decir, en el momento del cambio del precio actual.

Al final, podemos considerar un ejemplo de cómo usar el método para transferir los datos desde una fuente externa a un programa MQL4. Supongamos que no necesitamos cambiar ninguna variable externa, sino que un programa MQL4 o un asesor experto debe gestionarse desde una fuente externa. La fuente externa procesa los datos, realiza cálculos y, en base a los resultados obtenidos, toma una decisión sobre la apertura y cierre de órdenes. Para abrir una orden es necesario pasa los parámetros principales y el comando de apertura al programa. Los parámetros de la orden tienen el estado "esperando", ya que su cambio no debe forzar que el programa ejecute las acciones. En este ejemplo, es la acción de la variable la que constituye el evento para la lectura de los parámetros de apertura de la orden.

Hemos considerado tres aspectos del uso del sistema. El primero es pasar los parámetros con los estados en una dirección desde el programa externo a un programa MQL4. En este caso, el diálogo se realiza cambiando el valor del estado. El segundo es la solicitud para realizar ciertas acciones. En el diálogo, se cambia el valor de la variable y el del estado. El tercer aspecto y el más simple, es extraer la información del evento almacenada en el archivo. No se usa ningún diálogo.

Creación del sistema

Para crear el sistema debemos resolver una serie de problemas. En primer lugar, debemos crear la estructura del documento para transferir información entre los programas. Luego tenemos que seleccionar un protocolo para transferir este documento. Por último, debemos escribir bibliotecas para trabajar con el sistema usando MQL4 o cualquier otro lenguaje de programación adecuado para un programa externo concreto.

Creación de la estructura del documento
La creación de la estructura del documento es una de las tareas más importantes en el sistema. El documento debe reflejar todos los aspectos descritos anteriormente.

Para guardar la información el método más universal sería la tecnología XML. No obstante, aquí aparecen una serie de problemas. En primer lugar, MQL4 no tiene ningún recurso propio para trabajar con XML. En segundo lugar, si trabajamos con XML mediante DLL, todo el sistema será varias veces más complejo. Por tanto, vamos a usar un archivo de texto estándar y nuestra propia estructura de representación de los datos.

El objetivo principal del documento es una variable o un valor. El valor tiene una estructura bien definida que está compuesta por los siguientes elementos:

• Title
• Type
• Status
• Value

Vamos a verlos uno a uno:

Title – el nombre de la variable. Lo usan los programas para identificar el objeto.

Type – el tipo de variable. Según el tipo de variable, así será la lógica del procesamiento. Los tipos se especifican por los valores numéricos.

Tipo Descripción Analógico in MQL Valor
0Booleano o lógico
bool0 – false, 1 - true
1StringstringUn conjunto de caracteres
2Carácter enterointLos valores de frontera se corresponden con las reglas de MQL4.
3Carácter realdobleLos valores de frontera se corresponden con las reglas de MQL4. El delimitador es el punto.
4FechadatetimeEl formato de registro se corresponde con las reglas de MQL4.
5Acciónsin equivalente0 – no se necesita una ejecución, 1 - se requiere una ejecución.


Status – una variable de estado. Se indica por un valor numérico. Vamos a considerar una tabla de variaciones posibles:

Valor Descripción
0Esperando. No se necesita procesamiento
1Solicitud de cambio. El programa MQL4 debe responder a este valor de estado.
2No se necesita procesamiento Es un valor de las variables que debe procesarse en un evento distinto al cambio directo de la variable.

Value – el valor de la variable. Las reglas de registro del valor dependen del tipo de variable.
Interacción de los parámetros.

Programa externo. Cambiar el valor.

Si Status=0, entonces para cambiar el valor de 'Value' el valor de Status=1.
Si Status=1, entonces para cambiar el valor de 'Value' el valor de 'Status' no cambia.
Si Status=2, entonces para cambiar el valor de 'Value' el valor de 'Status' no cambia.

Programa externo. Cancelar el cambio del valor.

Hay situaciones en las que se cambia un valor por error o se sustituye por un valor erróneo, o el usuario cambió de opinión y decidió cambiar el valor después de haber confirmado los cambios. Vamos a ver la posibilidad de cancelar este procedimiento. No obstante, debe tenerse en cuenta que si el programa MQL4 ya ha procesado el archivo que contiene los cambios, no puede cancelarse nada

Si Status=1, entonces 'Value' se cambia por el anterior y Status=0.
Si Status=2, entonces 'Value' se cambia por el anterior, pero el valor 'Status' no cambia.

Programa MQL4. Procesamiento de los cambios.

El programa MQL4 considera los cambios solo si la variable 'Status' es igual a 1. Por definición, no importa qué tipo de variable haya cambiado, ya que estamos llamando a la función de procesamiento para cada cambio. La diferencia es solo cuándo tendrá 'Value' un valor, es decir, si el cambio de la variable es un cambio o una solicitud de ejecución de una función. Vamos a considerar esto en detalle.

Si Status=1 y 'Type' varía desde 0 a 4, entonces usamos 'Value' y cambiamos 'Status' por 0.
Si Status=1 y Type=5, entonces ejecutamos una acción y cambiamos 'Status' por 0 y cambiamos 'Value' por 0.
Si en el transcurso de la ejecución de la acción usamos valores adicionales con Status=2, el valor de 'Status' no cambia después del uso.

Vamos a considerar algunos ejemplos.

Ejemplo 1. Cambio de una variable.
Tenemos la variable Var1 del tipo entero con el valor 10. La variable se encuentra en el estado "waiting".

Title=Var1
Type=2
Status=0
Value=10

en el programa externo, cambia el valor de Var1 por 30. Ahora tenemos
Title=Var1
Type=2
Status=1
Value=30

El valor de 'Value' ha cambiado, así como el valor de 'Status' para "solicitud para el procesamiento de los cambios".

El programa MQL4 detecta los cambios, llama a la función necesaria y modifica el documento:
Title=Var1
Type=2
Status=0
Value=30

El valor de 'Value' ha sido aceptado y el valor de 'Status' ha cambiado a "waiting".

Ejemplo 2. Ejecución de una acción.
Veamos la variable Var2 del tipo Action. La variable se encuentra en el estado "waiting".

Title=Var2
Type=5
Status=0
Value=0

En el programa externo, cambia el valor de Var2 por 1. Mirando un poco hacia el futuro, podemos decir que para evitar errores al asignar un valor incorrecto a la variable de la acción en el programa externo, usamos un botón, no un campo de entrada. Ahora tenemos:
Title=Var2
Type=5
Status=1
Value=1

El valor de 'Value' ha cambiado, así como el valor de 'Status' para "solicitud para el procesamiento de los cambios".

El programa MQL4 detecta los cambios, llama a la función necesaria y modifica el documento:
Title=Var2
Type=5
Status=0
Value=0

El valor de 'Value' ha cambiado a 0, y el valor de 'Status' ha cambiado a "waiting".
Podemos ver que al ejecutar una acción, cambiarán los valores de 'Status' y 'Value'. Si cambia la variable, solo cambiará el valor de 'Status', mientras que el valor de la variable seguirá siendo el mismo.

Elegir un protocolo de transferencia
Entre los múltiples medios para la transferencia de datos entre un programa MQL4 y un programa externo, elegiremos el archivo. Usar un archivo no requiere el desarrollo de bibliotecas adicionales para MT4. Es método es bastante universal, requiere poco tiempo y es fácil de realizar. Tiene varios inconvenientes que pueden eliminarse fácilmente y no posee limitaciones críticas.

El programa MQL4 puede responder a los cambios en el archivo de las variables solo en un cierto evento: al cambiar el precio actual en el par de divisas actual.

Podemos iniciar la comprobación del archivo de las variables desde un programa externo en cualquier momento. Debemos seleccionar intervalos de tiempo óptimos para la comprobación para no sobrecargar los recursos de nuestro PC y no ocupar el archivo durante un largo periodo de tiempo, ya que puede ser usado simultáneamente por el programa MQL4. Los cambios en el programa externo se realizan principalmente por el ser humano, es decir, no tan rápido como un ordenador, por lo que será suficiente para comprobar el archivo con una frecuencia superior a medio segundo para hacer un seguimiento de la situación. Por supuesto, este parámetro puede ajustarse y debemos elegir empíricamente el intervalo de tiempo por nosotros mismos.

Durante el intento de abrir el archivo con el programa MQL4, este puede ser abierto por el programa externo para la escritura. Por tanto, debemos prever dicha situación y realizar varios intentos para llamar al archivo en un procesamiento para no desperdiciar nuestro tiempo esperando un nuevo cambio del precio. Lo mismo puede decirse del programa externo: Si el archivo es usado por el programa MQL4, debemos realizar varios intentos para llamar al archivo en ciertos intervalos de tiempo.

Adaptación a MQL4

Variables

int    ExVH_VarCnt;
string ExVH_FileName;
string ExVH_Project;
 
string ExVH_Title[];
string ExVH_Type[];
string ExVH_Status[];
string ExVH_Value[];

Funciones para el usuario

bool ExVH_Open(string FileName)
{
   bool Result=true;
   ExVH_FileName=FileName;
   if (!ExVH_i_Load())
      Result=false;
   if (Result)
      if (!ExVH_i_GetVarCnt())
         Result=false;
   if (Result)
      ExVH_i_Disassemble();
   return(Result);
}
 
int ExVH_Close()
{
   ExVH_i_Assemble();
   ExVH_i_Save();
 
}
 
int ExVH_GetStatus(int Id)
{
   if ((Id<1)||(Id>ExVH_VarCnt))
      return(-1);
   else
      return(StrToInteger(ExVH_Status[Id-1]));
}
 
int ExVH_SetStatus(int Id, int Status)
{
   int Result;
   if ((Id<1)||(Id>ExVH_VarCnt))
      Result=-1;
   else
   {
      Result=1;
      ExVH_Status[Id-1]=Status;
   }
   return(Result);
}
 
string ExVH_GetValue(int Id)
{
   if ((Id<1)||(Id>ExVH_VarCnt))
      return("N/A");
   else
      return(ExVH_Value[Id-1]);
}

Función para uso interno

bool ExVH_i_Load()
{
   bool Result=true;
   ExVH_Project="";
   int i=0;
   int FS=0;
   int handle;
   int Buf[];
   handle=FileOpen(ExVH_FileName,FILE_BIN|FILE_READ);
   if(handle>0)
   {
      FS=FileSize(handle);
      ArrayResize(Buf,FS);
      while(!FileIsEnding(handle)) 
      {
         Buf[i] = FileReadInteger(handle, CHAR_VALUE);
         i++;
      }
      
      FileClose(handle);
      string Str="";
      for (i=0;i<FS;i++)
         Str=Str+CharToStr(Buf[i]);  
      ExVH_Project=Str;
   } else 
      Result=false;
   return(Result);
}
 
bool ExVH_i_Save()
{
   bool Result=true;
   int handle=FileOpen(ExVH_FileName,FILE_BIN|FILE_WRITE);
   if(handle>0)
   {
      FileWriteString(handle,ExVH_Project,StringLen(ExVH_Project));
      FileClose(handle);
   } else
      Result=false;
   return(Result);
}
 
bool ExVH_i_GetVarCnt()
{
   bool Result=true;
   string Value=ExVH_i_GetVarValue("Var_Cnt");
   if (Value=="N/A")
      Result=false;
   else
      ExVH_VarCnt=StrToInteger(Value);
   return(Result);
}
 
void ExVH_i_Disassemble()
{
   int i;
   ArrayResize(ExVH_Title, ExVH_VarCnt);
   ArrayResize(ExVH_Type, ExVH_VarCnt);
   ArrayResize(ExVH_Status, ExVH_VarCnt);
   ArrayResize(ExVH_Value, ExVH_VarCnt);
   
   for (i=0;i<ExVH_VarCnt;i++)
   {
      ExVH_Title[i]=ExVH_i_GetVarValue("Var"+(i+1)+"_Title");
      ExVH_Type[i]=ExVH_i_GetVarValue("Var"+(i+1)+"_Type");
      ExVH_Status[i]=ExVH_i_GetVarValue("Var"+(i+1)+"_Status");
      ExVH_Value[i]=ExVH_i_GetVarValue("Var"+(i+1)+"_Value");
   } 
}
 
void ExVH_i_Assemble()
{
   ExVH_Project="[ExVH 1.0]\r\n\r\n";
   ExVH_Project=ExVH_Project+"Var_Cnt="+ExVH_VarCnt+"\r\n\r\n";
 
   int i;
   for (i=0;i<ExVH_VarCnt;i++)
   {
      ExVH_Project=ExVH_Project+"Var"+(i+1)+"_Title="+ExVH_Title[i]+"\r\n";
      ExVH_Project=ExVH_Project+"Var"+(i+1)+"_Type="+ExVH_Type[i]+"\r\n";
      ExVH_Project=ExVH_Project+"Var"+(i+1)+"_Status="+ExVH_Status[i]+"\r\n";
      ExVH_Project=ExVH_Project+"Var"+(i+1)+"_Value="+ExVH_Value[i]+"\r\n\r\n";
   } 
}
 
string ExVH_i_GetVarValue(string VarName)
{
   string Result="N/A";
   int Start,Stop;
   VarName=VarName+"=";
   Start=StringFind(ExVH_Project,VarName,0);
   if (Start!=-1)
   {
      Start=Start+StringLen(VarName);
      Stop=StringFind(ExVH_Project,CharToStr('\n'),Start);
      if (Stop!=-1)
      {
         Stop=Stop-1;
         Result=StringSubstr(ExVH_Project,Start,Stop-Start);
      }
   }
   return(Result);
}

Adaptación para C++

El proyecto fue escrito en C++ Builder 2007. Se adjunta al artículo el archivo de los códigos fuente llamado ExVH_CPP.zip.

La prueba

Vamos a realizar un pequeño ejemplo demostrativo que mostrará la mayoría de posibilidades.
Por tanto, vamos a crear el documento de prueba:


[ExVH 1.0]

Var_Cnt=5

Var1_Title=Boolean test
Var1_Type=0
Var1_Status=2
Var1_Value=0

Var2_Title=String test
Var2_Type=1
Var2_Status=2
Var2_Value=Hello world!

Var3_Title=Integer test
Var3_Type=2
Var3_Status=0
Var3_Value=12345

Var4_Title=Double test
Var4_Type=3
Var4_Status=0
Var4_Value=123.45

Var5_Title=Action test
Var5_Type=5
Var5_Status=0
Var5_Value=0

Vamos a guardar el documento con el nombre ExVH.evh en la carpeta [MetaTrader]/experts/files/.

La firma [ExVH 1.0] nos permite reconocer el documento al abrir el archivo e informa sobre la versión de la estructura del documento usada. Si cambia la estructura del documento, también debe cambiarse la firma. Esto nos permitirá evitar mezclar, teniendo en cuenta que la extensión del archivo del documento seguirá sin cambios.

Var_Cnt=5. Este registro nos indica que el documento contiene 5 variables.

Luego siguen los registros del mismo tipo que contienen la información de cada variable. Los registros se hacen de acuerdo con las especificaciones anteriores.

VarX_Title=
VarX_Type=
VarX_Status=
VarX_Value=

De este modo, tenemos dos variables (Var1 y Var2) que deben ser leídas tan pronto como aparece la acción (Var5), y dos variables (Var3 y Var4), cuyos cambios deben ser considerados de forma independiente.
El programa MQL4 debe visualizar el mensaje correspondiente en pantalla tan pronto como se realicen los cambios en las variables.


Prueba del código MQL4

int init()
{
   return(0);
}
 
int deinit()
{
   return(0);
}
 
int start()
{
   if (!ExVH_Open("ExVH.evh"))
      return(0);
   
   // Checking for action status
   if (ExVH_GetStatus(5)==1)
   {
      Alert("Actioned!");
      string VarValue;
      if (ExVH_GetValue(1)=="1")
         VarValue="true";
      else 
         VarValue="false";
      
      // Boolean variable value
      Alert("Boolean test variable="+VarValue);
      
      // String variable value
      Alert("String test variable="+ExVH_GetValue(2));
      
      ExVH_SetStatus(5,0);
   }
   
   // Integer variable value
   if (ExVH_GetStatus(3)==1)
   {
      Alert("Integer test variable has been changed. New value="+ExVH_GetValue(3));
      ExVH_SetStatus(3,0);
   }
   
   // Double variable value
   if (ExVH_GetStatus(4)==1)
   {
      Alert("Double test variable has been changed. New value="+ExVH_GetValue(4));
      ExVH_SetStatus(4,0);
   }
   
   ExVH_Close();
   return(0);
}


Ejecución y prueba
No importa qué parte del sistema de ejecute primero. En este caso será MetaTrader 4. Primero se copia el archivo ExVH_Demo.mq4 en la carpeta [MetaTrader]/experts/ y luego se inicia el terminal. El documento ExVH.evh ya ha sido escrito en el código del programa. Se ejecuta el asesor experto. No debe ocurrir nada ya que el asesor experto estará esperando a los cambios en el archivo.

Se ejecuta ExVH.exe instalado previamente en el PC.


Visión general del programa



Abrimos el 'Proyecto' y seleccionamos 'Abrir' el ítem…


Abrir el documento



El programa carga las variables y ahora podemos cambiarlas.

En la columna 'Status', aparecen dos valores: idle (esperando) y cambiado por ExVH (los cambios fueron realizados por un programa externo). Así es cómo aparece la pantalla después de haber activado nuestra acción ('Action').


Visión general del programa con 'Action' activada



Los cambios en los distintos tipos de variables se realizan de formas distintas.

Para una variable booleana, el programa muestra uno de los dos mensajes siguientes:



 



Para la activación de la acción ('Action') muestra este:





Para los demás tipos de variables ofrece una forma separada e independiente.


Forma para cambiar los valores de las variables



Después de una serie de cambios, puede aparecer la ventana de alerta ('Alert') en el terminal de la forma siguiente:


Cuadro de mensaje de ejemplo durante el funcionamiento del programa


Inconvenientes

Cualquier idea puede tener sus ventajas e inconvenientes.


• Este método no puede ser usado activamente para las pruebas retrospectivas.
• Cambiar los parámetros puede contradecir la lógica de nuestro asesor experto. Debemos procesar los cambios en las variables con mucho cuidado. Es más bien una característica que un inconveniente.
• La ejecución de los comandos solo es posible con la llegada de un nuevo tick.

¿Qué más se puede hacer?

La funcionalidad del sistema puede mejorarse en varios sentidos. El campo de acción es prácticamente ilimitado.

• Cambiar los parámetros según los distintos escenarios. Por ejemplo, para las contraseñas podemos tener la opción de ocultar la información introducida.
• El almacenamiento del archivo cifrado para poder ocultar las contraseñas.
• Podemos cambiar el protocolo de transferencia de datos, haciéndolo más fiable y seguro.

Conclusión


Hemos visto las formas de cambiar los valores de las variables internas en los programas MQL. Ahora tenemos una oportunidad de gestionar las variables externas y de otro tipo sin reiniciar el programa.

Los archivos adjuntos a este artículo

Archivo Descripción
ExVH_Demo.mq4Asesor experto de prueba
ExVH_Project.zipArchivo de proyecto elaborado
ExVH_CPP.zipCódigos fuente del programa externo
ExVH_Install.zipInstalador del programa externo

Nota: ExVH_Install se realizó usando la versión demostración del programa Advanced Installer.

Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/1538

Archivos adjuntos |
ExVH_CPP.zip (15.01 KB)
ExVH_Demo.mq4 (5.35 KB)
ExVH_Install.zip (1500.54 KB)
ExVH_Project.zip (0.28 KB)
Operaciones de archivo a través de WinAPI Operaciones de archivo a través de WinAPI
El entorno de MQL4 se basa en el concepto de "sandbox" seguro: solo está permitido leer y guardar archivos usando el lenguaje en algunas carpetas preestablecidas. Esto protege al usuario de MetaTrader 4 del peligro potencial de dañar datos importantes en el disco duro. No obstante, a veces es necesario dejar esa área segura. Este artículo está dedicado al problema de cómo hacerlo de una forma fácil y correcta.
Notas de aficionado: ZigZag Notas de aficionado: ZigZag
Seguramente, un iluso que pensara operar cerca de los extremos visitaría cada aprendiz de trader cuando es viera una polilínea "enigmática" por primera vez. Es tan simple, ciertamente. Este es el máximo. Y este es el mínimo. Una bonita imagen en el historial. ¿Y qué ocurre en la práctica? Se dibuja un rayo. Parecerá que este es el pico. Es el momento de vender. Y ahora vamos hacia abajo. Pero, demonios, no es así. El precio se mueve traicioneramente hacia abajo. ¡Sooo! Es una nimiedad, no un indicador. Y nos deshacemos de él.
Asesores expertos basados en sistemas de trading populares y alquimia de la optimización de robots de trading (Parte VII) Asesores expertos basados en sistemas de trading populares y alquimia de la optimización de robots de trading (Parte VII)
En este artículo, el autor da un ejemplo de asesor experto que cumple los requisitos establecidos en las Reglas del Campeonato de Trading Automatizado de 2008.
El análisis estadístico de los movimientos del mercado y su pronóstico El análisis estadístico de los movimientos del mercado y su pronóstico
El presente artículo contempla las amplias posibilidades del método estadístico en el marketing. Por desgracia, los traders principiantes fracasan deliberadamente a la hora de aplicar la formidable ciencia de la estadística. Mientras tanto, es lo único que usan de forma inconscientemente cuando analizan el mercado. Además, la estadística puede dar respuesta a muchas preguntas.