Do básico ao intermediário: Recursos
Introdução
No artigo anterior Do básico ao intermediário: Sub Janelas (IV), vimos que nem tudo é como normalmente imaginamos antes de ver as coisas funcionando. Não é raro as pessoas imaginarem que já sabe de algo apenas por saber o básico da coisa. O que é um grande erro.
Contudo, antes de continuar a falar sobre sub janelas, precisamos dar uma pequena pausa e tratar de um outro assunto que é igualmente importante. Então devido a natureza do que será visto neste artigo, peço a você que procure focar o máximo possível no que estará sendo explorado. Pois o mal entendimento deste conteúdo irá com toda a certeza lhe trazer sérios problemas no futuro.
O que iremos ver aqui neste artigo, é algo que permite que você construa aplicações, que outrora necessitaria que você as distribui-se como uma coleção de diversos arquivos. O que fatalmente gera alguns transtornos, como sendo apenas e somente um único arquivo executável. De manutenção muito mais simples e fácil.
Recursos
Um dos conceitos mais difíceis, para um iniciante conseguir compreender, é o chamado recursos. Isto falando em termos de código, e não de hardware. E o motivo para isto é que recurso, não faz nenhum sentido quando o apresentamos assim, de uma hora para outra. E faz ainda menos sentido, quando ele é explicado de maneira superficial e totalmente atropelada, como boa parte normalmente costuma fazer.
Para entender de maneira adequada este assunto, precisamos antes entender diversos outros conceitos. Tais conceitos foram apresentados naqueles que são os artigos anteriores. Então se você estiver com dificuldade em entender algum detalhe específico, procure ler os artigos anteriores.
Um recurso, em tese, é algo simples de entender. Já que tudo que você utiliza dentro de um programa, e para executar o próprio programa, é considerado como sendo um recurso. O conceito básico é justamente este. Porém, como programador, existem detalhes que precisam ser melhor entendidos. Isto a fim de que novas coisas possam ser incluídas dentro de um programa finalizado.
Para começar existem dois tipos básicos de recursos, isto quando o assunto está relacionado a questão do software. O primeiro tipo são recursos internos de um código, e o segundo são recursos externos deste mesmo código. Um recurso interno, seria qualquer coisa que estaria presente dentro de um executável. Já o recurso externo seria algo que o seu programa deverá procurar em algum local fora da região da memória, onde o próprio executável se encontra. Entender esta distinção, de forma adequada, é justamente a parte confusa. Isto no início. Isto por que, muitos iniciantes, ficam bem atordoados quando observam um executável fazer coisas sem aparentemente precisar de nenhum arquivo ou informação exterior. Enquanto outro, precisa de uma série enorme de informações, contidas em diferentes localizações e nos mais diversos tipos de arquivos externos.
Assim sendo, muitos destes iniciantes, imaginam que um ou outro código, que gera o mesmo tipo de resultado, é melhor ou pior. Porém, bem lá no fundo, a diferença entre uma abordagem e outra, fica a cargo de quem projetou o sistema para ser executado. Sendo mais adequado utilizar uma ou outra abordagem, dependendo do caso. Mas existem ainda uma outra questão, e esta talvez seja realmente o ponto principal, que faz um ou outro modelo ser o escolhido no final das contas. E é aqui que as coisas começam a ficar interessantes. Já que esta questão tem a ver com futuras atualizações da própria aplicação que você estará construindo.
Muito provavelmente você deve estar achando este assunto um tanto quanto chato e sem muita importância. Contudo, este assunto é de extrema importância, quando você se depara com alguns tipos específicos de problema. Vamos supor que você queira criar um Expert Advisor que venha a fazer operações automáticas utilizando algum tipo de indicador. Muitos de vocês podem até ficar imaginando que a única maneira de se criar tal coisa, seria criando dois ou mais executáveis. Um que seria o próprio Expert Advisor e um ou mais executáveis que seriam os indicadores a serem utilizados de fato. A principio, esta seria a maneira correta e a mais adequada de se fazer este tipo de coisa. Porém, toda via e, entretanto, quando você decidir que irá distribuir este seu sistema, você de depara com um pequeno problema. Como garantir que o usuário não irá remover o indicador que o Expert Advisor irá utilizar?
Bem, a maneira de se evitar isto, seria tornando tudo um único arquivo, que no caso seria o próprio arquivo do Expert Advisor. Mas espere um pouco. Você não disse que o Expert Advisor necessitaria de indicadores? Sim, ele irá necessitar dos indicadores que você irá construir. Então como o Expert Advisor irá funcionar, se não estamos distribuindo os tais indicadores? Bem, é neste ponto que a coisa começará a fazer sentido, para você, meu amigo leitor. Existe uma forma de você embutir os indicadores, ou qualquer outra coisa, dentro do executável do Expert Advisor. Assim tanto o usuário, como também o operador não poderão fazer mal ao tipo de análise que o Expert Advisor de fato foi projetado para executar. Já que o operador ou usuário não saberia em princípio da existência de tais indicadores que estariam sendo utilizados.
Digo a princípio, pois pode ser que você os queira sendo plotados no gráfico. Neste caso o usuário os irá ver, não entendendo por que quando aquele Expert Advisor é jogado no gráfico, tais linhas começam a ser plotadas. E quando o Expert Advisor é removido, as mesmas linhas desaparecem do gráfico, junto com o Expert Advisor.
Mas mesmo que os indicadores não venham a ser plotados no gráfico, como foi visto em artigos anteriores. Ele ainda assim estará visível na lista de indicadores. Contudo, o usuário ou operador não conseguirão entender de onde aquele, ou aqueles indicadores vieram. Pois eles simplesmente surgem e somem, toda a vez que o tal Expert Advisor é colocado ou removido do gráfico.
Hum, isto agora me pareceu ser algo bastante interessante. Então ao invés de enviar um monte de arquivos para um colega, tudo que preciso é enviar um único arquivo. E dentro dele estará toda uma configuração pre programada do que será feito. Gostei da ideia.
De fato, o princípio básico seria justamente este. Porém ele não se limita a fazer somente isto. Podemos tanto incluir dados que não poderão ser modificados, como também podemos incluir dados que podem ser modificados. E tudo isto dentro de uma série de critérios que você, como programador irá definir previamente, como sendo algo que pode ou não ser modificado por este ou aquele usuário. E caso o operador ou usuário venha a gerar uma falha na configuração, e lhe peça ajuda para corrigir as tais falhas. Tudo que você precisará dizer a ele é: Desinstale o programa, apagando todos os arquivos de configuração e logo depois volte a instalar o programa. Ao fazer isto, tudo voltará ao normal. Apesar do usuário, a princípio não gostar da ideia, isto irá lhe servir de lição para que na próxima vez tome mais cuidado ao mexer nas configurações. Ou no mínimo ser menos xereta, e não mexer onde não deveria. :-)
Ok, agora que o conceito foi devidamente apresentado, podemos pensar em como começar a fazer as coisas usando este conceito conhecido como recurso. Para começar, esqueça o fato de que você estará trabalhando com um ou mais arquivos. Trabalhar com recursos, envolve paciência e disciplina. Sem isto, todo seu código irá se tornar uma verdadeira bagunça. Na própria documentação do MQL5, você pode ter uma certa noção de com recursos podem ser trabalhados. Porém, o que se encontra ali, é algo bem superficial. E mesmo este artigo, ainda assim, não será o suficiente para mostrar tudo que podemos de fato fazer. Mas conforme novos artigos forem sendo publicados, você irá ver que este negócio é realmente muito legal e bastante divertido de ser utilizado.
Sendo assim, vamos começar com um exemplo bem simples, apenas para que você entenda como isto irá ser codificado na prática. O exemplo em questão, envolve dois arquivos. O primeiro será um arquivo de texto, e não se preocupe com o conteúdo do arquivo. Apenas procure entender como o conceito de recurso, estará sendo aplicado aqui. O arquivo de texto é mostrado logo abaixo.
Imagem 01
Nesta imagem 01 temos destacado em verde o nome e a localização do arquivo de texto. Já em amarelo temos exatamente o conteúdo do tal arquivo de texto. Bem, mas o que iremos fazer com isto? Calma, mantenha o foco e preste atenção. Agora vem a parte que deverá ser feita dentro do MQL5. Esta é mostrada logo abaixo.01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #resource "MyFile.txt" as string Antoine; 05. //+------------------------------------------------------------------+ 06. void OnStart(void) 07. { 08. Print(Antoine); 09. } 10. //+------------------------------------------------------------------+
Código 01
Quando este código for executado no terminal do MetaTrader 5, você irá ver como resultado o que é mostrado na animação logo abaixo.

Animação 01
Agora note que a região demarcada em amarelo na imagem 01, está sendo replicada no terminal. No entanto, aqui está acontecendo uma coisa que você talvez não esteja entendendo. Ou possivelmente esteja imaginando que está sendo feita uma coisa quando na verdade está sendo feita outra, totalmente diferente. Então preste muita atenção ao que irei explicar. Pois não irei repetir isto novamente no futura quando formos utilizar este tipo de modelagem.
Este código 01, quando compilado, irá na linha quatro pegar todo o conteúdo presente no arquivo mostrado na imagem 01 e o embutir dentro do executável. Agora pense no seguinte: Para o executável, o que esta linha quatro contém, é um array gigante com todo o conteúdo que antes estava presente dentro do arquivo MyFile.txt. A partir de agora todo aquele conteúdo estará presente dentro deste array. Porém para simplificar as coisas, estamos usando o tipo string como forma de categorizar as informações, dentro desta constante gigante que recebe o nome de Antoine. Retornando ao que você certamente já conhece e sabe interpretar, o que estamos fazendo neste código 01 seria o equivalente mostrado no código 02, visto logo abaixo.01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. const string Antoine = 05. "E foi então que apareceu a raposa:\n\r" \ 06. "- Boa dia, disse a raposa.\n\r" \ 07. "- Bom dia, respondeu polidamente o principezinho, que se voltou, mas não viu nada.\n\r"\ 08. "- Eu estou aqui, disse a voz, debaixo da macieira…\n\r" \ 09. "- Quem és tu? perguntou o principezinho. Tu és bem bonita…\n\r" \ 10. "- Sou uma raposa, disse a raposa.\n\r" \ 11. "- Vem brincar comigo, propôs o principezinho. Estou tão triste…\n\r" \ 12. "- Eu não posso brincar contigo, disse a raposa.\n\r"; 13. //+------------------------------------------------------------------+ 14. void OnStart(void) 15. { 16. Print(Antoine); 17. } 18. //+------------------------------------------------------------------+
Código 02
Hum, não entendi. Como assim? Ao meu ver este código 01 é muito mais simples e com muito menos coisas para nos preocupar do que este código 02. E mesmo assim, você me diz que o código 01 é equivalente a este código 02? Isto ao meu ver não faz o menor sentido.
Justamente por conta disto, que esperei todo este tempo para poder explicar sobre este assunto. A princípio este tipo de coisa parece não faz o menor sentido. E olha que estamos apenas no início do que realmente podemos fazer. Porém entender este início de maneira correta e adequada é realmente muito importante. E entender tudo que foi explicado nos artigos anteriores, também se faz importante agora. Pois a coisa toda irá ficar cada vez mais confusa, conforme começarmos a adicionar novas informações aqui. No entanto, por mais estranho que possa parecer, o que de fato está ocorrendo é que a linha quatro do código 01 está na verdade criando o que seria a linha quatro do código 02. Porém, é esta é a parte legal de tudo isto. É muito mais fácil entender o código 01 do que entender o código 02. Ainda mais se o objetivo viesse a ser o de colocar alguma informação mais complexa dentro do executável.
Então preste atenção, pois entender isto é importante. Podemos colocar qualquer tipo de informação dentro do executável. Qualquer tipo mesmo, desde informação que pode ser executada pelo MetaTrader 5, até coisas como imagens, sons ou algo que você precise ou queira colocar ali. E este tipo de coisa é que são os tais recursos de software.
Espere um pouco. Você está me dizendo que podemos colocar um executável, dentro de um outro, utilizando para isto, este sistema que acabamos de ver? Mas isto não vai funcionar. Pelo menos não consigo ver uma forma de fazer isto funcionar. Já que a princípio o fato de colocar algo dentro de um indicador, script ou Expert Advisor, não necessariamente tornará a coisa um objeto executável. Pelo menos é assim que imagino que venha a ser.
Pois bem, então já que você ainda é um inocente neste mundo, e não sabe de certas malandragens que podemos fazer como programadores. Chegou a hora de perder esta inocência e ver que o mundo não é um mar de rosas, onde tudo é lindo e maravilhoso. E todos queremos o bem uns dos outros. Pois na realidade não é bem assim que as coisas funcionam.
Para entender o que iremos começar a fazer, será preciso voltar ao artigo anterior. Lá foi mostrado como poderíamos fazer com que um indicador carregasse um outro indicador para o gráfico. Ao fazermos isto, seriamos capazes de modificar ou controlar algo no gráfico. Agora note o seguinte: Para que o sistema não viesse a falhar, seria necessário que ambos os códigos estivessem sido compilados e estivessem na sua devida localização. Isto é fato e se você estudou o que foi mostrado ali, sabe bem do que estou falando. Porém, toda via e, entretanto, nem sempre queremos que as coisas sejam feitas daquela maneira. Já que isto acabaria tornando o próprio sistema bem menos estável no que diz respeito a presença ou não dos executáveis. Acabando assim tornando a experiência do usuário final, algo consideravelmente bastante desagradável. Mas e se fosse utilizado este conceito visto neste artigo? Como as coisas de fato iriam ficar? Bem, para responder esta pergunta, vamos retornar ao que foi visto anteriormente.
Ok, originalmente os códigos vistos lá naquele artigo, estão sendo replicados logo abaixo.01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #property description "DEMO Indicator" 05. //+------------------------------------------------------------------+ 06. #property indicator_separate_window 07. #property indicator_height 50 08. #property indicator_plots 0 09. //+------------------------------------------------------------------+ 10. int OnInit(void) 11. { 12. IndicatorSetString(INDICATOR_SHORTNAME, "Test 123."); 13. 14. return INIT_SUCCEEDED; 15. }; 16. //+------------------------------------------------------------------+ 17. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 18. { 19. return rates_total; 20. }; 21. //+------------------------------------------------------------------+
Código 03
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #property description "DEMO Indicator" 05. //+------------------------------------------------------------------+ 06. #property indicator_chart_window 07. #property indicator_plots 0 08. //+------------------------------------------------------------------+ 09. int OnInit(void) 10. { 11. IndicatorSetString(INDICATOR_SHORTNAME, "Test 456."); 12. ChartIndicatorAdd(0, (int)ChartGetInteger(0, CHART_WINDOWS_TOTAL), iCustom(NULL, NULL, "Tutor\\Code 01")); 13. 14. return INIT_SUCCEEDED; 15. }; 16. //+------------------------------------------------------------------+ 17. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 18. { 19. return rates_total; 20. }; 21. //+------------------------------------------------------------------+
Código 04
Muito bem, a ideia aqui é que este código 04 carregue e passe a executar o indicador visto no código 03. Até aí, acredito que todos tenham entendido o que está acontecendo. Observe que na linha doze deste código 04 é justamente o ponto onde o carregamento irá se dar. E ali indicamos o nome e a localização do arquivo a ser utilizado. Agora preste muita atenção aos detalhes, pois o diabo mora nos detalhes.
O primeiro detalhe a ser observado é a localização do próprio executável que iremos embutir dentro do outro que estaremos criando. Muita atenção neste ponto. Pois sem entender isto, você acabará dando um nó cego no cérebro. Na linha doze do código 04 estamos indicando a localização do executável. Porém, quando vamos usar ele como recurso, precisamos indicar a localização, de forma relativa e não de forma absoluta. Hum, que história é esta de localização relativa e absoluta? Nunca ouvi falar disto em lugar algum. Bem, meu caro leitor, a posição absoluta é usada pelo MetaTrader 5 para acessar certos arquivos dentro da SandBox.No artigo Do básico ao intermediário: Navegando na SandBox falamos sobre esta coisa da SandBox, para mais detalhes veja o mesmo. Quando você utiliza o acesso absoluto, precisa indicar isto se baseando na própria SandBox. No entanto, para o compilador, a SandBox não é de fato usada da mesma maneira que é usada pelo MetaTrader 5. Para simplificar a explicação, pense no seguinte: O MetaTrader 5 enxerga o executável partindo de uma posição dentro da raiz da SandBox. Já o compilador observa o código de sua posição original, independentemente da posição que ele se encontre dentro da SandBox.
Cara este negócio de SandBox, posição relativa e posição absoluta, parece muito confuso. Não tem como resumir isto tornando este assunto mais simples de entender? Infelizmente não tem como. Você de fato precisa entender esta questão antes de tentar entender como o código 04 será modificado. Então, voltando a explicação. Sabemos que o código 03 SE ENCONTRA NO MESMO DIRETÓRIO do código 04. Esta informação é muito importante para nós durante a compilação e integração. Se o código 03 estivesse em outro diretório, precisaríamos dizer isto ao compilador, criando todo um caminho com de forma a dizer ao compilador onde o código 03 estaria. Sem esta informação o compilador NÃO CONSEGUIRÁ tornar o código 03 um recurso dentro do código 04.
Ok, entendido isto, a primeira mudança a ser feita é a criação de uma definição. Isto por que, não queremos ter o trabalho de indicar um local durante a integração e no momento de usar o recurso estarmos chamando de um outro local. Sendo assim a primeira mudança prática é vista logo abaixo.01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #property description "DEMO Indicator" 05. //+------------------------------------------------------------------+ 06. #property indicator_chart_window 07. #property indicator_plots 0 08. //+------------------------------------------------------------------+ 09. #define def_Resource "Code 01.ex5" 10. //+------------------------------------------------------------------+ 11. int OnInit(void) 12. { 13. IndicatorSetString(INDICATOR_SHORTNAME, "Test 456."); 14. ChartIndicatorAdd(0, (int)ChartGetInteger(0, CHART_WINDOWS_TOTAL), iCustom(NULL, NULL, "Tutor\\Code 01")); 15. 16. return INIT_SUCCEEDED; 17. }; 18. //+------------------------------------------------------------------+ 19. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 20. { 21. return rates_total; 22. }; 23. //+------------------------------------------------------------------+
Código 05
A única modificação que fizemos aqui, foi adicionar a linha nove a este código 05. Então não se esqueça:
O indicador visto no código 03 ESTÁ NO MESMO DIRETÓRIO deste código que iremos criar.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #property description "DEMO Indicator" 05. //+------------------------------------------------------------------+ 06. #property indicator_chart_window 07. #property indicator_plots 0 08. //+------------------------------------------------------------------+ 09. #define def_Resource "Code 01.ex5" 10. //+------------------------------------------------------------------+ 11. #resource def_Resource 12. //+------------------------------------------------------------------+ 13. int OnInit(void) 14. { 15. IndicatorSetString(INDICATOR_SHORTNAME, "Test 456."); 16. ChartIndicatorAdd(0, (int)ChartGetInteger(0, CHART_WINDOWS_TOTAL), iCustom(NULL, NULL, "Tutor\\Code 01")); 17. 18. return INIT_SUCCEEDED; 19. }; 20. //+------------------------------------------------------------------+ 21. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 22. { 23. return rates_total; 24. }; 25. //+------------------------------------------------------------------+
Código 06
Agora temos algo realmente interessante acontecendo. Isto pelo simples fato de termos adicionado esta linha onze ao código que é visto logo acima. O que esta linha onze faz, é integrar o código que estamos definindo na linha nove, a este código 06, tornando assim ele um recurso do código 06. Mas não é somente isto. A coisa em si é muito, mas muito mais interessante. Então vamos por partes, pois existe um macete aqui que futuramente irei explicar como contornar, que mata muita gente de raiva. Isto quando você está fazendo a integração de um executável dentro de outro executável.
No artigo anterior, menciono que para o indicador visto no código 03 seja colocado no gráfico. Precisamos garantir que ele tenha sido compilado e que esteja disponível para ser executado. Isto é fato. Agora quando você for compilar este código 06, algo mágico irá acontecer. Isto por que, SE o executável NÃO EXISTIR, o compilador irá criar o executável do código definido na linha nove. Hã? Mas como assim? Que coisa mais maluca é esta? Você está me dizendo que só de termos o código e tentarmos compilar um código que necessite do executável, o compilador irá criar ele para nós? Sim, é isto mesmo que irá acontecer. A mensagem disparada pelo compilador é um tanto quanto grande. E como temos um limite para a largura de imagens, a mesma não será mostrada por inteiro. Porém a parte que nos interessa pode ser vista em destaque logo abaixo.
Imagem 02
Nesta mensagem o compilador está nos informando que não encontrou o executável, e que está tentando compilar o mesmo. Como ele conseguiu fazer isto, temos a mensagem vista na segunda linha da imagem 02. Se tivesse ocorrido uma falha a mensagem seria outra, como mostrado logo abaixo.
Imagem 03
Note que agora o compilador informa que existe um erro na compilação. Mas o erro é devido justamente ao fato de que o compilador, NÃO CONSEGUIU compilar o código que é necessário para resolver a dependência da linha onze. Ou seja, justamente a linha onde a integração iria ocorrer. Isto pode ser por conta de que o código que precisa ser integrado contém algum erro, ou por conta de alguma falha na localização relativa do próprio código a ser integrado. De qualquer modo, o executável final não será criado, isto até que você venha a corrigir a falha que está impendido que a integração venha a ocorrer.
Acho que estou conseguindo entender. Mas e se o executável que será integrado já exista? Será que o compilador irá refazer a compilação novamente? Bem, neste caso não irá ocorrer uma nova compilação. Mesmo que o código tenha sido modificado, o compilador continuará a usar o código compilado anteriormente. Por isto é bom ficar atento ao que você está fazendo, caso contrário você poderá modificar o código a ser integrado e ao executar ele, notará que ele está funcionando como uma versão mais antiga.
De qualquer forma é bom você observar atentamente as mensagens disparadas pelo compilador. No caso de o executável que será integrado já existir, teremos um resultado como o que é mostrado na imagem logo na sequência.
Imagem 04
Note que esta imagem 04 se parece bastante com o que seria visto se você por ventura viesse a compilar o código 04. Porém, o resultado final, será ou poderá ser bem diferente do obtido durante a execução. Mas vamos deixar para entrar em mais detalhes sobre isto em outro momento. Já que este tipo de coisa toma tempo e quero mostrar ainda dentro deste artigo, como a integração será resolvida em tempo de execução. Pois até agora apenas criamos os códigos e os integramos como sendo recursos um do outro. Então chegou a hora de ver como tornar isto algo realmente executável.
Agora vem a segunda parte, que pode ser bem confusa. Para que o código funcione, precisamos fazer uma manobra. Esta manobra se baseia no uso de um operador especial, mas que precisa ser passado de uma maneira muito especifica para dentro do código. O tal operador é usado para resolver escopo dentro do próprio código. Cara este negócio está ficando cada vez mais confuso e complicado. O que é isto de operador de escopo? Bem, você pode ler um pouco sobre isto, na própria documentação do mql5 neste local. Me desculpe por não usar um nome mais adequado.
Mas a própria documentação mostra apenas o básico sobre este operador de resolução de escopo. Mas o que realmente nos interessa, aqui e de agora em diante, é saber que precisamos de alguma forma dizer ao nosso novo código, como fazer para executar o código que está integrado dentro dele. Ou seja, precisamos fazer com que a linha dezesseis do código 06, execute o código que agora é um recurso interno do executável que acabamos de criar. E não mais procure executar aquele código externo, como fazia antes e ainda está fazendo devido justamente a forma como a linha dezesseis ainda está escrita.
Certo, acho que estou entendendo onde você quer chegar. Mas agora lhe pergunto: Como iremos fazer isto? Pois, ao meu ver não temos nenhum meio de acessar este recurso que está sendo integrado ao executável, na linha onze deste código 06. E mais do que isto. Dei uma olhada na documentação a respeito de como utilizar um código como recurso, e lá é mostrado algo completamente diferente disto que você está fazendo neste código 06. Então para mim, apesar de esta integração está ocorrendo, ela de fato não tornará o código integrado realmente funcional. A não ser que você tenha uma carta na manga que permita fazer isto. Mas neste caso não faço a menor ideia de como tal truque venha a funcionar.
Pois bem, neste momento não irei entrar em muitos detalhes do motivo pelo qual este tipo de coisa que será feita funciona. Mas lhe garanto que a única coisa que precisaremos e iremos fazer, será o de modificar a linha dezesseis do código 06, para algo como é visto, na mesma linha, no código logo abaixo.01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #property description "DEMO Indicator" 05. //+------------------------------------------------------------------+ 06. #property indicator_chart_window 07. #property indicator_plots 0 08. //+------------------------------------------------------------------+ 09. #define def_Resource "Code 01.ex5" 10. //+------------------------------------------------------------------+ 11. #resource def_Resource 12. //+------------------------------------------------------------------+ 13. int OnInit(void) 14. { 15. IndicatorSetString(INDICATOR_SHORTNAME, "Test 456."); 16. ChartIndicatorAdd(0, (int)ChartGetInteger(0, CHART_WINDOWS_TOTAL), iCustom(NULL, NULL, "::" + def_Resource)); 17. 18. return INIT_SUCCEEDED; 19. }; 20. //+------------------------------------------------------------------+ 21. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 22. { 23. return rates_total; 24. }; 25. //+------------------------------------------------------------------+
Código 07
Ao fazermos esta singela mudança, teremos finalmente conseguido criar algo realmente interessante. E apesar de você imaginar que ainda assim, precisaremos do executável criado do código 03 visto neste artigo. Este mesmo executável poderá ser deletado logo depois que este código 07 tiver sido compilado. Na verdade, até aconselho você deletar o mesmo logo em seguida e o motivo será explicado em outro artigo. Mas de qualquer maneira, este código 07, irá fazer com que o indicador integrado do executável final, seja perfeitamente funcional. Isto por que, o próprio indicador visto no código 03, agora faz parte do código 07, podendo assim apenas o executável deste código 07, ser transferido e compartilhado com seus amigos e colegas. Sem que eles de fato venham a precisar se preocupar com a presença ou não do executável visto no código 03.
Ok, agora executando este código 07, você irá ver o que é mostrado na animação logo abaixo.
Animação 02
Hum, não vejo nada demais acontecendo aqui. Este tipo de comportamento já era conseguido anteriormente. E ainda assim, não tenho certeza se você está ou não tentando me enganar com esta história de que está conseguindo integrar e executar o código diretamente apenas por conta que mudou a linha dezesseis. Por mim, você está é brincadeira. Não tem como esta linha dezesseis do código 07, de fato executar o indicador integrado ao executável.
Legal, temos um incrédulo entre nós. Pois vamos verificar se o código 07 está ou não está conseguindo fazer o que foi dito aqui. Para isto, bastará abrirmos a lista de indicadores presentes no gráfico e checar o que estará sendo informado ali. Ao fazermos isto, será visto algo parecido com a imagem logo abaixo.
Imagem 05
Note que estou destacando algo nesta imagem. E então, você agora está convencido do fato do código 07, realmente conseguir executar o indicador integrado a ele? Bem, de qualquer maneira, o ideal é que você veja com seus próprios olhos e ateste o que foi demonstrado aqui.
Considerações finais
Neste artigo você foi apresentado a um conceito que pode ser de extrema utilidade em muitos casos. Facilitando em muito o compartilhamento de suas aplicações e projetos. Apesar de não ser um conceito muito simples de ser totalmente explicando em apenas um único artigo. O que foi explicado e exposto aqui, já nos irá permitir fazer diversas outras coisas no futuro próximo. Inclusive algumas que de outra maneira não seriam possíveis de serem feitas. Justamente por que este artigo ainda não havia sido publicado, para que você, pudesse ter um material de apoio e uma base inicial de estudo.
Com isto, minha dica é: Estude com calma este conceito explicado aqui. Conforme novos artigos forem sendo escritos, você irá notar que entender o que foi explicado aqui, irá lhe ajudar imensamente a ter um bom entendimento e assimilar melhor os próximos conteúdo. Então use e abuse dos códigos que estarão no anexo e nos vemos no próximo artigo.| Arquivo MQ5 | Descrição |
|---|---|
| Indicators\Code 01 | Demonstração básica |
| Indicators\Code 02 | Demonstração básica |
| Indicators\Code 03 | Demonstração básica |
| Scripts\Code 01 | Demonstração básica |
| Scripts\Code 02 | Demonstração básica |
| Scripts\MyFile.txt | Arquivo exemplo simples |
Aviso: Todos os direitos sobre esses materiais pertencem à MetaQuotes Ltd. É proibida a reimpressão total ou parcial.
Esse artigo foi escrito por um usuário do site e reflete seu ponto de vista pessoal. A MetaQuotes Ltd. não se responsabiliza pela precisão das informações apresentadas nem pelas possíveis consequências decorrentes do uso das soluções, estratégias ou recomendações descritas.
Caminhe em novos trilhos: Personalize indicadores no MQL5
Símbolos personalizados em MQL5: Criando um símbolo customizado de barras 3D
Está chegando o novo MetaTrader 5 e MQL5
Introdução ao MQL5 (Parte 13): Um Guia para Iniciantes na Construção de Indicadores Personalizados (II)
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso