Conexión del Asesor Experto con ICQ en MQL5
Andriy Voitenko | 18 febrero, 2014
Introducción
El ICQ es un servicio centralizado de intercambio instantáneo de mensajes de texto con un modo offline que usa el protocolo OSCAR. Para un comerciante, el ICQ puede servir como terminal que muestra información actual, así como un panel de control. Este artículo demostrará un ejemplo de cómo implementar un ICQ client con un conjunto mínimo de funciones dentro de un Asesor Experto.
El borrador del proyecto IcqMod, que contiene un código original abierto, se usó y procesó como base para este artículo. El protocolo de intercambio con el servidor ICQ se implementa en el módulo DLL icq_mql5.dll. Se escribe en C++ y hace uso de la biblioteca solo de Windows winsock2. Puede encontrar adjuntos con este artículo módulos y un código fuente para Visual Studio 2005.
Distinguir cualidades y limitaciones de la implementación de este client:
- El número máximo de clients trabajando al mismo tiempo es, teóricamente, ilimitado.
- El tamaño máximo de mensajes entrantes es de 150 caracteres. No se admite la recepción de mensajes más largos.
- Soporte de unicode
- Solo soporta una conexión directa. No se admite la conexión a través de un servidor proxy (HTTP / SOCK4 / SOCK5).
- Los mensajes offline no se procesan.
Descripción de funciones de biblioteca
Las descripciones de constantes y funciones del módulo dll se encuentran en el archivo ejecutable icq_mql5.mqh.
La función ICQConnect se usa para conectarse al servidor:
uint ICQConnect (ICQ_CLIENT & cl, // Variable for storing data about the connection string host, // Server name, such as login.icq.com ushort port, // Server port, eg 5190 string login, // Account Number (UIN) string pass // Account password for)
Descripción del valor de devolución a través de ICQConnect:
Nombre de la Constante |
Valor |
Descripción |
---|---|---|
ICQ_CONNECT_STATUS_OK |
0xFFFFFFFF | Conexión establecida |
ICQ_CONNECT_STATUS_RECV_ERROR |
0xFFFFFFFE |
Leer error de datos |
ICQ_CONNECT_STATUS_SEND_ERR |
0xFFFFFFFD |
Enviar error de datos |
ICQ_CONNECT_STATUS_CONNECT_ERROR |
0xFFFFFFFC |
Error de conexión al servidor |
ICQ_CONNECT_STATUS_AUTH_ERROR | 0xFFFFFFFB | Error de autorización: contraseña incorrecta o se ha excedido el límite de conexiones. |
Estructura para almacenar datos sobre la conexión:
struct ICQ_CLIENT ( uchar status; // connection status code ushort sequence; // sequence meter uint sock; // socket number )
En la práctica, para realizar un análisis del estado de la conexión en esta estructura usaremos el estado variable, que puede asumir los siguientes valores:
Nombre de la Constante |
Valor |
Descripción |
---|---|---|
ICQ_CLIENT_STATUS_CONNECTED | 0x01 | Se ha establecido una conexión al servidor |
ICQ_CLIENT_STATUS_DISCONNECTED |
0x02 | Fallo en la conexión al servidor |
Si se dan intentos frecuentes de conexión al servidor se puede producir un bloqueo temporal de acceso a su cuenta. Por tanto, es necesario esperar un intervalo de tiempo entre los intentos de conexión al servidor.
El tiempo recomendado de desconexión es de entre 20 y 30 segundos.
La función ICQClose sirve para terminar la conexión con el servidor:
void ICQClose ( ICQ_CLIENT & cl // Variable for storing connection data)
La función ICQSendMsg se usa para enviar mensajes de texto:
uint ICQSendMsg ( ICQ_CLIENT & cl, // Variable to store data about the connection. string uin, // Account number of the recipient string msg // Message)
El valor de devolución equivale a 0x01 si el mensaje se envió con éxito, y equivale a 0x00 si se dio un error de envío.
La función ICQReadMsg comprueba si hay mensajes entrantes
uint ICQReadMsg ( ICQ_CLIENT & cl, // Variable for storing connection data string & Uin, // Account number of the sender string & Msg, // Message uint & Len // Number of received symbols in the message)
El valor de devolución equivale a 0x01 si hay un mensaje entrante, y a 0x00 si no hay mensajes.
Clase COscarClient
La clase COscarClient se desarrolló para hacer más conveniente trabajar con ICQ en un entorno orientado al objeto en MQL5. Además de las funciones básicas descritas arriba, contiene un mecanismo que, tras un determinado intervalo de tiempo, se reconecta automáticamente al servidor (cuando autocon = true). La descripción de la clase se incluye en el archivo adjunto icq_mql5.mqh , y se muestra abajo:
//+------------------------------------------------------------------+ class COscarClient //+------------------------------------------------------------------+ { private: ICQ_CLIENT client; // storing connection data uint connect; // flag of status connection datetime timesave; // the time of last connection to the server datetime time_in; // the time of last reading of messages public: string uin; // buffer for the storage of the uin of the sender for a received message string msg; // buffer for the storage of text for a received message uint len; // the number of symbols in the received message string login; // number of the sender's account (UIN) string password; // password for UIN string server; // name of the server uint port; // network port uint timeout; // timeout tasks (in seconds) between attempts to reconnect to the server bool autocon; // automatic connection resume COscarClient(); // constructor for initialization of variable classes bool Connect(void); // establishment of a connection with a server void Disconnect(void); // breaking a connection with a server bool SendMessage(string UIN, string msg); // sending a message bool ReadMessage(string &UIN, string &msg, uint &len); // receiving a message };
Asesor Experto en las bases de COscarClient
El código mínimo de Asesor Experto necesario para trabajar con ICQ usando la clase COscarClient se encuentra en el archivo icq_demo.mq5 y abajo:
#include <icq_mql5.mqh> COscarClient client; //+------------------------------------------------------------------+ int OnInit() //+------------------------------------------------------------------+ { printf("Start ICQ Client"); client.login = "641848065"; //<- login client.password = "password"; //<- password client.server = "login.icq.com"; client.port = 5190; client.Connect(); return(0); } //+------------------------------------------------------------------+ void OnDeinit(const int reason) //+------------------------------------------------------------------+ { client.Disconnect(); printf("Stop ICQ Client"); } //+------------------------------------------------------------------+ void OnTick() //+------------------------------------------------------------------+ { string text; static datetime time_out; MqlTick last_tick; // reading the messages while(client.ReadMessage(client.uin,client.msg,client.len)) printf("Receive: %s, %s, %u", client.uin, client.msg, client.len); // transmission of quotes every 30 seconds if((TimeCurrent()-time_out)>=30) { time_out = TimeCurrent(); SymbolInfoTick(Symbol(), last_tick); text = Symbol()+" BID:"+DoubleToString(last_tick.bid, Digits())+ " ASK:"+DoubleToString(last_tick.ask, Digits()); if (client.SendMessage("266690424", //<- number of the recipient text)) //<- message text printf("Send: " + text); } } //+------------------------------------------------------------------+
Figura 1. sirve como demostración del trabajo del Asesor Experto, que permite el intercambio de mensajes de texto con el ICQ client.
Figura 1. Mensajes de texto entre MetaTrader5 y ICQ2Go
Construir capacidad
Compliquemos la tarea acercándola a su aplicación práctica. Por ejemplo, imaginemos que necesitamos gestionar el trabajo de nuestro Asesor Experto y obtener información remotamente usando un teléfono móvil u otro PC conectado a internet. Para ello, describimos un conjunto de comandos para controlar el futuro Asesor Experto. Asimismo, complementemos el asesor con una función de análisis para descodificar los comandos entrantes.
El formato, común a todos los comandos, será así:
[? |!] [command] [parameter] [value] ,
donde ? - Un símbolo de lectura de comando; ! - Un símbolo de escritura de operación.
A continuación damos una lista de comandos en la siguiente tabla:
ayuda | lectura | muestra de referencia de la sintaxis y la lista de comandos |
info | lectura | Muestra de los datos del resumen de cuenta |
symb | lectura | precio de mercado para el par de divisas seleccionado |
ords | lectura / escritura | gestión de órdenes abiertas |
param | lectura / escritura | gestión de parámetros de Asesor Experto |
cerrar | grabar | Terminación del trabajo del Asesor Experto y el cierre del terminal |
shdwn | grabar | Apagado de PC |
El Asesor Experto, que implementa el procesamiento de este conjunto de comandos, se encuentra en el archivo icq_power.mq5 .
La figura 2 muestra el trabajo del Asesor Experto. Los comandos se reciben del CCP con un ICQ client instalado (Figura 2a), así como a través del servidor WAP http://wap.ebuddy.com, que implementa el trabajo con ICQ (Figura 2b). La segunda opción es preferible para aquellos que no desean buscar, instalar y configurar software para ICQ en sus teléfonos móviles.
Figura 2. Trabajar con un Asesor Experto a través del ICQ client para Pocket PC (Figura 2a), así como a través del sitio wap wap.ebuddy.com (Figura 2b).
Componente Visual del ICQ
Esta sección revisará brevemente un ejemplo de script icq_visual.mq5 que implementa un componente cuya apariencia visual se muestra en la Figura 3.
Figura 3. Componente Visual del ICQ
La forma del componente se parece a una ventana de Windows, y está formada por arrays de elementos de control como botones, cuadros de texto y etiquetas.
Por motivos de conveniencia se incluye un elemento de control integrado para almacenar una lista de cuentas y contactos. Los valores se seleccionan de la lista a través del uso de los botones de navegación correspondientes.
Para crear una ventana del estilo de ICQ 6.5, podemos sustituir los botones con etiquetas de imagen. La Figura 4 muestra la apariencia visual del componente, implementada en el script icq_visual_skin.mq5 . Para aquellos que desean crear su propio diseño de componentes, es suficiente desarrollar y sustituir el archivo skin.bmp, que es responsable de la apariencia de la ventana.
Figura 4. Diseño de colores del componente visual del ICQ
Conclusión
Este artículo demuestra una de las formas más sencillas de implementar un ICQ client para MetaTrader 5 usando los medios de un lenguaje de programación incrustado.