English Русский 中文 Español Deutsch 日本語
Usando o Skype para enviar mensagens de um Expert Advisor

Usando o Skype para enviar mensagens de um Expert Advisor

MetaTrader 4Exemplos | 19 fevereiro 2016, 12:43
877 0
Alexey Koshevoy
Alexey Koshevoy

Introdução

Skype é um programa de telecomunicações que, juntamente com chats normais, permite ligações via Internet. Uma das principais vantagens do Skype em comparação com outros programas do tipo é uma porta de entrada para operadoras reais de telefonia móvel. Respectivamente, pode-se ligar para um telefone móvel real, enviar SMS e assim por diante. Há também uma versão do Skype para telefones móveis. Pode-se economizar dinheiro em SMS já que o envio de mensagens regulares dentro do programa é absolutamente gratuito. Basicamente, um telefone celular deve trabalhar sob um sistema operacional. Bem, agora é possível ser totalmente móvel, se necessário. E é essa oportunidade que muitas pessoas utilizam hoje em dia.


Por que e quem precisa disso?

O operador nem sempre pode sentar-se na frente do terminal de negociação e ver como a negociação é executada, ele não precisa fazer isso. No entanto, seria ótimo ser capaz de receber sinais que informassem o operador sobre ações do Expert Advisor ou sobre o estado do mercado em certos momentos. Por que não obter essa informação no celular?


Que tipo de informação seria útil receber?

As informações que podem ser obtidas utilizando mensagens em um telefone móvel podem ser divididas em dois grupos:

  1. dados atuais que não influenciam em nada e são praticamente os mesmos que aqueles no arquivo log;
  2. informações que serão úteis para o operador exatamente no momento de entrada.

Vamos considerar exemplos de dados atuais:

  • Estado dos pedidos. Quando um pedido for aberto, em que direção, que paradas foram atribuídas para ele, quando foi fechado, por que razão, com perda ou com lucro, etc.
  • Vários estados do mercado. Por exemplo, quando um indicador encontra um determinado nível ou quando uma tendência muda de direção.

Informação útil:

  • Relatório de erro. Todos os programadores são pessoas, e às vezes algumas situações desagradáveis ocorrem quando o Expert Advisor funciona de forma inadequada. Seria bom saber as condições nas quais ocorrem erros e se isso resulta em uma parada fatal. Isto irá funcionar, é claro, se a lógica do Expert Advisor permitir a detecção de erros.
  • Estado de funcionamento do Expert Advisor. Por exemplo, o EA está configurado para enviar uma mensagem sobre o estado de funcionamento a cada hora enquanto você estiver em uma viagem de negócios. E isso acontece para que a mensagem esperada não chegue na hora indicada. Tudo pode acontecer: desconectar-se da Internet e cortes de energia. Se o terminal funciona em sua casa, faria sentido pedir a um colega ou cônjuge para saber o motivo e restaurar as configurações, ao invés de esperar durante uma semana no escuro.

Essa divisão é, naturalmente, de uma natureza relativa, e a lista de eventos possíveis é maior que este artigo. Cada operador vai decidir o conteúdo que a mensagem deve ter. O principal é perceber que essa função é muito útil.


Como isso funciona no Skype?

  • SMS

    O serviço é, naturalmente, pago. Tudo parece normal: disque o número do assinante, escreva a mensagem e pressione "Enviar".

  • Mensagens comuns

    Isso é totalmente gratuito. Basta selecionar um usuário, digitar uma mensagem e pressionar "Enviar".

Como fazer isso de um Expert Advisor?

Eu encontrei duas maneiras de como fazer isso, e ambas precisam usar DLLs:

  1. Devemos preparar anteriormente um arquivo macro, ou seja, no lançamento daquele arquivo de controle do teclado e do mouse que será interceptado. Assim, usando a seqüência de ações, devemos ativar o Skype, encontrar o ícone de envio de SMS no menu, e em seguida, discar o número do assinante na janela, e colar da área de transferência a mensagem de texto inicialmente escrita na Expert Advisor. Você pode treinar e aperfeiçoar as operações de antemão. Assim, preparamos um arquivo que é um documento associado e pode ser lançado como uma aplicação normal. A propósito, existem muitos aplicativos que gravam e reproduzem arquivos macro, por isso não vamos considerar programas específicos neste artigo.

    Então, temos que desenvolver uma DLL que irá operar do seguinte modo: Sua primeira operação será colocar o texto do Expert Advisor na área de transferência. A segunda operação é lançar o arquivo macro predefinido. Se tudo estiver bem configurado e todas as janelas e botões aparecerem em seus devidos lugares, não deve ocorrer qualquer problema e a mensagem será enviada.

    No entanto, esta maneira é um pouco assustadora. Minha intuição me sugere que, se os cérebros começam a inventar algo assim, algum tem que encontrar uma solução mais agradável ou renunciar a ideia como um todo. Uma nova ideia surgiu na minha mente: O Skype pode ter um API? Bem, eu encontrei API e interface de ActiveX no site do Skype. Ótimo! Vamos considerar uma outra maneira de trabalhar com o Skype a partir de um Expert Advisor.

  2. É basicamente a mesma coisa. O número do assinante e o texto a ser enviado será transmitido do EA para a DLL, que envia a mensagem através do Skype objeto COM.

Como fazer da segunda maneira

Vamos começar com a DLL. A parte principal de todas as operações estarão preparando a DLL para a interação com o Expert Advisor. Em primeiro lugar, nós escrevemos uma biblioteca que trabalhará quando chamada desde vários Expert Advisors. Infelizmente, não será suficiente apenas escrever uma função e chamá-la. Estamos usando ActiveX, por isso é desejável criar um thread especial separado para isso e fazer todo o trabalho nele. A ferramenta de paralelismo padrão para funções Mutex não vai ajudar. Haverão crashes que não podem ser detectados. Então, vamos realizar a sequência de chamadas através do sistema de mensagens personalizado.

Código fonte DLL

#include "stdafx.h"
 
#pragma once
// Allow use of features specific to Windows XP or later. 
#ifndef WINVER
// Change this to the appropriate value to target other versions of Windows.
#define WINVER 0x0501      
#endif
// Exclude rarely-used stuff from Windows headers 
#define WIN32_LEAN_AND_MEAN
 
// Include Skype4COM.dll, preliminarily downloaded 
// from the Skype developers website – http://developers.skype.com/
#import "Skype4COM.dll" rename("CreateEvent","CreatePluginEvent"), 
                        rename("SendMessage","SendChatMessage")
 
 
#define MT4_EXPFUNC __declspec(dllexport)
 
// Declare message codes for our functions.
#define WM_PROC_SENDSKYPESMS WM_USER + 01
#define WM_PROC_SENDSKYPEMESSAGE WM_USER + 02
 
// Variables for the thread to be used for 
// sending messages
HANDLE hUserThread;
DWORD ThreadId;
 
// Structures to store parameters of functions
// SendSkypeSMS
struct fcpSendSkypeSMS
  {
    int ExitCode;
    char * UserNum;
    char * Message;
  };
 
// SendSkypeMessage
struct fcpSendSkypeMessage
  {
    int ExitCode;
    char * UserName;
    char * Message;
  };
//+------------------------------------------------------------------+
//| Thread function                                                  |
//+------------------------------------------------------------------+
DWORD WINAPI ThreadProc(LPVOID lpParameter)
  {
    MSG msg;
    HANDLE hEvent;
  
    while(true)
      {
        if(PostThreadMessage(GetCurrentThreadId(), WM_USER, 0, 0))
            break;
      };
    // Initialize COM
    CoInitialize(NULL);
    while(GetMessage(&msg, 0, 0, 0))
      {
        if(msg.message == WM_QUIT)
          {
            break;
          }
        // Message processor WM_PROC_SENDSKYPESMS
        else 
            if(msg.message == WM_PROC_SENDSKYPESMS)
              {
                fcpSendSkypeSMS* fcp = (fcpSendSkypeSMS*)msg.wParam;
                hEvent = (HANDLE)msg.lParam;
                try
                  {
                    // Initialize Skype 
                    SKYPE4COMLib::ISkypePtr pSkype(__uuidof(SKYPE4COMLib::Skype));
                    // Connect to Skype. 6 is the protocol version
                    HRESULT hr=pSkype->Attach(6,VARIANT_TRUE);
                    // If everything is ok, start sending the message
                    if(!FAILED(hr))
                      {    
                        try
                          {
                            fcp->ExitCode = 1;
                            // Try to send an SMS
                            pSkype->SendSms(fcp->UserNum,fcp->Message,"");
                          }
                        catch(...)
                          {
                            fcp->ExitCode=-1;
                          }
                      }
                    // Deinitialize Skype
                    pSkype = NULL;
                  }
                catch(...)
                  {
                    //Error is processed here
                  }
                // Set the event
                SetEvent(hEvent);
              }
            // Message processor WM_PROC_SENDSKYPEMESSAGE
            else 
                if(msg.message == WM_PROC_SENDSKYPEMESSAGE)
                  {
                    fcpSendSkypeMessage* fcp = 
                                   (fcpSendSkypeMessage*)msg.wParam;
                    hEvent = (HANDLE)msg.lParam;
        
                    try
                      {
                        // Initialize Skype 
                        SKYPE4COMLib::ISkypePtr pSkype(__uuidof
                                              (SKYPE4COMLib::Skype));
                        // Connect to Skype. 6 is the protocol version
                        HRESULT hr=pSkype->Attach(6,VARIANT_TRUE);
                        // If everything is ok, start sending the message
                        if(!FAILED(hr))
                          {
                            try
                              {
                                fcp->ExitCode = 1;
                                // Try to send the message
                                pSkype->SendChatMessage(fcp->UserName,
                                                        fcp->Message);
                              }
                            catch(...)
                              {
                                fcp->ExitCode=-1;
                                MessageBeep(0);
                              }
                          }
                        // Deinitialize Skype
                        pSkype = NULL;
                      }
                    catch(...)
                      {
                        //Error is processed here
                      }
  
                    // Set the event
                    SetEvent(hEvent);
                  }
              };
            // Deinitialize COM
            CoUninitialize();
            return 0;
          }
 
//DLL Initialization
//+------------------------------------------------------------------+
//| DLL entry                                                        |
//+------------------------------------------------------------------+
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call,
                      LPVOID lpReserved)
  {
    if(ul_reason_for_call == DLL_PROCESS_ATTACH)
      {
        // Create a thread and attach the processor procedure address to it
        hUserThread = CreateThread(NULL, NULL, ThreadProc, NULL, 0, &ThreadId);
        if(!hUserThread)
          {
            // Error processing if the thread is not created
          };
      } 
    else 
        if(ul_reason_for_call == DLL_PROCESS_DETACH)
          {
            // Delete the thread when exiting the library
            CloseHandle(hUserThread);
          }
    return(TRUE);
  }
 
MT4_EXPFUNC bool __stdcall SendSkypeSMS(int &ExCode,char* sUserNum, 
                                        char* sMessage)
  {
    //Declare the structure of function parameters
    fcpSendSkypeSMS* fcp;
    //Declare an event
    HANDLE hEvent;
    //The result of function operation by default is false
    bool Result = false;
 
    // Allocate a password for the structure and initialize it
    fcp = new fcpSendSkypeSMS();
    memset(fcp, 0, sizeof(fcpSendSkypeSMS));
 
    // Fill out the structure
    //By default, the code of the function working end is an error.
    fcp->ExitCode = -1;
    fcp->UserNum = sUserNum;
    fcp->Message = sMessage;
 
    // Create an event
    hEvent = CreateEvent(NULL,FALSE,FALSE, NULL);
    // Call event WM_PROC_SENDSKYPESMS, pass  the data structure address 
    // to processing procedure 
    PostThreadMessage(ThreadId, WM_PROC_SENDSKYPESMS, (WPARAM)fcp,
                      (LPARAM)hEvent);
    if(WAIT_OBJECT_0 == WaitForSingleObject(hEvent,INFINITE))
      {
        
        Result = true;
      } 
    else
      {
        // If there was an error at message processing, the function will 
        // return false
        return(Result);
      };
    // Assign the function processing code to the variable
    ExCode = fcp->ExitCode;
    if(ExCode == -1) 
        Result = false;
    // Free memory and variables and exit
    delete fcp;
    CloseHandle(hEvent);
    return(Result);
  }
 
MT4_EXPFUNC bool __stdcall SendSkypeMessage(int &ExCode,char* sUserName, 
                                            char* sMessage)
  {
    //Declare the structure of function parameters
 fcpSendSkypeMessage* fcp;
    //Declare an event
    HANDLE hEvent;
    //The result of function operation by default is false
    bool Result = false;
 
    // Allocate memory for the structure and initialize it
    fcp = new fcpSendSkypeMessage();
    memset(fcp, 0, sizeof(fcpSendSkypeMessage));
 
    // Fill out the structure
    //By default, the code of the function working end is an error.
    fcp->ExitCode = -1;
    fcp->UserName = sUserName;
    fcp->Message = sMessage;
 
    // Create an event
    hEvent = CreateEvent(NULL, FALSE,FALSE, NULL);
    // Call the event WM_PROC_SENDSKYPESMS, pass the data structure address 
    // to processing procedure
    PostThreadMessage(ThreadId, WM_PROC_SENDSKYPEMESSAGE, (WPARAM)fcp,
                      (LPARAM)hEvent);
    if(WAIT_OBJECT_0 == WaitForSingleObject(hEvent, INFINITE))
      {
        Result = true;
      } 
    else
      {
        // If there was an error at message processing, the function will 
        // return false
        return(Result);
      };
    // Assign the function processing code to the variable
    ExCode = fcp->ExitCode;
    if(ExCode == -1) 
        Result = false;
    // Free memory and variables and exit
    delete fcp;
    CloseHandle(hEvent);
    return(Result);
  }


Arquivo DEF

LIBRARY SkypeLib
 
EXPORTS SendSkypeSMS
        SendSkypeMessage


Expert Advisor a ser testado

//+------------------------------------------------------------------+
//|                                              SkypeTestExpert.mq4 |
//|                               Copyright © 2007, Alexey Koshevoy. |
//+------------------------------------------------------------------+
// Import functions
#import "SkypeLib.dll"
   bool SendSkypeSMS(int &ExCode[], string Num,string Message);
   bool SendSkypeMessage(int &ExCode[], string User, string Message);
#import
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {
   int ExCode[1];
   Alert("Send message...");
   Alert(SendSkypeMessage(ExCode, "skype.account.name", "Skype message test"));
   if(ExCode[0] == -1)
       Alert("Error sending the message");
   else 
       Alert("Message sent");
   Alert("Send SMS...");
   Alert(SendSkypeSMS(ExCode, "+1234567890", "Skype sms test"));
   if(ExCode[0] == -1)
       Alert("Error sending the SMS");
   else
       Alert("SMS sent");
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   return(0);
  }
//+------------------------------------------------------------------+

O Ea é muito simples, seu principal objetivo é enviar um SMS e uma mensagem normal por meio da DLL codificada. Atua com a função de inicialização, de modo que também pode ser testado nos fins de semana.


Instalação do Skype

O aplicativo pode ser baixado em http://www.skype.com/. Recomenda-se instalar a versão mais recente do programa, uma vez que as versões anteriores não suportam a interface COM, elas têm apenas uma API. No entanto, a API não suporta o envio de SMS.

Bem, o Skype já foi instalado. Agora, temos que baixar a biblioteca COM. Ela pode ser encontrada em https://developer.skype.com/, em Downloads. Verifique a quantidade na conta para ser utilizada para enviar SMS. Se não houver dinheiro suficiente, você pode adicionar um pouco através da Internet. Não permitirá enviar SMS sem dinheiro na conta, mas as mensagens regulares podem ser enviadas sem quaisquer problemas.


Para o terminal acessar a API do Skype, ele deve ser registrado. Você pode verificar se está autorizado a trabalhar com a API usando o menu de Ferramentas> Opções> privacidade-> Gerenciar outros programas de acesso ao Skype. Deve parecer mais ou menos com isso:




O terminal será registrado na primeira tentativa de usar a biblioteca. Não pode ser feito manualmente. Então, quando a biblioteca está sendo instalado pela primeira vez, é necessário esperar até que uma mensagem seja enviada, a fim de confirmar a permissão para usar o API do Skype. O Skype mostrará a seguinte caixa de diálogo:





Após a confirmação, o sistema começa a funcionar no modo automático.


Instalação da SkypeLib

Para instalar a biblioteca chamada Skype Lib.dll, é necessário copiá-la para a pasta experts/libraries no diretório terminal. A biblioteca nomeada Skype4COM.dll também deve ser copiada para a pasta. Agora, temos que configurar o terminal para ser capaz de trabalhar com o DLL. Para isso, verifique o campo de seleção "Permitir importações de DLL" na seção "Segurança" ao anexar uma EA como mostrado abaixo:


Agora podemos usar a biblioteca.


Alguns detalhes importantes

Possuindo alguma experiência em testes e implementações, eu notei algumas "sutilezas". Por exemplo, você tem que considerar que, se você tem dinheiro suficiente em sua conta e enviar um SMS para um número não-existente, nenhum erro será relatado, a função vai funcionar com êxito e o status da mensagem será definido para "enviando ... ". Por isso, é importante configurar as funções de entrada de forma muito clara. Também é muito importante usar o Skype versão 3. 0 (ou versões posteriores).

Acontece (no entanto, raramente) que o objeto COM não é inicializado e nenhuma mensagem será enviada. Isso só pode ser ajudado com a instalação do Skype. A interface externa é relativamente nova, não sem erros, então essas coisas desagradáveis podem acontecer. Comigo isso já aconteceu duas vezes. Esperamos que as versões posteriores sejam mais estáveis.

Algumas bibliotecas adicionais para Skype Lib. dll. podem ser necessárias. O problema ficou intenso após o lançamento do primeiro service pack para o Visual Studio 2005 A melhor maneira de resolver este problema é criar um arquivo de configuração. Todas as bibliotecas necessárias serão incluídas automaticamente. O arquivo Skype4COM. dll também pode ser incluído.


Arquivos anexados ao artigo

  • SkypeLib.dll - A biblioteca foi compilada no Visual C++ 6.0. Não precisa de quaisquer arquivos adicionais além do Skype4COM.dll.
  • SkypeLib.zip - O código fonte da biblioteca.
  • SkypeExample.mq4 - Um Expert Advisor para a biblioteca ser testada.

Altos e baixos

As seguintes desvantagens podem ser observadas quando se utiliza SMS pelo Skype:

  • Mensagens SMS têm um certo custo
  • Não se pode enviar uma mensagem para si mesmo, é necessário ter uma outra conta do Skype para obter mensagens.
  • O seu telefone deve suportar a versão móvel do Skype. Se um computador é usado para receber mensagens, esta desvantagem não existe mais.

Este método tem as seguintes vantagens:

  • Sinais em tempo real
  • Função que não podem ser substituídas no momento. Isto não é uma vantagem, é apenas um fato.


Conclusões

Aprendemos como enviar SMS e mensagens regulares via Skype. Desta forma, temos uma interface, que talvez não seja a mais conveniente, mas é certamente indispensável para nos informar sobre eventos atuais no terminal. O que vem a seguir? Bem, por exemplo, o Skype permite mensagens de envio e RECEBIMENTO...

Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/1454

Arquivos anexados |
SkypeExample.mq4 (0.71 KB)
SkypeLib.dll (56 KB)
SkypeLib.zip (2.36 KB)
Princípios de transformação de tempo em negociações intraday Princípios de transformação de tempo em negociações intraday
Este artigo contém o conceito de tempo de operação que permite receber mais até com fluxo de preço. Ele também contém o código de mudança de média móvel com auxílio para essa transformação de tempo.
Teste de Visualização: Histórico de negociações Teste de Visualização: Histórico de negociações
O artigo descreve as possibilidades de visualização convenientes do histórico de negociações ao visualizar testes.
Transferência de um Código Indicador para um Código Expert Advisor. Estrutura do Indicator Transferência de um Código Indicador para um Código Expert Advisor. Estrutura do Indicator
Este artigo trata sobre formas de transferência de um código indicador para um código Expert Advisor e sobre a escrita de Expert Advisors sem convocar indicadores personalizados, e com todo o código do programa para o cálculo dos valores dos indicadores necessários dentro do Expert Advisor. Este artigo fornece um esquema geral de uma estrutura de indicador, emulação de buffers indicadores no Expert Advisor e a substituição da função IndicatorCounted (). O artigo destina-se para leitores com experiência de programação na linguagem MQL4.
Análise técnica: Torne possível o impossível! Análise técnica: Torne possível o impossível!
O artigo responde a pergunta: por que o impossível tornou-se possível onde grande parte sugere o contrário? Raciocínio da análise técnica.