Conexão do Expert Advisor com ICQ no MQL5
Andriy Voitenko | 9 janeiro, 2014
Introdução
O ICQ é um serviço centralizado de troca instantânea de mensagens de texto, com um modo offline, o qual utiliza o protocolo OSCAR. Para um negociador, o ICQ serve como um terminal que mostra informações oportunas, assim como um painel de controle. Este artigo demonstrará um exemplo de como implementar um cliente de ICQ, com um conjunto mínimo de funções, dentro de um Consultor Especialista.
O esboço do projeto IcqMod, contendo um código original aberto, foi utilizado e processado como uma base para este artigo. O protocolo de troca com o servidor do ICQ é implementado no módulo DLL icq_mql5.dll. Ele é escrito em C++ e faz uso do único Windows library winsock2. Um módulo compilado e um código-fonte para o Visual Studio 2005, estão anexos neste arquivo.
Características e limitações distintas da implementação desse cliente:
- O número máximo de clientes operando simultaneamente é teoricamente ilimitado.
- O tamanho máximo de uma mensagem recebida - 150 caracteres. O recebimento de mensagens mais longas não é suportado.
- Suporte ao Unicode.
- Suporta somente uma conexão direta. Uma conexão feita através de um servidor proxy (HTTP/SOCK4/SOCK5) não é suportada.
- Mensagens offline não são processadas.
Descrição das funções da biblioteca
Descrições de constantes e funções do módulo dll estão localizadas no arquivo executável icq_mql5.mqh.
A função ICQConnect é utilizada para conectar ao 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)
Descrição do valor retornado através do ICQConnect:
Nome das constantes |
Valor |
Descrição |
---|---|---|
ICQ_CONNECT_STATUS_OK |
0xFFFFFFFF | Conexão estabelecida |
ICQ_CONNECT_STATUS_RECV_ERROR |
0xFFFFFFFE |
Erro de leitura de dados |
ICQ_CONNECT_STATUS_SEND_ERR |
0xFFFFFFFD |
Erro de envio de dados |
ICQ_CONNECT_STATUS_CONNECT_ERROR |
0xFFFFFFFC |
Erro de conexão ao servidor |
ICQ_CONNECT_STATUS_AUTH_ERROR | 0xFFFFFFFB | Erro de autorização: senha incorreta ou ultrapassado o limite de conexões |
Estrutura para armazenamento de dados sobre a conexão:
struct ICQ_CLIENT ( uchar status; // connection status code ushort sequence; // sequence meter uint sock; // socket number )
Na prática, de modo a realizar uma análise do status da conexão nesta estrutura, usamos o status variável o qual pode assumir os seguintes valores:
Nome das constantes |
Valor |
Descrição |
---|---|---|
ICQ_CLIENT_STATUS_CONNECTED | 0x01 | Uma conexão ao servidor está estabelecida |
ICQ_CLIENT_STATUS_DISCONNECTED |
0x02 | A conexão ao servidor falhou |
Tentativas frequentes de conectar-se ao servidor podem levar a um bloqueio temporário de acesso à sua conta. Assim, é necessário aguardar um intervalo de tempo entre tentativas de conexão ao servidor.
O tempo limite recomendado é de 20-30 segundos.
A função ICQClose serve para finalizar a conexão ao servidor:
void ICQClose ( ICQ_CLIENT & cl // Variable for storing connection data)
A função ICQSendMsg é utilizada para enviar mensagens de texto:
uint ICQSendMsg ( ICQ_CLIENT & cl, // Variable to store data about the connection. string uin, // Account number of the recipient string msg // Message)
O valor retornado é igual a 0x01, se a mensagem for enviada com sucesso, e igual a 0x00 se houve um erro de envio.
A função ICQReadMsg verifica o recebimento de mensagens:
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)
O valor retornado é igual a 0 se há uma mensagem de entrada e igual a 0x00 se não há mensagem.
Classe COscarClient
Para conveniência de trabalho com o ICQ em um ambiente orientado a objeto do MQL5, foi desenvolvida a classe COscarClient. Além das funções básicas descritas acima, ele contém um mecanismo o qual, após um intervalo de tempo específico, automaticamente se reconecta ao servidor (quando autocon = true). A descrição da classe está inclusa no arquivo anexo icq_mql5.mqh e é dada abaixo:
//+------------------------------------------------------------------+ 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 };
O Consultor Especialista nas bases do COscarClient
O código mínimo do Expert Advisor necessário para trabalhar com o ICQ usando a classe COscarClient está localizado no arquivo icq_demo.mq5 e abaixo:
#include 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); } } //+------------------------------------------------------------------+
A Figura 1. serve como uma demonstração do trabalho do Consultor Especialista o qual permite a troca de mensagens de texto com o cliente do ICQ.
Figura 1. Sistema de mensagem de texto entre o MetaTrader 5 e o ICQ2Go
Desenvolvimento de capacidade
Vamos complicar a tarefa trazendo para próximo da aplicação prática. Por exemplo, precisamos gerir o trabalho de nosso Consultor Especialista e obtemos as informações necessárias remotamente usando um celular ou outro PC conectado à internet. Para fazer isso, descrevemos um conjunto de comandos para controle do futuro Consultor Especialista. Além disso, vamos complementar o conselheiro com uma função de análise para decodificar os comandos de entrada.
O formato, comum a todos os comandos, será conforme o seguinte:
[? |!] [command] [parameter] [value] ,
onde? - Um símbolo de comando de leitura; ! - Um símbolo de uma escrita de operação.
Uma lista de comandos dados na tabela abaixo:
ajuda | leitura | Exibição de referência de sintaxe e a lista de comandos |
info | leitura | Exibição de dados do resumo da conta |
symb | leitura | Preço de mercado para o par de moedas dado |
ords | leitura/gravação | Gerenciamento de pedidos abertos |
param | leitura/gravação | gerenciamento de parâmetros do Consultor Especialista |
fechar | gravar | Encerramento do trabalho do Consultor Especialista e o fechamento do terminal |
shdwn | gravar | Desligamento do PC |
O Consultor Especialista, que implementa o processamento deste conjunto de comandos, está localizado no arquivo icq_power.mq5.
A Figura 2 mostra uma clara demonstração do trabalho do Consultor Especialista. Os comandos são recebidos do CCP com um cliente do ICQ instalado (Figura 2a) assim como através do servidor WAP http://wap.ebuddy.com o qual implementa o trabalho com o ICQ (Figura 2b). A segunda opção é preferível para aqueles que não queiram lidar com a busca, instalação e configuração do software para ICQ em seus celulares.
Figura 2. Trabalhando com um consultor pelo cliente do ICQ para Pocket PC (Figura 2a), assim como através do site wap wap.ebuddy.com (Figura 2b)
Componente visual do ICQ
Esta seção vai considerar resumidamente um exemplo de um script icq_visual.mq5, o qual implementa um componente, a aparência visual a qual é mostrada na Figura 3.
Figura 3. Componente visual do ICQ
A forma do componente lembra uma janela do Windows e é feita de arrays de elementos de controle, como botões, caixas de texto e etiquetas de texto.
Para comodidade, um elemento de controle integrado para armazenar uma lista de contas e contatos é implementada nessa forma. Valores são selecionados da lista através da utilização de botões de navegação apropriados.
Para criar uma janela no estilo do ICQ 6.5, podemos substituir os botões por marcas de imagem. A Figura 4 mostra a aparência visual do componente, implementado no script icq_visual_skin.mq5. Para aqueles que desejam criar seus próprios componentes de design, basta desenvolver e substituir o arquivo skin.bmp, o qual é responsável pelo aparecimento da janela.
Figura 4. Design de cor do componente visual do ICQ
Conclusão
Este artigo demonstra uma das maneiras mais fáceis de implementar um cliente de ICQ para o MetaTrader 5 utilizando os meios de uma linguagem de programação embutida.