English Русский 中文 Español Deutsch 日本語
preview
Desenvolvendo um EA de negociação do zero (Parte 31): Em direção ao futuro (IV)

Desenvolvendo um EA de negociação do zero (Parte 31): Em direção ao futuro (IV)

MetaTrader 5Negociação | 16 setembro 2022, 08:53
1 122 0
Daniel Jose
Daniel Jose

Introdução

Depois de termos retirado o Chart Trade de dentro do EA, no artigo Desenvolvendo um EA de negociação do zero (Parte 29), fizemos com que este mesmo Chart Trade se torna-se um indicador. O modo de se fazer isto, com todos os detalhes envolvidos, incluindo os procedimentos e os cuidados necessários para que o indicador continua-se sendo útil, foi visto no artigo Desenvolvendo um EA de negociação do zero (Parte 30). Aquilo foi um dos meios que podemos usar, existem outros com suas vantagens e desvantagens, mas isto iremos ver em outro momento.

Pois bem, ainda temos mais coisas para serem removidas de dentro do EA, aqui vamos remover mais uma delas, a última coisa que será de fato removida, nesta serie de artigos, é o sistema de som. Talvez isto venha a lhe dar um nó no cérebro, caso você não tenha acompanhado estes artigos.

Para entender como todo o processo irá se dar, já que é algo que envolve uma quantidade muito grande de coisas a serem explicadas. Nos iremos utilizar, quase o mesmo modelo, utilizado no artigo anterior, isto para que a explicação, fique o mais simples possível de ser entendida, principalmente por parte de pessoas que não são programadores profissionais. Mas iremos adicionar uma pitada de complexidade no sistema, só para apimentar um pouco a coisa.

A bola da vez, como já foi dito acima, será o sistema de som. Sim, ele agora irá deixar de fazer parte do EA. Mas isto trará uma enorme quantidade de vantagens, em um futuro próximo. Então vamos com calma, pois o perfeito entendimento do que estará acontecendo aqui é primordial. Apesar disto, este artigo será relativamente curto, mas nem por isto, menos interessante.


Implementando um Serviço de Som

Você pode estar ficando maluco com todas estas mudanças, mas a ideia aqui não é te deixar maluco, talvez um pouco desnorteado 😁, mas a real intenção é mostrar como as vezes pequenas mudanças, podem fazer uma grande diferença e tornar o uso da plataforma MetaTrader 5, algo muito mais agradável. Ao mesmo tempo que você poderá notar, o quanto ela nos permite modular as coisas.

Desta forma você pode escolher o que quer ou não usar, e quando algo lhe agradar, você possa a vim a conseguir adicionar melhorias a este recurso, de maneira a torná-lo ainda mais útil e agradável, mas ao mesmo tempo, você não irá precisar fazer grandes mudanças, ou ter que reprogramar coisas que montadas a tempos atrás, a ideia é REUTILIZAR SEMPRE.

Um destes recursos é o sistema de som, talvez você pense que deixar este sistema dentro do EA, é uma boa ideia. De certa forma este sistema não atrapalha o EA, de uma maneira geral, mas se você o tirar de dentro do EA, mas mantendo algum tipo de comunicação com o EA, irá notar que conseguirá usar alertas sonoros, em vários outros momentos, e de maneira super simples, como se fosse uma biblioteca sonora, e isto irá lhe ajudar muito.

Nada adianta você colocar um sistema de alerta apenas no EA, pode lhe ser muito útil ter um sistema de alertas sonoros em indicadores, ou até mesmo em scripts que estejam sendo executados em determinados momentos. Isto para lhe ajudar na analise, junto com o EA. Desta forma, a plataforma MetaTrader 5, se torna um verdadeiro MONSTRO em termos de analise, onde você irá usar uma quantidade enorme de cálculos, para lhe ajudar a analisar o mercado, em momentos bastante específicos, seja para entrada em posições, seja para encerramento. E isto com o mínimo de esforço.

Desta forma, acredito que você pode estar pensando: Mas posso adicionar em um arquivo MQH ( Arquivo de Cabeçalho ) todos os sons, embutir eles nos executáveis, e ter o comportamento necessário. Sim você pode, mas pense no seguinte cenário: Com o tempo, este arquivo MQH irá crescer, e conforme isto for acontecendo, alguns programas mais antigos, podem vim a se tornar incompatíveis com este arquivo de cabeçalho ( MQH ). Ao ter que recompilar tais arquivos antigos, você irá se deparar com problemas, mas se você criar um sistema modular, onde existirá um protocolo de comunicação entre os processos, irá conseguir ampliar as funcionalidades da plataforma, ao mesmo tempo que mantem uma retrocompatibilidade, com os programas mais antigos.

É esta a proposta e o motivo destas mudanças, mostrar como você pode criar e usar algum dos caminhos possíveis. E estou mostrando isto, ao retirar as coisas de dentro do EA, ao mesmo tempo que mantemos as coisas com um funcionamento o mais próximo possível do comportamento original.

No artigo anterior, mostrei como recriar o Chart Trade, de forma a ter um comportamento bastante similar, ao que existia quando ele ainda estava embutido no EA. Mas ao retirar ele do EA, era preciso criar alguma forma de fazer com que ele continuasse a funcionar da mesma maneira. Aquela forma que mostrei, é um, entre tantos caminhos possíveis, não é o melhor, mas é um que funciona. Cada solução exige conhecimento adequado de como as coisas funcionam. As vezes ficar limitado a apenas um modelo de ideia, não nos ajuda a resolver algumas situações especificas, muito pelo contrário. Justamente por falta de conhecimento, muitos acham que não dá para fazer as coisas, ou simplesmente dizem que o sistema é limitado, quando na verdade, a limitação esta na falta de conhecimento da pessoa responsável por planejar e implementar uma solução.

Vimos isto quando implementei o sistema de ordens, de forma a não usar nenhum tipo de estrutura para armazenar os dados, muitos achavam que aquilo era algo impossível de ser feito, que não haveria como fazer tal coisa, mas mostrei que sim, é possível fazer tal coisa. O grande detalhe é que para fazer isto, é preciso que você conheça e entenda o que esta fazendo, e saber conhecer as limitações de cada tipo de solução, é o primeiro caminho.

Então vamos aprender, como fazer com que o sistema de som, fique o mais modular possível, ao mesmo tempo que poderemos expandir a sua funcionalidade, conforme o sistema vier a crescer no futuro.

Em primeiro lugar, não iremos mexer, a não ser que o motivo seja vim a aumentar a funcionalidade na classe C_Sound, esta não irá sofrer grandes mudanças. Na verdade neste momento, esta classe irá ficar da mesma forma, mas precisamos fazer algumas pequenas adições ao sistema. A primeira delas é um arquivo de cabeçalho visto abaixo:

#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
#define def_GlobalVariableAlert "Sound Alert"
//+------------------------------------------------------------------+

Você já deve estar pensando que iremos usar este arquivo no EA, mas não ... o EA não irá usar este arquivo, pelo menos por enquanto, ele irá usar um outro arquivo, que iremos ver mais para frente.

Depois disto, poderemos criar o arquivo que será o serviço de som, este pode ser visto no código abaixo:

#property service
#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
#include <NanoEA-SIMD\Auxiliar\C_Sounds.mqh>
#include <NanoEA-SIMD\Interprocess\Sound.mqh>
//+------------------------------------------------------------------+
void OnStart()
{
        union u00
        {
                double value;
                struct s00
                {
                        uint    i0,
                                i1;
                }info;
        }u_local;
        C_Sounds Sound;
        
        while (!IsStopped())
        {
                Sleep(500);
                if (GlobalVariableGet(def_GlobalVariableAlert, u_local.value))
                {
                        GlobalVariableDel(def_GlobalVariableAlert);
                        if (u_local.info.i1 == 0) Sound.PlayAlert((C_Sounds::eTypeSound)u_local.info.i0);
                        else Sound.PlayAlert(u_local.info.i1);
                }
        }
}
//+------------------------------------------------------------------+

O que este serviço faz é ficar observando as variáveis globais do MetaTrader 5, assim que a variável cujo nome esta declarado no arquivo de cabeçalho, for lançada por qualquer script, EA ou indicador, não importa qual seja, ou quando isto irá acontecer, o serviço irá reproduzir o som indicado.

Tudo que você irá precisar fazer, é indicar qual é o index do som a ser reproduzido, com base na estrutura acima, você irá poder reproduzir um total de 4294967295 sons diferentes, este numero é apenas de arquivos externos, você poderá ter o mesmo numero de sons internos, ou seja dá para fazer MUITA coisa.

Para que o sistema saiba qual o tipo de som a ser reproduzido, é verificando o valor da variável u_local.info.i1, se este valor for igual a 0, o som a ser reproduzido estará embutido no arquivo de serviço, e o index do som será indicado pela variável u_local.info.i0, mas este valor representa o enumerador dentro da classe C_Sound.

Com isto já podemos compilar o serviço, e colocá-lo em execução, e assim que as condições descritas acima forem satisfeitas, o serviço irá executar o seu trabalho, lembrando que quando a variável global for capturada pelo serviço, ela será removida para que seja utilizada em outro momento.

Mas vamos pensar um pouco antes de prosseguirmos. Diferente do indicador Chart Trade, que irá se comunicar apenas com o EA, o sistema de som, poderá se comunicar com qualquer tipo de programa, dentro da plataforma MetaTrader 5. E para fazer com que o som adequado seja reproduzido, teremos que montar o valor da variável, que sempre será um valor double, e isto de forma adequada.

Você pode achar que isto é simples, mas tente fazer isto e verá que não é tão simples assim, isto fora o trabalho de ter que ficar criando a variável global, com o nome correto a todo momento. Ou seja, no mínimo você terá uma bela, de uma trabalheira, toda a vez que desejar emitir algum som, previamente armazenado.

Mas existe uma solução, que ao mesmo tempo é prática, e evita que tenhamos toda esta trabalheira. Já que ela é bastante bonita e sedutora, vamos utilizá-la no seu nível mais simples, neste primeiro momento. Para ver como isto será feito, vejamos o próximo tópico, que irá tratar justamente desta questão.


Criando uma biblioteca para acessar o serviço de som

O motivo da criação de uma biblioteca, é que ela irá facilitar a nossa vida de alguma forma, não importa como, mas ela irá facilitar a nossa vida. No tópico anterior, falei que quando um programa for acessar o serviço de som, nos não iriamos precisar saber qual era o nome da variável global, que daria acesso ao serviço. E apesar de parecer estranho, a melhor forma de passar informações entre processos, é adicionando uma camada ao sistema, esta camada é a biblioteca.

Estas bibliotecas irão "ocultar" a complexidade da modelagem dos dados entre processos, de forma que você irá deixar de se preocupar com a forma que esta modelagem deverá ter, e apenas se preocupar com as chamadas em si, e qual o resultado esperado.

Ao criar uma biblioteca teremos 2 preocupações apenas:

  1. Declarar de forma clara as funções que serão exportadas;
  2. Ocultar o máximo a complexidade da modelagem interna, de forma que o usuário da biblioteca não precise saber o que esta acontecendo, ele apenas irá ver os dados entrando e o resultado saindo.

Então qualquer procedimento ou função dentro de uma biblioteca, é pensada de forma a ter um comportamento bastante simples, pelo ponto de vista do usuário da função ou procedimento, mas internamente, pode haver um nível extremamente complexo no funcionamento, até se obter os resultados no final. Mas o programador que estará usando a biblioteca, não precisa saber o que esta acontecendo dentro dela, apenas saber que os resultados estão sendo fornecidos de forma correta.

Então vamos ver a nossa biblioteca, que irá ocultar a modelagem dos dados a serem usados no serviço de som. Todo e qualquer programa irá precisar informa 2 coisas: A primeira é se o som é interno ou externo; A segunda é qual o index do som. Parece complicado ?!?! Bem, vamos ver o código destas chamadas dentro da biblioteca:

void Sound_WAV(uint index) export { Sound(0, index); }
void Sound_Alert(uint index) export { Sound(index, 0); }

Estas duas funções fazem a vez de ocultar qualquer complexidade na modelagem dos dados. Veja que estamos usando uma palavra chave, export, esta irá informar ao compilador, para criar um link simbólico para estas funções. Na verdade elas são procedimentos, já que não retornam valores. Desta forma estas ficarão visíveis fora do arquivo, seria como se este arquivo fosse uma DLL.

Bom, mas se você procurar em todo o código, não irá encontrar nenhuma função chamada Sound, então onde ela esta ?!?! Na verdade ela esta na própria biblioteca, mas não será visível fora dela. Vejam o código completo da biblioteca logo abaixo:

//+------------------------------------------------------------------+
#property library
#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
#include <NanoEA-SIMD\Interprocess\Sound.mqh>
//+------------------------------------------------------------------+
void Sound_WAV(uint index) export { Sound(0, index); }
//+------------------------------------------------------------------+
void Sound_Alert(uint index) export { Sound(index, 0); }
//+------------------------------------------------------------------+
void Sound(uint value00, uint value01)
{
        union u00
        {
                double value;
                struct s00
                {
                        uint    i0,
                                i1;
                }info;
        }u_local;
        
        u_local.info.i0 = value00;
        u_local.info.i1 = value01;
        GlobalVariableTemp(def_GlobalVariableAlert);
        GlobalVariableSet(def_GlobalVariableAlert, u_local.value);
}
//+------------------------------------------------------------------+

Notem que o procedimento Sound, irá conter toda a complexidade necessária, para montar o valor adequando, a fim de que o serviço execute a tarefa, que algum script, indicador ou EA está querendo efetuar. Mas ao invés de colocar este código, dentro do programa que irá acessar o serviço, iremos usar apenas as chamadas simplificadas, o que torna a depuração dos programas mais confortável e menos cansativa.

Para que você entenda, como isto funciona vamos ver um script de exemplo:

#property copyright "Daniel Jose"
#property script_show_inputs
#import "Service_Sound.ex5"
        void Sound_WAV(uint);
        void Sound_Alert(uint);
#import
//+------------------------------------------------------------------+
input uint value00 = 1;         //Som interno do serviço...
input uint value01 = 10016;     //Som gravado em arquivo WAV...
//+------------------------------------------------------------------+
void OnStart()
{
        Sound_WAV(value01);
        Sound_Alert(value00);
}
//+------------------------------------------------------------------+

Notem no código acima do script, que não é preciso saber qual o tipo de comunicação que esta sendo feita, onde e quando o evento de reprodução de som irá acontecer, ele pode estar acontecendo em qualquer lugar, dentro da plataforma, dentro do sistema operacional, ou mesmo remotamente, não importa. As únicas coisas que precisamos informar, é se o som é interno ou externo do sistema, e o index deste.

Agora antes de prosseguirmos, gostaria que você fizesse a seguinte experiência: Troque de lugar as funções, ou seja, na atual situação estamos executando Sound_WAV e depois Sound_Alert. Execute e veja o resultado. Mude de forma a executar primeiro Sound_Alert, para logo em seguida Sound_WAV, e veja o resultado. Para quem não entendeu, o código dentro do evento OnStart, ficaria assim na primeira situação:

void OnStart()
{
        Sound_WAV(value01);
        Sound_Alert(value00);
}

Na segunda situação, o código seria este:

void OnStart()
{
        Sound_Alert(value00);
        Sound_WAV(value01);
}

Apesar de aparentemente bobo, este teste é necessário, para que você entenda algumas coisas. Não deixe de experimentar isto, será interessante você ver os resultados...

Agora que você viu, o que será preciso adicionar aos seus programas, de forma a reproduzir sons, bastará adicionar o seguinte código:

#import "Service_Sound.ex5"
        void Sound_WAV(uint);
        void Sound_Alert(uint);
#import

E quando você for reproduzir o som, bastará usar a rotina adequada com o valor adequado, não precisando se preocupar em como a coisa será realmente feita, pois todo o restante do sistema, irá tomar conta para que tudo funcione perfeitamente. No nosso EA, o código ficará assim:

// ...

#import "Service_Sound.ex5"
        void Sound_WAV(uint);
        void Sound_Alert(uint);
#import
//+------------------------------------------------------------------+
#include <NanoEA-SIMD\Trade\Control\C_IndicatorTradeView.mqh>
#include <NanoEA-SIMD\Interprocess\Sound.mqh>

// ...

Mas ai vem a pergunta: O que o código em destaque esta fazendo ai ?!?! Não seria preciso apenas usar a biblioteca ?!?! SIM, mas pode ser que você esteja utilizando uma enumeração, para identificar os código numéricos dos sons, assim como era feito antes, e a não ser que você utilize um número muito baixo de sons ou alertas, saber o que cada um representa, apenas observando o código, é algo muito difícil. Por este motivo o arquivo de cabeçalho Sound.mqh recebeu uma adição, e esta esta em destaque no código abaixo:

#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
#define def_GlobalVariableAlert "Sound Alert"
//+------------------------------------------------------------------+
enum eTypeSound {TRADE_ALLOWED, OPERATION_BEGIN, OPERATION_END};
//+------------------------------------------------------------------+

Desta forma podemos ter um código como mostrado abaixo:

int OnInit()
{
        if (!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
        {
                Sound_Alert(TRADE_ALLOWED);
                return INIT_FAILED;
        }

// ... Restante da função

Que é muito mais representativo, que o mesmo código, só que usando index no lugar das enumerações, que é visto logo a seguir:

int OnInit()
{
        if (!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
        {
                Sound_Alert(0);
                return INIT_FAILED;
        }

// ... Restante do código

Agora responda sinceramente: Qual é mais simples de entender ?!?!

No final de todo este trabalho, você terá um fluxo de informações, dentro da plataforma, que é mostrado na figura abaixo:

Notem que não interessa quem esta fornecendo o sinal, teremos sempre o mesmo destino.


Conclusão

Apesar de não parecer grande coisa, o que foi mostrado neste artigo ajuda muito a aumentar a usabilidade de seus código, programas e informações. Já que você começa a programar cada vez menos, e ficar cada vez mais produtivo, ao mesmo tempo que seus código se tornam mais seguros e estáveis, pois a reutilização e os testes estão acontecendo em diversos cenários diferentes.

Aqui vimos um outro caminho, diferente do visto no artigo anterior, mas ainda assim, este pode ser melhorado e muito, nos dando uma quantidade enorme de novas possibilidades e arranjos possíveis. Mas isto será visto em um outro momento, em uma outra sequencia que esta sendo produzida. Onde você irá aprender a deixar seus programas e projetos no MetaTrader 5 muito mais modulares, com um nível de segurança, usabilidade e estabilidade, muito maior, do que qualquer o método mostrado aqui.

Mas o principal e mais importante, é você saber como projetar, e usar alguns tipos de solução, pois existem casos em que uma solução, irá ser melhor que outra, seja por um motivo ou outro.

Todos os código estão disponíveis no arquivo em anexo, para quem não tem muito costume com este modo de programar, usando bibliotecas, aconselho estudar bem esta fase de desenvolvimento do EA, não deixe para amanhã o que você pode fazer no dia de hoje, pois o dia de amanhã pode não chegar para você da maneira que você espera.

Com este artigo, encerramos esta fase de desenvolvimento do EA. Em breve irei trazer outro tipo de material, focado em outro tipo de situação, onde o nível de complexidade envolvida é muito maior, mas no entanto consideravelmente mais interessante. Então nos vemos em breve ... forte abraço a todos e até mais ...


Arquivos anexados |
EA_-_j_Parte_31_f.zip (14533.52 KB)
Redes neurais de maneira fácil (Parte 18): Regras de associação Redes neurais de maneira fácil (Parte 18): Regras de associação
Como continuação desta série, gostaria de apresentar a vocês outro tipo de tarefa dos métodos de aprendizado não supervisionado, em particular a busca de regras de associação. Este tipo de tarefa foi usado pela primeira vez no varejo para analisar cestas de compras. Neste artigo falaremos sobre as possibilidades de utilização de tais algoritmos no trading.
Ciência de Dados e Aprendizado de Máquina (Parte 04): Previsão de um crash no mercado de ações Ciência de Dados e Aprendizado de Máquina (Parte 04): Previsão de um crash no mercado de ações
Neste artigo, eu tentarei usar nosso modelo logístico para prever o crash do mercado de ações com base nos fundamentos da economia dos EUA, nos concentraremos nas ações do NETFLIX e da APPLE, usando os crashes anteriores do mercado de 2019 e 2020, vamos ver como nosso modelo se comportará nas atuais desgraças e tristezas.
Desenvolvimento de um sistema de negociação baseado no indicador Ichimoku Desenvolvimento de um sistema de negociação baseado no indicador Ichimoku
Neste artigo continuamos a série em que aprendemos a construir sistemas de negociação com base nos indicadores mais populares. Desta vez vamos falar sobre o indicador Ichimoku e criar um sistema de negociação baseado nos seus valores.
Funcionalidades do assistente MQL5 que você precisa conhecer (Parte 1): Análise de regressão Funcionalidades do assistente MQL5 que você precisa conhecer (Parte 1): Análise de regressão
O trader moderno está quase sempre procurando novas ideias, consciente ou inconscientemente. Ele está constantemente tentando novas estratégias, modificando-as e descartando aquelas que não funcionam. Este processo de pesquisa é demorado e propenso a erros. Nesta série de artigos, tentarei provar que o assistente MQL5 é um verdadeiro suporte para qualquer operador. Graças ao assistente, o trader economiza tempo ao implementar suas ideias. Também reduz a probabilidade de erros que ocorrem ao duplicar o código. Assim, em vez de perder tempo com codificação, os operadores colocam em prática sua filosofia de negociação.