preview
Do básico ao intermediário: Diretiva Include

Do básico ao intermediário: Diretiva Include

MetaTrader 5Exemplos | 5 setembro 2024, 11:09
220 0
CODE X
CODE X

Introdução

O conteúdo exposto aqui, visa e tem como objetivo, pura e simplesmente a didática. De modo algum deve ser encarado como uma aplicação final, onde o objetivo não seja o estudo dos conceitos aqui mostrados.

No artigo anterior Do básico ao intermediário: Comandos BREAK e CONTINUE, ficamos focados basicamente em entender como controlar o fluxo de execução dentro de laços que fazem uso dos comandos WHILE e do casal DO WHILE. No entanto, apesar de que eu esteja imaginando que você, meu caro leitor já deva estar preparado o suficiente para que o laço com o comando FOR, possa ser explicado. Aqui irei dar uma breve pausa no assunto sobre laços. Isto por que é bom dar um tempo, vendo outras coisas antes de que venhamos a prosseguir com mais comandos de controle de fluxo.

Assim, neste artigo de agora, vamos ver um assunto, que poderá lhe ajudar bastante. Pelo menos uma vez que ele tenha sido explicado, poderei começar a mostrar códigos um pouco mais elaborados. Visto, que até o presente momento, tem sido bem desafiador, para mim, criar códigos sem utilizar certos recursos que estão presentes no MQL5. Mesmo que alguns de você imaginem que tem sido fácil para mim. De fato, escrever códigos sem utilizar certos recursos. É algo bem desafiador. Mas agora vamos adicionar certas coisas a lista do que já poderá ser feito.

O recurso do qual estou me referindo são as diretivas de compilação. Sem estas diretivas, muito do que podemos fazer, fica bastante limitado. Nos forçando a escrever muito mais código do que seria de fato necessário em uma programação real.

As diretivas de compilação, diferente do que muitos podem pensar. Não torna o código mais confuso. Muito pelo contrário. O objetivo principal delas, é justamente o contrário. Ou seja, tornar o código mais simples, rápido e fácil de ser manuseado e modificado. O problema é que muitos iniciantes ignoram, ou não procuram aprender como utilizar de maneira adequada tal recurso. Talvez por que algumas linguagens de programação não possuem tal recurso em seu repertorio. Alguns exemplos de linguagem que não possuem diretivas de compilação, são o JavaScript e o Python. Que apesar de bastante populares entre programadores ocasionais, não são adequadas para se criar certos tipos de aplicação. Mas aqui, o objetivo, não é falar de tais linguagens e sim de MQL5. Então vamos começar o que será o primeiro tópico deste artigo.


Por que usar diretivas de compilação?

Apesar do fato de que as diretivas de compilação presentes no MQL5, serem bem adequadas para a maioria das vezes. Em alguns momentos sinto um pouco a falta de outras diretivas. Isto por que, o MQL5, essencialmente vem de uma modificação, muito bem elaborada do C / C++. No entanto, no C / C++ existem algumas diretivas que não estão presentes no MQL5. Uma destas diretivas é a #ifdef, que apesar de parecer pouco interessante, em alguns momentos nos ajuda muito a controlar certas partes da versão que estamos trabalhando.

No entanto, apesar desta diretiva não estar presente no MQL5. Pelo menos não até o momento que escrevo este artigo. A mesma não nos fará falta aqui. Apenas mencionei este fato, para que você, meu caro leitor, que talvez venha a se interessar futuramente em aprender C / C++, saiba que existem alguns detalhes que diferencia o C / C++ do MQL5. Mesmo que tudo, senão a maior parte, que venha a ser mostrado aqui, pode também ser usado como uma rampa de acesso ao C / C++.

Basicamente as diretivas de compilação servem para dois propósitos. Isto falando de maneira bem resumida. O primeiro proposito é o de direcionar a implementação para um modelo mais eficiente de código. O segundo proposito é permitir que você crie versões diferentes de um mesmo código, sem de fato apagar ou perder trechos anteriores.

Sei que para muitos de vocês, estas coisas podem parecer absurdo. Isto por que, programadores iniciantes, tem como habito, apagar um trecho de código, para tentar criar um novo trecho de código. Isto Tentando corrigir possíveis falhas ou melhorar a forma como certas fatorações estão sendo feitas.

Porém, toda via e, entretanto, este tipo de coisa somente precisa ser feita, em linguagens onde NÃO EXISTE as diretivas de compilação. Linguagens que permitem, e tem este tipo de recurso. Podem comportar diversas, mini versões de um mesmo código ao mesmo tempo. E a forma de selecionar entre uma versão e outra, é justamente fazendo uso das diretivas. De maneira inteligente e bem organizada.

Como parte desta organização, exige alguma experiência por parte do programador. Aqui, e neste exato momento, vamos começar, do princípio. Ou seja, estarei considerando que você, meu caro e estimador leitor, NÃO sabe absolutamente nada de como trabalhar, manusear e implementar um código fazendo uso de diretivas de compilação.

Porém conforme os próximos artigos vierem a serem postados. Irei aos poucos mostrar a você como ir agregando nossas atividades ligadas as diretivas de compilação. Muito provavelmente não irei criar um artigo, focado apenas neste tema específico. Este daqui, é apenas para introduzir sobre o assunto. De forma que você, consiga ter uma noção do que seria uma diretiva de compilação.

Muito bem, dada esta, que pode ser considerada uma introdução geral ao tema. Vamos começar vendo a diretiva mais comum em códigos MQL5. Mas para isto vamos a um novo tópico.


Diretiva #INCLUDE

Muito provavelmente esta será a diretiva de compilação, que você, meu caro leitor, mais irá ver em códigos. Principalmente códigos MQL5 e do estilo C / C++. E por que disto? O motivo, é que, grande parte, para não dizer todos programadores mais experientes. NÃO GOSTAM de colocar tudo em um único código. Normalmente, é isto com o tempo você entenderá. Programadores mais experientes, dividem seus códigos em pequenos blocos. Estes normalmente com o tempo, acabam configurando o que seria uma biblioteca de funções, procedimentos, estruturas e classes. Todos organizados de maneira completamente lógica. De forma, a tornar a programação, mesmo de códigos novos e inéditos, algo extremamente rápido de ser feito. Com uma quantidade mínima de modificações que precisam ser feitas. Isto a fim de tornar o código original, que o programador já tem a muito tempo catalogado, em um novo código.

E você ali digitando código a todo momento, para fazer sempre as mesmas coisas.

Mas organizar seus códigos, de modo a fazer uso desta diretiva, é algo que eu não irei lhe ensinar como fazer. Na verdade, NINGUÉM irá lhe ensinar como fazer isto. Já que este tipo de coisa, só faz sentido, quando aquele que irá manter tais códigos, faz uma seleção cuidadosa e meticulosa, de onde cada coisa irá ficar. Porém, apesar de não lhe ensinar como fazer isto. Posso lhe explicar, como acessar os códigos que você criou com tanto esmero e carinho. E este é o objetivo desta diretiva em particular. Permitir que você acesse as coisas de maneira bem natural e prática.

Aqui não existe um fluxo de execução. Apesar de que existem detalhes a serem observados. Mas iremos fazer isto aos poucos, para que tais detalhes, sejam compreendidos de maneira bastante natural por cada um de vocês.

Primeiramente, vamos pegar um dos códigos vistos nos artigos anteriores. Isto tornará mais natural o que será visto aqui. Para isto, vamos pegar e montar um pequeno código inicial. Este pode ser visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     ulong value;
07. 
08.     Print("Factorial of 5: ", Factorial(5));
09.     Print("Factorial of 3: ", Factorial(3));
10.     Print(One_Radian());
11.     do
12.     {
13.         value = Tic_Tac();
14.         Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", value);
15.     }while (value < 3);
16.     Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", Tic_Tac(true));
17.     Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", Tic_Tac());
18. }
19. //+------------------------------------------------------------------+
20. double One_Radian()
21. {
22.     return 180. / M_PI;
23. }
24. //+------------------------------------------------------------------+
25. ulong Tic_Tac(bool reset = false)
26. {
27.     static ulong Tic_Tac = 0;
28. 
29.     if (reset)
30.         Tic_Tac = 0;
31.     else
32.         Tic_Tac = Tic_Tac + 1;
33. 
34.     return Tic_Tac;
35. }
36. //+------------------------------------------------------------------+
37. ulong Factorial(uchar who)
38. {
39.     static uchar counter = 0;
40.     static ulong value = 1;
41. 
42.     if (who) who = who - 1;
43.     else
44.     {
45.         counter = 0;
46.         value = 1;
47.     }
48.     while (counter < who)
49.     {
50.         counter = counter + 1;
51.         value = value * counter;
52.     };
53.     while (counter > who)
54.     {
55.         value = value / counter;
56.         counter = counter - 1;
57.     };
58.     counter = counter + 1;
59.     return (value = value * counter);
60. }
61. //+------------------------------------------------------------------+

Código 01

Você meu caro leitor, deve obrigatoriamente conseguir entender este código 01. Isto é um pré-requisito, para podermos continuar daqui para frente. Se você não está conseguindo entender este código. Por favor, pare neste exato momento, e volte aos artigos anteriores. Pois este código daqui é muito simples. Não podendo de forma alguma, ser algo confuso, ou que você não consiga compreender.

Bem, quando executado, este código irá gerar a seguinte saída no terminal do MetaTrader 5.


Imagem 01

Algo que estamos fazendo apenas para verificar se ele de fato funciona. Como podemos claramente notar que ele funciona. Podemos começar a falar sobre como fazer uso da diretiva de compilação aqui. Talvez eu devesse ter iniciado com outra diretiva. Mas tudo bem, como a diretiva #include é muito mais requisitada que todas as demais. Não faz tanto sentido começar com outra. Então vamos em frente.

A primeira coisa que você precisa entender, isto antes de fazer qualquer outra coisa. É escolher como você irá dividir as coisas. Isto parece ser bobagem, mas não é. Se você não bolar uma maneira, que para você seja adequada, e perfeitamente utilizável. Com o tempo você acabará tendo sérios problemas para criar novos códigos. Mas se você bolar uma maneira que seja, para você, adequada. Você vai longe.

Como aqui, o objetivo é pura e simplesmente a didática. Iremos fazer o seguinte: Vamos dividir as coisas em três arquivos diferentes. Cada um irá conter uma função ou procedimento, que é visto originalmente neste código 01.

Com isto em mente, você logo pensa: Ok, vou criar os arquivos então. Mas este não é o segundo passo que você deverá dar meu caro leitor. Na verdade, existe um passo antes de fazer isto. O passo em questão, que é o segundo a ser dado. Você deverá responder: Qual será o diretório onde irei colocar os arquivos que serão criados? Espere um pouco aí. O diretório não deveria ser o diretório include? Esta é uma questão, muito mais pessoal do que qualquer outra. Isto porque, nem sempre o melhor lugar, será o diretório include. Se você não sabe do que estou falando. Basta ir até a pasta do MQL5, via MetaEditor. Conforme mostrado na imagem abaixo.


Imagem 02

Ao fazer isto, você irá ver uma pasta chamada de include, dentro do diretório MQL5. Este é o diretório padrão, para arquivos do tipo que estaremos criando. Que são mais conhecidos como arquivos de cabeçalho. Porém com eu disse a pouco, nem sempre esta é a melhor escolha. Dependendo do projeto, ou do objetivo que você está pretendo alcançar. Muitas das vezes colocar todos os seus arquivos de cabeçalho, dentro do diretório include, pode acabar lhe prejudicando. Isto por que, versões levemente diferentes de um mesmo procedimento ou função, pode entrar em conflito com outra versão. Que possivelmente, seria, ou deverá estar dentro desta pasta include.

Porém muitos podem questionar este tipo de coisa, da seguinte maneira: Poderíamos criar sub diretórios para melhor organizar estes nossos arquivos de cabeçalho. Sim, está de fato é uma das coisas mais comuns de serem feitas. No entanto, mesmo seguindo e utilizando este recurso de criar sub diretórios, dentro da pasta include. Em alguns momentos, não é adequado.

No entanto, antes que alguns comecem a ficar desesperados. Irei sim mostrar como você pode fazer isto, meu caro leitor. Isto com o intuito de organizar da melhor forma, seus próprios códigos. Como eu disse, ninguém pode lhe ensinar como fazer isto. Mas você sabendo como pode ser feito. Pode sim, criar sua própria organização.

Então vamos fazer uma coisa completamente diferente neste primeiro momento. Vamos criar um sub diretório dentro da pasta Scripts. Este irá conter cada uma das funções que foram vistas no código 01. Mas para separar adequadamente as coisas, vamos ver isto em tópico. Começando com o que é a solução número 1.


Solução número 1

A primeira solução de separação das funções vistas no código 01. É colocando cada uma em um arquivo de cabeçalho. Mas estes arquivos irão ficar em uma pasta dentro do diretório Scripts. Um detalhe importante. Procure sempre usar extensões MQH para os arquivos de cabeçalho que você criar. Desta forma, fica mais fácil, saber do que se trata, apenas observando o explorador de arquivos, do sistema operacional. Bem, dito isto, fazemos a divisão. E esta faz com que cada um dos arquivos fique com os seguintes conteúdo.

1. //+------------------------------------------------------------------+
2. #property copyright "Daniel Jose"
3. //+------------------------------------------------------------------+
4. double One_Radian()
5. {
6.     return 180. / M_PI;
7. }
8. //+------------------------------------------------------------------+

Arquivo 01

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. ulong Tic_Tac(bool reset = false)
05. {
06.     static ulong Tic_Tac = 0;
07. 
08.     if (reset)
09.         Tic_Tac = 0;
10.     else
11.         Tic_Tac = Tic_Tac + 1;
12. 
13.     return Tic_Tac;
14. }
15. //+------------------------------------------------------------------+

Arquivo 02

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. ulong Factorial(uchar who)
05. {
06.     static uchar counter = 0;
07.     static ulong value = 1;
08. 
09.     if (who) who = who - 1;
10.     else
11.     {
12.         counter = 0;
13.         value = 1;
14.     }
15.     while (counter < who)
16.     {
17.         counter = counter + 1;
18.         value = value * counter;
19.     };
20.     while (counter > who)
21.     {
22.         value = value / counter;
23.         counter = counter - 1;
24.     };
25.     counter = counter + 1;
26.     return (value = value * counter);
27. }
28. //+------------------------------------------------------------------+

Arquivo 03

Um detalhe importante. Uma vez feita esta divisão, a decisão de onde as coisas irão ficar, depende de você, assim como também os nomes de cada um dos arquivos. Não existe nenhum tipo de imposição aqui. Você é livre para fazer suas próprias escolhas.

Agora que os códigos foram removidos do código 01, e colocado em arquivo separados. Você terá como código, algo parecido com o mostrado logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     ulong value;
07. 
08.     Print("Factorial of 5: ", Factorial(5));
09.     Print("Factorial of 3: ", Factorial(3));
10.     Print(One_Radian());
11.     do
12.     {
13.         value = Tic_Tac();
14.         Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", value);
15.     }while (value < 3);
16.     Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", Tic_Tac(true));
17.     Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", Tic_Tac());
18. }
19. //+------------------------------------------------------------------+

Código 02

Legal, parece bem mais simples do que o visto lá no código 01. É verdade meu caro leitor. Porém, se você tentar compilar este código 02, irá ter uma enorme quantidade de erros sendo reportadas pelo compilador. Estes erros, que você pode observar na imagem abaixo, indicam que o compilador não conseguiu entender o código.


Imagem 03

Bem, na verdade, não é que o compilador, não entendeu o código. O problema é que o compilador, NÃO SABE como resolver as chamadas de procedimento e funções que aparecem no código. Mas como assim? Diferente do que muitos pensam ou imaginam que seja uma linguagem de programação. Existe na verdade duas coisas em uma linguagem de programação. A primeira é conhecida como biblioteca padrão. Esta biblioteca padrão é que define as funções, procedimentos, palavras reservadas, constantes entre outras coisas, que usamos para criar o que seria o código ao nível de usuário.

Você, como programador que utiliza uma linguagem qualquer, NÃO PODE mudar como a biblioteca padrão funciona. Mas pode usar o que está definido dentro dela para criar suas próprias soluções. Tudo que está na biblioteca padrão, pode ser utilizado, sem a necessidade de nenhuma outra operação especial. Porém qualquer coisa fora desta biblioteca, necessitará de ser adicionada de maneira explicita no código. Isto para que o compilador saiba como resolver cada uma das chamadas que vierem a surgir. Por isto, quando você tentar compilar o código 02, que apesar de parecer com o código 01. Você não consegue fazer isto.

Para conseguir fazer isto, você necessitará dizer ao compilador, quais arquivos deverão ser incluídos na compilação. Por isto a diretiva é chamada de diretiva de compilação. E tem um nome bastante sugestivo de #include. Ou seja, inclua tal coisa durante a compilação deste código aqui. Compreendeu meu caro leitor?

Se de fato você conseguiu compreender isto, irá conseguir fazer coisas, que antes você não conseguia. Mesmo tentando aprender programação, algumas coisas ficavam meio que sem ter um sentido claro e real. Mas iremos falar sobre isto em um outro momento. Já que não quero lhe deixar todo desorientado, lhe apresentando uma enorme quantidade de informações. Quero que você compreenda e assimile adequadamente o que está sendo explicado e mostrado em cada um destes meus artigos.

Ok, se o código 02, não pode ser compilado, justamente por que o compilador não sabe como acessar as informações necessárias. Como podemos resolver isto? Será que teríamos de ir até os arquivos que criamos a pouco. Copiar e depois colar cada uma das funções ou procedimentos, no código 02, a fim de fazê-lo voltar a se parecer com o código 01? Pois se o código 01 podia ser compilado, isto indicava que ele estava correto. Mas isto talvez não venha a fazer de fato sentido. Já vi outros códigos trabalhando e não havia necessidade de copiar e colar trechos inteiros dentro do código final. Agora fiquei curioso. Como resolver este problema? Esta é a parte fácil meu caro leitor. Basta que você crie algo parecido com o que é visto no código logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #include "Tutorial\File 01.mqh"
05. #include "Tutorial\File 02.mqh"
06. #include "Tutorial\File 03.mqh"
07. //+------------------------------------------------------------------+
08. void OnStart(void)
09. {
10.     ulong value;
11. 
12.     Print("Factorial of 5: ", Factorial(5));
13.     Print("Factorial of 3: ", Factorial(3));
14.     Print(One_Radian());
15.     do
16.     {
17.         value = Tic_Tac();
18.         Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", value);
19.     }while (value < 3);
20.     Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", Tic_Tac(true));
21.     Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", Tic_Tac());
22. }
23. //+------------------------------------------------------------------+

Código 03

Agora a parte interessante. Quando você tentar compilar este código 03, irá ter uma resposta parecida com a que pode ser observada logo abaixo.


Imagem 04

Ou seja, sucesso. Mas como? O motivo é justamente as linhas quatro, cinco e seis presentes neste código 03. Estas linhas podem estar em qualquer ponto do código. No entanto, por questões de organização, sempre, no normalmente as colocamos no começo do código. Existem situações em que elas podem aparecer em outros locais do código. Mas são situações bastante raras e por motivos muitos específicos. O que não vem ao caso no momento. No entanto, mesmo assim, é algo maravilhoso, o simples fato de poder colocar as coisas em um formato muito mais organizado e prático.

Porém existe uma questão aqui, e esta é muito importante que você compreenda. Pelo menos o básico da coisa. Em outros artigos iremos ver isto de uma maneira mais aprofundada. Que é justamente a forma que estamos declarando cada uma das diretivas #include presentes neste código 03.

Neste momento, não vou explicar isto, prefiro que você leia a documentação. Isto porque, se eu for explicar este tipo de coisa, neste exato momento, você não irá conseguir compreender por que de fazer assim, como está sendo feito neste código 03. E pior, você pode acabar ficando muito mais confuso, do que esclarecido sobre os motivos da declaração aparecer desta forma em alguns casos e de outra forma em outros casos.

Na documentação, você pode ver isto buscando em: Incluindo arquivos (#include). Mas quem já me acompanha a mais tempo, sabe perfeitamente que existe um motivo para a declaração das linhas quatro, cinco e seis, serem feitas como aparece no código 03.

De qualquer forma, quando você executar o código 03, irá ter o mesmo resultado que é mostrado na imagem 01. Agora vamos ao segundo tipo de solução. Mas para separar ela desta daqui, vamos a um novo tópico.


Solução número 2

Esta segunda solução, segue o princípio da usabilidade. Ou seja, você cria algo, de forma a expandir a própria capacidade do MQL5 em criar novos código, ou os criar de maneira mais rápida. Não é raro você ver, outros programadores, distribuindo arquivos de cabeçalho, que estão presentes na instalação do MetaTrader 5. Porém estes arquivos de cabeçalho se encontram modificados, de alguma maneira. Pessoalmente acho algo bastante válido, tais distribuições. Já que muitas das vezes, algumas destas modificações são bem interessantes. O problema, é onde você, meu caro leitor, as irá colocar.

Isto por que, de tempos em tempos, o MetaTrader 5, é atualizado. E se você tem um destes arquivos de cabeçalho modificado, mesmo que seja por você. E este é muito prático e se mostrou bastante útil para o que você gosta de desenvolver. É uma tremenda de uma bobagem, deixá-lo em qualquer lugar. Isto por que, se ele estiver dentro do diretório include, da pasta MQL5. Assim que o MetaTrader 5, atualizar seus dados, este arquivo poderá ser reescrito. Caso isto venha a correr. Pronto, você perdeu um excelente arquivo de cabeçalho.

No entanto, existe uma solução para isto, que é dar um novo nome para o arquivo de cabeçalho. Mas você também pode utilizar o que foi mostrado no tópico anterior. Em ambos casos irá funcionar. Porém, para o caso anterior, neste primeiro momento, você ficará restrito a algumas coisas. Como o fato de ser mais difícil acessar fora do diretório atual, os arquivos de cabeçalho que você criou. Não que isto seja impossível. Apenas é um pouco mais complicado, devido a algo que você precisará fazer.

Por conta justamente disto, quando queremos usar um mesmo arquivo de cabeçalho, em diversas aplicações completamente diferentes entre si. É preferível os colocar em um só local. No caso dentro do diretório include. Mas fique atendo, em sempre fazer um backup de tempos em tempos. De qualquer modo, o melhor é mesmo usar uma ferramenta de versionamento.

No caso sugiro usar o GIT, você pode saber mais sobre ele vendo este outro artigo meu GIT. Mas que coisa é esta?. Isto irá evitar muitas dores de cabeça e horas de sono perdido. Desde que você estude e passe a usar a ferramenta de forma adequada.

Mas vamos voltar a nossa questão. Podemos agora usando os mesmos arquivos mostrados no tópico anterior. E os colocar dentro do diretório include. Com isto poderemos utilizar duas versões diferentes do mesmo arquivo. Um que será facilmente acessível por qualquer aplicação que você queira criar. E uma outra, facilmente acessível para uma aplicação particular. Para tornar isto evidente e mostra que tal coisa é possível, vamos modificar um dos arquivos visto no tópico anterior. Na verdade, agora iremos ter duas versões dele. Uma acessível a princípio, apenas ao código que estamos criando aqui. E outro que poderá ser acessado por qualquer código que você deseje implementar. Este arquivo é visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. double One_Radian()
05. {
06.     return 180. / M_PI;
07. }
08. //+------------------------------------------------------------------+
09. double ToRadians(double angle)
10. {
11.     return angle / One_Radian();
12. }
13. //+------------------------------------------------------------------+
14. double ToDegrees(double angle)
15. {
16.     return angle * One_Radian();
17. }
18. //+------------------------------------------------------------------+

Arquivo 04

Aqui como estamos iniciando do básico, não vou mostrar certas coisas que podemos fazer. Apenas quero mostrar como você pode lidar com arquivo de cabeçalho. Assim sendo, agora temos dois arquivos, que contém duas versões idênticas de uma mesma função. No caso a função One_Radians. Apesar de neste instante ser algo simples e banal, podendo ser ignorado. Conforme formos aprofundando e mostrando novas coisas. Iremos ver que podemos tirar algum proveito deste tipo de coisa. Mas tudo ao seu devido tempo.

Porém agora queremos que este arquivo 04, seja utilizado no lugar do arquivo 01. Isto por que, nele temos outras funções que queremos utilizar. Devido justamente ao código visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #include "Tutorial\File 01.mqh"
05. #include "Tutorial\File 02.mqh"
06. #include "Tutorial\File 03.mqh"
07. //+------------------------------------------------------------------+
08. void OnStart(void)
09. {
10.     ulong value;
11. 
12.     Print("Factorial of 5: ", Factorial(5));
13.     Print("Factorial of 3: ", Factorial(3));
14.     Print(One_Radian());
15.     Print(ToRadians(90));
16.     do
17.     {
18.         value = Tic_Tac();
19.         Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", value);
20.     }while (value < 3);
21.     Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", Tic_Tac(true));
22.     Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", Tic_Tac());
23. }
24. //+------------------------------------------------------------------+

Código 04

Se você tentar compilar este código 04, irá ter como resultado a imagem vista logo abaixo.


Imagem 05

Provando que existe uma falha aqui. Mas resolver esta falha é algo simples. Mas que exige de você, como programador, um certo nível de atenção. Isto porque você pode estar trabalhando, com arquivos de cabeçalho, onde temos versões diferentes para uma função ou procedimento com um mesmo nome. E esta é a parte complicada, que você precisará dominar sozinho. Não existe como explicar ou lhe mostrar uma forma de lidar com isto. E o motivo é simples: Tudo depende de como você foi se organizando durante tempo. Fora esta questão, para o que estamos vendo aqui, sendo inicialmente um objetivo didático. A solução é bastante simples e direta. Pois na verdade, a falha reportada se deve justamente pela ausência da função que se encontra na linha 15. Como ela não existe, em nenhum dos arquivos de cabeçalho, que estão sendo incluído a no código 04. A compilação sempre irá falhar. Por isto, precisamos dizer ao compilador, onde está o arquivo correto, que contém o código que irá fazer com que a linha 15 funcione. Para tanto, basta que mudemos o código para o código 05 que pode ser observado na sequência.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #include <Tutorial\File 01.mqh>
05. #include "Tutorial\File 02.mqh"
06. #include "Tutorial\File 03.mqh"
07. //+------------------------------------------------------------------+
08. void OnStart(void)
09. {
10.     ulong value;
11. 
12.     Print("Factorial of 5: ", Factorial(5));
13.     Print("Factorial of 3: ", Factorial(3));
14.     Print(One_Radian());
15.     Print(ToRadians(90));
16.     do
17.     {
18.         value = Tic_Tac();
19.         Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", value);
20.     }while (value < 3);
21.     Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", Tic_Tac(true));
22.     Print(__FUNCTION__, " ", __LINE__, " Tic Tac: ", Tic_Tac());
23. }
24. //+------------------------------------------------------------------+

Código 05

Veja que aparentemente a mudança foi muito pequena. Porém, esta mudança está sendo pequena, de propósito. Servindo justamente, para mostrar a você, meu caro leitor, que é preciso de fato praticar e se dedicar a entender como as coisas funcionam na prática. Ao pedir para compilar este código 05, o resultado será o que é mostrado logo abaixo.


Imagem 06

Com isto, podemos notar que este arquivo que estamos incluindo na linha quatro. Estará na verdade, posicionado no diretório include. No anexo você poderá ver isto sendo mostrado. Assim poderá entender como as coisas devem ficar e serem organizadas na prática. Como última coisa a ser mostrada neste artigo. Vejamos o resultado da execução do código 05.


Imagem 07


Considerações finais

Neste artigo, vimos como utilizar uma das mais comuns diretivas de compilação. Apesar de termos focado apenas em uma única coisa. Não foi, ou melhor, não é possível explicar tudo que podemos fazer com esta diretiva em um único artigo. E mesmo se viermos a montar mais artigos, apenas para explicar esta diretiva. Ainda assim, não seria possível explicar certas coisas. Isto por que, muito do que tornar alguém realmente um bom programador, não é só o fato de saber organizar um código a fim de que ele gere algum resultado. Mas sim saber organizar a sua própria identidade como programador. Criando e catalogando em arquivos de cabeçalho, partes interessantes, e úteis de códigos, mais utilizados no seu dia a dia.

E aprender como fazer isto, não é algo que ninguém irá conseguir lhe ensinar. É algo que você de fato, somente irá aprender com a prática e com o tempo. Mas é preciso dar o primeiro passo. E este artigo visa, justamente lhe mostrar como dar este primeiro passo. Espero que ele venha a lhe ser útil meu caro leitor. E no próximo artigo, iremos tratar de um outro comando de controle de fluxo. Então não nos vemos lá.


Arquivos anexados |
Anexo.zip (3.94 KB)
Desenvolvendo um Trading System com base no Livro de Ofertas (Parte I): o indicador Desenvolvendo um Trading System com base no Livro de Ofertas (Parte I): o indicador
O livro de ofertas - Depth of Market - é sem dúvidas algo de bastante relevância para a execução de trades rápidos, sobretudo em algoritmos de alta frequência - os HFT. Nessa série de artigos, iremos explorar esse tipo de evento de mercado que podemos obeter através do broker em muitos dos ativos negociados. Começaremos com um indicador em que são configuráveis a paleta de cores, a posição e o tamanho do histograma a ser exibido diretamente no gráfico. Também abordaremos uma forma de gerar eventos BookEvent para fins de testes do indicador em condições específicas. Como possíveis temas a serem abordados nos artigos futuros estão o armazenamento dessas distribuições de preços e formas de usá-las no testador de estratégia.
Algoritmos de otimização populacional: Algoritmo Boids, ou algoritmo de comportamento de enxame (Boids Algorithm, Boids) Algoritmos de otimização populacional: Algoritmo Boids, ou algoritmo de comportamento de enxame (Boids Algorithm, Boids)
Neste artigo, estudaremos algoritmo Boids, baseado em exemplos únicos de comportamento de enxame de animais. O algoritmo Boids, por sua vez, serviu como base para a criação de uma classe inteira de algoritmos, agrupados sob o nome de "Inteligência de Enxame".
Algoritmo de otimização baseado em brainstorming — Brain Storm Optimization (Parte I): Clusterização Algoritmo de otimização baseado em brainstorming — Brain Storm Optimization (Parte I): Clusterização
Neste artigo, discutimos um método inovador de otimização chamado BSO (Brain Storm Optimization), inspirado na tempestade de ideias (brainstorming). Também abordamos um novo enfoque para resolver problemas de otimização multimodal que utiliza o BSO, permitindo encontrar várias soluções ótimas sem a necessidade de definir previamente o número de subpopulações. Além disso, analisamos os métodos de clusterização K-Means e K-Means++.
Desenvolvendo um EA multimoeda (Parte 7): Seleção de grupos considerando o período forward Desenvolvendo um EA multimoeda (Parte 7): Seleção de grupos considerando o período forward
Anteriormente, ao selecionar grupos de estratégias de trading para melhorar os resultados combinados, avaliamos os grupos apenas no mesmo período utilizado para a otimização dos EAs individuais. Vamos agora observar o que acontece ao aplicar a seleção no período forward.