Download MetaTrader 5

Programação baseada em autômatos como nova abordagem para criação de sistemas de negociação automatizados

4 março 2014, 09:51
GOURO
0
1 188

ἓν οἶδα ὅτι οὐδὲν οἶδα ( ο φιλόσοφος Σωκράτης )

Só sei que nada sei (Sócrates, o filósofo )


Introdução

Para começar, este assunto é completamente novo para negociadores que desenvolvem EAs utilizando a linguagem MetaQuotes 4/5 (MQL4/5). Eu pude constatar isso por conta própria quando tentei realizar uma pesquisa relevante no website da MetaQuotes. Não há nada sobre o assunto.

Cada negociador cria o seu próprio Expert Advisor, o qual requer uma abordagem séria para solucionar todos os tipos de problemas associados à programação e a uma lógica de programa muito complicada. No final das contas, o programa deveria funcionar INDEPENDENTEMENTE, como um relógio, em qualquer situação padrão e de força maior.

Mas como é possível abranger tudo? Isso é extremamente difícil e é por essa razão que os sistemas de controle automático requerem programação adequada de todos os sistemas de controle, o que pode ser melhor alcançado apenas com a utilização da tecnologia adequada da programação baseada em autômatos. Em anos recentes, o desenvolvimento de tecnologias de programação para sistemas integrados e de tempo real que estabelecem altos requisitos à qualidade do software tem recebido grande atenção.

Em 1991, o autor russo A.A. Shalyto (palestrante, professor, DSc em engenharia, chefe do departamento de tecnologias de programação na SPbSU ITMO) desenvolveu uma tecnologia de programação que ele denominou "programação baseada em autômatos". Acredito que os leitores possam achar interessante saber o quão simples pode ser a programação baseada em autômatos ou a tecnologia SWITCH. Ela possibilita o desenvolvimento de MTS utilizando a linguagem MetaQuotes de forma tão conveniente que simplesmente não poderia ser melhor. E ela é integrada perfeitamente ao sistema complexo de tomada de decisões.


1. Chegando ao problema

O desejo estimado e querido de todos os criadores de problemas e desenvolvedores de software é ter uma solução planejada para o problema (algoritmo) e uma implementação do algoritmo que seja totalmente consistente com ela. Mas parece que as coisas não funcionam assim para criadores e desenvolvedores. Os algoritmos tendem a deixar de fora o que os desenvolvedores consideram importante para implementação, enquanto que o texto do programa em si é pouco semelhante ao algoritmo.

Assim, há dois algoritmos - um em papel (para registro e documentação de soluções de projeto), o que geralmente representa um determinado resultado de projeto em vez de métodos empregados para a sua obtenção, enquanto que o segundo algoritmo está na mente do desenvolvedor (o qual também é, entretanto, salvo textualmente).

A versão final do texto do programa é geralmente seguida por tentativas de modificar a documentação, pela qual muitas coisas não são novamente levadas em consideração. Nesse caso, a lógica do programa provavelmente será diferente da lógica do algoritmo, demonstrando assim uma falta de correspondência. Eu disse "provavelmente" de propósito, visto que ninguém algum dia vai verificar o texto do programa de outra pessoa.

Se o programa é grande, é impossível verificar se ele corresponde ou não ao algoritmo somente utilizando o texto. A precisão da implementação pode ser verificada com um procedimento denominado "teste". Ele basicamente verifica como o desenvolvedor dominou o algoritmo (escrito em papel), transformou ele em outro algoritmo em sua mente e criou um programa como resultado. Por fim, o desenvolvedor é a única pessoa que possui informações importantes sobre a lógica e tudo o que foi cunhado antes da implementação torna-se absolutamente irrelevante.

Não é como se o desenvolvedor pudesse adoecer (ou demitir-se). O ponto é que a lógica de fundo do programa seria diferente com cada desenvolvedor, dependendo de sua inteligência e conhecimento sobre uma linguagem de programação. De qualquer forma, o desenvolvedor introduz e utiliza diversas variáveis intermediárias conforme considera apropriado. E, se o programa é grande e logicamente complexo, um especialista melhor qualificado será necessário para encontrar as falhas (e não estou falando aqui de falhas de sistema operacional ou uso incorreto de funções de linguagem, e sim de implementação inapropriada em termos de lógica) e resolvê-las através do próprio texto do programa.

A maioria dos desenvolvedores, para dizer o mínimo, não tem interesse em escrever algoritmos antes da programação (ou mesmo esboçá-los em papel), o que provavelmente se deve ao fato de que eles ainda precisam pensar em alguma ideia própria ao longo do caminho. Realmente, qual a razão de desenhar alguns retângulos, diamantes e setas quando é melhor passar imediatamente à programação e então planejar um algoritmo um pouco similar ou muito geral na documentação.

Todos se acostumaram a isso - os desenvolvedores fazem isso porque é mais fácil assim, enquanto que os criadores de problemas nem sempre têm habilidades de programação em nível requerido e, mesmo se tiverem, eles são simplesmente incapazes de fazer alterações oportunas no que é criado pelos desenvolvedores. Ambientes de programação convenientes também contribuem para a validade da ordem de desenvolvimento especificada. Ferramentas avançadas para depuração e monitoramento de valores de variáveis nos dão esperanças de detectar qualquer erro na lógica.

à medida em que o tempo passa e o prazo de entrega do projeto se aproxima, o desenvolvedor está sentado e desenhando em um guardanapo as soluções para um determinado problema lógico, o qual, aliás, ainda deve ser implementado. Não vamos nem mencionar que os erros negligenciados durante o teste seguem praticamente o mesmo cenário caótico.... Essa é a situação atual. Há alguma solução ou isso pode ser ao menos melhorado? Parece que algo importante é perdido na transição do algoritmo planejado de forma padrão para o código do programa.


2. Parte lógica do programa

O autor da "programação baseada em autômatos" propôs o seguinte conceito da parte lógica ideal de um programa. Toda a lógica do programa é baseada no switch. De forma simplificada, qualquer algoritmo (autômato) de controle pode ser implementado conforme exibido abaixo (não pense muito sobre o significado dos comentários, neste ponto, apenas observe a estrutura).

switch(int STATUS ) // Мulti-valued global state variable of the automaton.
{
  case 0:  // start

  // Checking arc and loop conditions (in order of priority),
  // transition (change of the value of the variable STATUS)
  // and execution of arc and loop actions (output function execution);
  // logging transitions and actions if the condition is met. 0

  // Calling nested automata.
  // Execution of output functions in the state.
  break ;
  
  case 1:
  // Checking arc and loop conditions (in order of priority),
  // transition (change of the value of the variable STATUS)
  // and execution of arc and loop actions (output function execution);
  // logging transitions and actions if the condition is met. 

  // Calling nested automata.
  // Execution of output functions in the state.
  break ;
  
*********
*********
*********

 case N-1:
  // Checking arc and loop conditions (in order of priority),
  // transition (change of the value of the variable STATUS)
  // and execution of arc and loop actions (output function execution);
  // logging transitions and actions if the condition is met. 

  // Calling nested automata.
  // Execution of output functions in the state.
  break ;

 case N:
  // Checking arc and loop conditions (in order of priority),
  // transition (change of the value of the variable STATUS)
  // and execution of arc and loop actions (output function execution);
  // logging transitions and actions if the condition is met.

  // Calling nested automata.
  // Execution of output functions in the state.
  break ;
}


3. Programação baseada em autômatos, conforme explicada pelo autor A.A. Shalyto

Independentemente das técnicas de desenvolvimento, qualquer programa tem estados determinados por todos os seus valores de dados a qualquer tempo especificado. Poderá haver centenas e mesmo milhares de variáveis e diversos fluxos de controle em um programa aplicativo grande. Um conjunto completo dessas variáveis descreve o estado do programa aplicativo em qualquer tempo específico.

O estado do programa pode ser tratado, de forma mais simples, como um conjunto de valores de todas as variáveis de controle, as que participam de todas as condições de transição. Uma mudança no valor de uma das variáveis de controle significará, então, uma mudança no estado do programa e o número de estados de programa será determinado pelo número máximo possível de combinações de valores de variáveis de controle que surgem durante a operação do programa. Imagine que apenas variáveis binárias de controle (flag) são usadas em um programa. O número de estados do programa que contém n variáveis binárias de controle, nesse caso, estará dentro do limite de n a 2n.

Poderá ser que o desenvolvedor tenha estipulado reações para todas as combinações de valores de variáveis de controle (2n combinações, em nosso caso). Entretanto, é mais provável que algumas combinações de valores de variáveis de controle (até 2n-n) não tenham sido especificadas. Então, se a combinação inesperada de ações de entrada surgir, o programa pode passar a um estado não especificado.

Isso tem o mesmo efeito da inação de um EA para um negociador nos seguintes eventos:

  • intervalo,
  • perda do depósito,
  • cair em situação de balanço negativo com pedido de cobertura subsequente,
  • não obtenção de bom lucro, passando a zero e cada vez mais no vermelho,
  • abertura e fechamento incorretos de posições longas e curtas,
  • outras situações obviamente adversas.

Esses estados são chamados de "não visualizados". A complexidade causa dificuldade de enumeração, menos entendimento, todos os possíveis estados do programa, o que leva a sua falta de confiabilidade... A complexidade da estrutura é a fonte de estados não visualizados que constituem armadilhas de segurança. O comportamento do programa em um estado não especificado pode variar entre falhas de proteção de memória à extensão do programa para novas funções e criação de efeitos colaterais de diversas naturezas.

Muitos usuários de computador e provavelmente todos os desenvolvedores de software encontraram, muitas vezes, situações em que um programa em uso ou em desenvolvimento entra em um estado não especificado.

Para eliminar a possibilidade de estados não especificados no programa, todos os estados requeridos devem ser explicitamente especificados logo na etapa de projeto e apenas uma variável de controle de múltiplos valores deve ser utilizada para diferenciação entre eles. Em seguida, é necessário identificar todas as possíveis transições entre os estados e desenvolver o programa de forma que ele não possa "extraviar-se".

São necessários três componentes para obter rigor no desenvolvimento do comportamento do programa:

  • Modelo matemático que permite identificar inequivocamente os estados de programa e possíveis transições entre eles;
  • Notação gráfica para esse modelo;
  • Método universal para implementação de algoritmos expresso na notação.

Um autômato finito baseado na noção de "estado" é proposto para ser usado como modelo matemático. A programação baseada em autômatos suporta as etapas de desenvolvimento de software tal como projeto, implementação, depuração e documentação.

Ao passo que o termo "evento" tem sido usado com mais frequência em programação nos anos recentes, a abordagem proposta se baseia na noção de "estado". Após acoplá-lo ao termo "ação de entrada", que pode ser uma variável de entrada ou um evento, o termo "autômato sem saída" pode ser introduzido. O último é seguido pelo termo "ação de saída" e a noção de autônomo (finito determinístico) é introduzida mais detalhadamente. A área de programação baseada nesse conceito é, portanto, chamada programação baseada em autômatos e o processo de desenvolvimento respectivo é denominado projeto de programa baseado em autômatos.

A abordagem especificada é peculiar no sentido de que, quando aplicada, os autômatos são representados por gráficos de transição. Para uma diferenciação entre os seus nodos, o termo "designação de estado" é introduzido. Ao selecionar uma "designação de estado de valores múltiplos", os estados cujos números coincidem com o número dos valores que a variável selecionada pode aceitar podem ser diferenciados com o uso de apenas uma variável. Esse fato permitiu a introdução do termo "observabilidade do programa" na programação.

A programação sob a abordagem proposta é realizada através de "estado" em vez de "variáveis" (flags), o que ajuda a entender e especificar melhor o problema e os seus componentes. A depuração, nesse caso, é feita por registro em termos de autômatos.

Visto que a abordagem acima propõe ir do gráfico de transição ao código do programa utilizando um método formal e isomórfico, parece mais razoável fazer isso aplicando estruturas switch quando linguagens de programação de alto nível são utilizadas. Essa é a razão pela qual decidi usar o termo "tecnologia SWITCH" ao me referir ao paradigma da programação baseada em autômatos.


4. Programação explícita baseada em estados

A abordagem de aplicativo baseado em autômatos foi ampliada para sistemas baseados em eventos que também são chamados de "reativos". Os sistemas reativos interagem com o ambiente utilizando mensagens a uma taxa estabelecida pelo ambiente (um EA pode ser incluído na mesma classe).

O desenvolvimento de sistemas baseados em eventos e com utilização de autômatos foi possível através do uso da abordagem processual, da qual o nome programação explícita baseada em estados foi derivado. As ações de saída, neste método, são atribuídas a arcos, circuitos ou nodos de gráficos de transição (autômatos mistos - de Moore e Mealy - são utilizados). Isso permite obter uma representação compacta da sequência de ações que estão sendo reações a ações de entrada relevantes.

A abordagem proposta para programar a classe determinada de sistemas tem como característica um aumento de centralização da lógica, visto que ela é eliminada dos handlers de evento e a geração de um sistema de autômatos interconectados é chamada a partir dos handlers. A interação entre os autômatos nesse sistema pode ser obtida através de aninhamento, chamada e troca de números de estados.

O sistema de autômatos interconectados forma uma parte do programa independente do sistema enquanto que uma parte dependente do sistema é formada pelas funções de ação de entrada e de saída, handlers, etc.

Outra característica-chave da abordagem em análise é que, quando ela é aplicada, os autômatos são utilizados de forma tríplice:

  • para especificação;
  • para implementação (eles permanecem no código do programa);
  • para registro em termos de autômatos (conforme especificado acima).

O último item permite controlar a precisão da operação do sistema de autômatos. O registro é realizado automaticamente com base no programa desenvolvido e pode ser utilizado para problemas de grande escala com lógica de programa complexa. Cada registro pode, nesse caso, ser considerado um script relevante.

Os registros permitem monitorar o programa em operação e ilustrar o fato de que os autômatos não são "imagens", e sim entidades reais ativas. A abordagem baseada em autômatos é proposta para ser utilizada não apenas para a criação de um sistema de controle, mas também para modelar objetos de controle.


5. Conceitos básicos da programação baseada em autômatos

O conceito básico da programação baseada em autômatos é o ESTADO. A principal propriedade do estado do sistema a qualquer tempo t0 especificado é "separar" o futuro (t > t0) do passado (t < t0) no sentido de que o estado atual contém todas as informações sobre o passado do sistema que são necessárias para determinar as suas reações a qualquer ação de entrada gerada a qualquer tempo t0 determinado.

Na utilização do termo ESTADO, o conhecimento de dados históricos não é requerido. O estado pode ser considerado uma característica especial que combina implicitamente todas as ações de entrada do passado que afetam a reação da entidade no momento atual. A reação atual depende apenas da ação de entrada e do estado atual.

A noção de "ação de entrada" também é uma das noções-chave da programação baseada em autômatos. Uma ação de entrada é normalmente um vetor. Os seus componentes são divididos em eventos e variáveis de entrada, dependendo do significado e do mecanismo de geração.

A combinação do conjunto finito de estados e conjunto finito de ações de entrada forma um autômato (finito) sem saída. Esse autômato reage às ações de entrada, mudando o seu estado atual de uma determinada maneira. As regras de acordo com as quais os estados podem ser alterados são chamadas de função de transição do autômato.

O que é chamado de autômato (finito) em programação baseada em autômatos é basicamente a combinação do "autômato sem saída' e da "ação de entrada". Esse autômato reage à ação de entrada não apenas através da alteração do seu estado, mas também através da geração de determinados valores de saídas. As regras de geração de ações de saída são chamadas de função de saída do autômato.

Ao projetar um sistema de comportamento complexo, é necessário tomar como ponto de partida os objetos de controle existentes com um determinado conjunto de operações e um determinado conjunto de eventos que pode surgir no ambiente externo (mercado).

Na prática, o projeto é mais frequentemente baseado em objetos de controle e eventos:

  1. Os dados iniciais do problema não são apenas uma descrição verbal do comportamento alvo do sistema, mas também uma especificação (mais ou menos) precisa sobre o conjunto de eventos que está entrando no sistema a partir do ambiente externo e um grande número de solicitações e comandos de todos os objetos de controle.

  2. Um conjunto de estados de controle é construído.

  3. Cada solicitação de objetos de controle é atribuída a uma variável de entrada correspondente do autômato, enquanto que cada comando é atribuído a uma variável de saída correspondente. O autômato que irá assegurar um comportamento de sistema requerido é construído com base em variáveis de estados de controle, de eventos, de entrada e de saída.


6. Características e vantagens do programa

A primeira característica de um programa baseado em autômatos é que a presença de um circuito externo essencial. Basicamente, parece que não há novidade alguma; o principal aspecto aqui, entretanto, é que esse circuito será o único na parte lógica de todo o programa! (Ou seja, novo tick de entrada.)

A segunda característica é derivada da primeira. Qualquer autômato contém uma estrutura de switch (na realidade, ele é virtualmente constituído por ela) que engloba todas as operações lógicas. Quando um autômato é chamado, o controle é transferido para uma das etiquetas de "caso" e, após as ações relevantes, a operação do autômato (subprograma) é finalizada até o próximo início. Essas ações consistem em verificar condições de transição e, caso uma condição ocorrer, as funções de saída relevantes são chamadas e o estado do autômato é alterado.

A principal consequência de tipo o que foi dito acima é que a implementação de um autômato não é somente simples. O mais importante é que o programa pode ser executado sem diversas variáveis (flags) lógicas intermediárias, cuja funcionalidade em cada autômato é proporcionada por uma variável de estado de valores múltiplos.

é difícil acreditar na última afirmação, visto que ficamos acostumados a usar diversas variáveis globais e locais (flags) sem pensar muito. O que podemos fazer sem elas?! Essas são frequentemente flags que sinalizam para o programa que uma condição foi atendida. A flag é configurada (como TRUE) quando o desenvolvedor pensa que é necessário, mas ela é então (geralmente após a flag começar a causar os efeitos desejados por sempre ser TRUE) forçada a retornar a FALSE em outro lugar no programa.

Isso parece familiar, não? Agora observe o exemplo e veja? nenhuma variável adicional foi utilizada aqui; a mudança diz respeito apenas ao valor do número do estado e apenas quando uma condição lógica é atendida. Você não acha que esse é um substituto valioso para as flags?!

O algoritmo desempenha um papel principal na criação da parte lógica de um programa. A frase-chave que deve ser lembrada aqui é "parte lógica". O estado fundamenta tudo, nesse caso. Outra palavra que deve ser adiciona é "espera". E, na minha opinião, nós obtemos uma definição muito adequada de "estado de espera". Quando estamos nesse estado, esperamos pelo aparecimento de ações de entrada (atributos, valores ou eventos). A espera pode ser cuta ou longa. Ou, em outras palavras, há estados que podem ser instáveis ou estáveis.

A primeira propriedade do estado é o fato de que um conjunto limitado de ações de entrada é esperado no estado. Qualquer algoritmo (e, obviamente, qualquer programa) possui informações de entrada e de saída. As ações de saída podem ser divididas em dois tipos: variáveis (por exemplo, operações de propriedade de objeto) e funções (por exemplo, chamada da função de início do aplicativo, função de relatório, etc.).

A segunda propriedade do estado é a provisão de um conjunto de valores precisos de variáveis de saída. Isso revela uma circunstância simples, ainda que extremamente importante - todos os valores de variáveis de saída podem ser determinados a qualquer tempo quando o algoritmo (programa) está em um determinado estado a qualquer ponto do tempo.

O número de estados é limitado, assim como o número de valores de variáveis de saída. A função de relatório de transições é suavemente integrada à função do autômato e a sequência de transições entre estados bem como a entrega de ações de saída podem, consequentemente, ser determinadas sempre.

A lista completa de características é apresentada na seção 2. As Características da tecnologia proposta e a lista completa de vantagens podem ser encontradas na seção 3. Vantagens da tecnologia proposta. Este artigo não consegue cobrir todas as informações sobre o assunto! Após um estudo aprofundado de toda a literatura de pesquisa escrita por Anatoly Shalyto, todas as perguntas teóricas devem ser feitas pessoalmente a ele, através do e-mail shalyto@mail.ifmo.ru.

E, como usuário das ideias científicas dele, tendo em mente nossos objetivos e problemas, apresentarei abaixo três exemplos da minha implementação da tecnologia de programação baseada em autômatos.


7. Exemplos de programação baseada em autômatos

7,1. Exemplo para compreensão

O estado é apenas um modo em que o sistema existe. Por exemplo, a água existe em 3 estados: sólido, líquido ou gasoso. Ela muda de um estado para outro ao ser influenciada por uma variável - a temperatura (a uma pressão constante).

Suponha que tenhamos um gráfico de temperatura (t) baseado em tempo (em nosso caso, o valor do preço):

int STATUS=0; // a global integer is by all means always a variable !!! STATUS is a multi-valued flag
//----------------------------------------------------------------------------------------------//
int start() // outer loop is a must
  {
   switch(STATUS)
     {
      case 0:  //--- start state of the program
         if(T>0 && T<100) STATUS=1;
         if(T>=100)       STATUS=2;
         if(T<=0)         STATUS=3;
         break;

      case 1:  //---  liquid
         // set of calculations or actions in this situation (repeating the 1st status -- a loop in automata-based programming) //
         // and calls of other nested automata A4, A5;
         if(T>=100 )      { STATUS=2; /* set of actions when transitioning, calls of other nested automata A2, A3;*/}
         if(T<0)          { STATUS=3; /* set of actions when transitioning, calls of other nested automata A2, A3;*/}
         // logging transitions and actions when the condition is met.
         break;

      case 2:  //--- gas
         // set of calculations or actions in this situation (repeating the 2nd status -- a loop in automata-based programming) //
         // and calls of other nested automata A4, A5;
         if(T>0 && T<100) { STATUS=1; /* set of actions when transitioning, calls of other nested automata A2, A3;*/}
         if(T<=0)         { STATUS=3; /* set of actions when transitioning, calls of other nested automata A2, A3;*/}
         // logging transitions and actions when the condition is met.
         break;

      case 3:  //--- solid
         // set of calculations or actions in this situation (repeating the 3rd status -- a loop in automata-based programming) //
         // and calls of other nested automata A4, A5;
         if(T>0 && T<100) {STATUS=1; /* set of actions when transitioning, calls of other nested automata A2, A3;*/}
         if(T>=100)       {STATUS=2; /* set of actions when transitioning, calls of other nested automata A2, A3;*/}
         // logging transitions and actions when the condition is met.
         break;
     }
   return(0);
  }

O programa pode ficar mais sofisticado com a adição do parâmetro de pressão P, de novos estados e da introdução de uma dependência complexa demonstrados no gráfico:


Este autômato possui 32 = 9 condições de transição, de forma que nada pode ficar de fora ou ser negligenciado. Esse estilo também pode ser muito conveniente para escrever instruções e regras! Nenhuma brecha ou desvio de lei é permitido aqui - todas as combinações das variantes de sucessão de eventos devem ser cobertas em todos os casos descritos.

A programação baseada em autômatos requer que nós levemos tudo em consideração, mesmo se algumas variantes de sucessão de eventos não fossem consideradas, razão pela qual essa é a principal ferramenta para verificação de regras, instruções e sistemas de controle para constatar a consistência e integridade. Também há uma lei matemática:

Se há N estados (exceto o início 0) no sistema, o total de condições de transição é N2.

Diagrama de transição: N = 3 estados, o número de transições e ciclos é N2 = 9 (igual ao número de setas).


Se o número de variáveis no exemplo fosse diferente, então:


Isso mostra que todos os valores calculados na tabela crescem exponencialmente, ou seja, o projeto é um processo complicado que requer meticulosidade durante a seleção das principais variáveis sistêmicas.

Mesmo se houver apenas dois parâmetros, é muito difícil descrever tudo! Entretanto, na prática, tudo é muito mais fácil! Dependendo da lógica e do significado, 50-95% das transições não podem existir fisicamente e o número de estados também é 60-95% inferior. A análise de lógica e significado diminui expressivamente a dificuldade de descrição de todas as transições e estados.

Em casos mais complicados, requer-se o cálculo do número máximo de estados para todos os dados de entrada e de saída conhecidos em um EA. A solução para esse problema pode ser encontrada através da aplicação de combinatória e fórmulas de combinação, permutação, arranjos e combinatória enumerativa.

7,2. Atraso com histerese

A programação de atrasos, gatilhos, registros, contadores, decodificadores, comparadores e outros elementos do sistema de controle digital e analógico pode ser muito conveniente em um EA.

  • xmáx = 100 - valor máximo de pick-up;
  • xmín = -100 - valor mínimo de pick-up;
  • x = x(t) - sinal na entrada;
  • Y = Y(t) - sinal na saída.
int   status=0;  // at the beginning of the program we globally assign
//------------------------------------------------------------------//
switch(status)
  {
   case 0: //  start  
      Y=x;
      if(x>xmax)  {status=1;}
      if(x<xmin)  {status=2;}
      break;

   case 1: //++++++++++++++++++++
      if(x>xmax)  Y=x;
      if(x<xmax)  Y=xmin;
      if(x<=xmin) {status=2; Y=xmin;}
      break;

   case 2: //--------------------
      if(x<xmin)  Y=x;
      if(x>xmin)  Y=xmax;
      if(x>=xmax) {status=1; Y=xmax;}
      break;
  }

A característica do atraso:

7,3. Modelo para 9 estados e 81 variantes de sucessão de eventos

Y é o estado de entrada atual do autômato de 1 a 9. O valor de Y é gerado no EA fora do subprograma especificado. MEGASTATUS é a situação anterior de Y.

int MEGASTATUS=0; // at the beginning of the program we globally assign
//---------------------------------------------------------------------//
void A0(int Y) // automaton template
  {
   switch(MEGASTATUS)
     {
      case 0:  // start
          MEGASTATUS=Y;
          break;

      case 1: // it was the past
          // it became current, repeating
          if(Y=1) { /*set of actions in this situation, calls of other nested automata A2, A3, ... */ } // Loop//
          // new current
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ }
          if(Y=6) { /* set of actions in this situation */ }
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 2: // it was the past
          // it has become current
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ } //Loop//
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ }
          // e.g. if the transition from 2 to 6 is in essence impossible or does not exist, do not write anything
          if(Y=6) { /* set of actions in this situation */ }
          // the automaton will then be reduced but the automaton template shall be complete to count in everything
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 3: // it was the past
          // it has become current
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ } //Loop//
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ }
          if(Y=6) { /* set of actions in this situation */ }
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 4: // it was the past
          // it has become current
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ } //Loop//
          if(Y=5) { /* set of actions in this situation */ }
          if(Y=6) { /* set of actions in this situation */ }
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 5: // it was the past
          // it has become current
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ } //Loop//
          if(Y=6) { /* set of actions in this situation */ }
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 6: // it was the past
          // it has become current
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ }
          if(Y=6) { /* set of actions in this situation */ } //Loop//
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 7: // it was the past  
          //it has become current  
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ }
          if(Y=6) { /* set of actions in this situation */ }
          if(Y=7) { /* set of actions in this situation */ } //Loop//
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 8: // it was the past
          // it has become current
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ }
          if(Y=6) { /* set of actions in this situation */ }
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ } //Loop//
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 9: // it was the past
         // it has become current
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ }
          if(Y=6) { /* set of actions in this situation */ }
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ } //Loop//
          // logging transitions and actions when the condition is met.
          break;
     }
   MEGASTATUS=Y;
  }

7.4. Autômato de reprodutor de áudio

Vamos analisar um reprodutor de áudio simples.

Esse dispositivo pode estar em 6 estados:

  1. Pronto;
  2. Sem faixa;
  3. Reproduzindo;
  4. Avanço rápido;
  5. Retrocesso rápido;
  6. Pausar.

O sistema de controle do reprodutor de áudio é representado por um autômato. Os botões apertados são considerados eventos que têm efeito sobre o autômato. As transições entre as faixas, reproduzindo, controle de exibição, etc., são ações de saída.

switch(STATUS)
  {
   case 0: //--- "Ready"
      if(Event == 3) { STATUS = 3; } //«>>» button pressed
      if(Event == 6) { STATUS = 1; } //Audio file not found 
      if(Event == 1) { STATUS = 2; } //«PLAY» button pressed
   
      z1();  // Set the indicator to the initial state
      break;

   case 1: //--- "No Track"
      z6();  // Give the «No Track» message
      break;

   case 2: //--- "Playing"
      if(Event == 4) { STATUS = 4; } //«<<» button pressed
      if(Event == 5) { STATUS = 5; } //«PAUSE»( | | ) button pressed
      if(Event == 3) { STATUS = 3; } //«>>» button pressed
      if(Event == 2) { STATUS = 0; } //«STOP» button pressed
      z2(); // Playing
      break;

   case 3: //--- "Fast-Forward"
      z3();  // Next track
      { STATUS=2; }
      break;

   case 4: //--- "Rewind"
      z4(); // Previous track
      { STATUS=2; }
      break;

   case 5: //--- "Pause"
      if(Event == 5) { STATUS = 2; } //«PAUSE» button pressed
      if(Event == 1) { STATUS = 2; } //«PLAY» button pressed
      if(Event == 2) { STATUS = 0; } //«STOP» button pressed
      if(Event == 3) { STATUS = 3; } //«>>» button pressed
      if(Event == 4) { STATUS = 4; } //«<<» button pressed
      z5(); //Pause
      break;
  }

Em teoria, esse autômato poderia ter 36 variantes de transição, mas apenas 15 existem realmente e todos os detalhes podem ser encontrados na descrição fornecida pelo autor.


8. Recomendações de A.A. Shalyto sobre a execução do projeto

As informações completas sobre como preparar e escrever a documentação do projeto pode ser encontrada aqui http://project.ifmo.ru/books/3. Neste artigo, apenas apresentarei uma breve síntese:

  1. O livro de A.A. Shalyto "Controle de lógica. Métodos de implementação de algoritmos para hardware e software. SPb.: Nauka, 2000", disponível no website especificado na seção "Livros" pode ser utilizado como um protótipo. Ele incorpora uma apresentação adequada de informações, visto que foi publicado pela editora mais antiga e respeitada da Rússia.
  2. A introdução deve fornecer uma base para a relevância do assunto escolhido, apresentar brevemente o problema que está sendo considerado e especificar a linguagem de programação e o sistema operacional utilizado no projeto.
  3. Uma descrição verbal detalhada do problema em análise deve ser fornecido na seção "Descrição do problema" junto com figuras, diagramas e capturas de tela, esclarecendo o problema descrito.
  4. Ao utilizar programação orientada a objetos, a seção "Projeto" deve incluir um diagrama de classes. As principais classes devem ser descritas cuidadosamente. é recomendável que um "Diagrama de bloco da classe" seja preparado para cada uma delas, com vistas a apresentar a sua interface e os métodos utilizados juntamente com a indicação de métodos baseados em autômatos.
  5. Três documentos devem ser fornecidos para cada autômato da seção "Autômatos": uma descrição verbal, um diagrama de ligação de autômato e um gráfico de transição.
  6. A descrição verbal deve ser bem detalhada. Porém, porque é difícil de descrever de maneira clara o comportamento de um autômato complexo, ela geralmente representa uma "declaração de intenções".
  7. O diagrama de ligação de autômato apresenta uma descrição detalhada da sua interface. A parte esquerda do diagrama deve apresentar:
    • fontes de dados;
    • nome completo de cada variável de entrada;
    • nome completo de cada evento;
    • Predicados com números de estado de outros autômatos que são utilizados em determinado autômato como ações de entrada. Por exemplo, o predicado Y8 == 6 pode ser utilizado (o qual obtém o valor igual a um uma vez que o oitavo autômato passa ao sexto estado);
    • variáveis de entrada indicadas por x com índices relevantes;
    • eventos indicados por e com índices relevantes;
    • variáveis para armazenagem de estados do autômato com o número N, indicado por YN.

    A parte direita do diagrama deve apresentar:
    • variáveis de saída indicadas por z com índices relevantes;
    • nome completo de cada variável de saída;
    • eventos gerados pelo autômato em análise (se houver);
    • nome completo de cada evento gerado;
    • receptores de dados.
  8. Se algoritmos computacionais complexos são utilizados em nodos ou transições, a seção "Algoritmos computacionais" explica a escolha de algoritmos e fornece a descrição deles (incluindo descrição matemática). Esses algoritmos são designados pelas variáveis x e z, dependendo se os cálculos são feitos na entrada ou na saída.
  9. As peculiaridades da implementação do programa devem ser apresentadas na seção "Implementação". Ela deve apresentar, em especial, um modelo para a implementação formal e isomórfica dos autômatos. As implementações dos autômatos também devem ser fornecidas aqui.
  10. A "Conclusão" abrange os benefícios e desvantagens do projeto finalizado. Ela também pode apresentar formas de melhorar o projeto.


9. Conclusão

Encorajo todos vocês a:

  • explorar essa nova abordagem de programação.
  • implementar essa abordagem totalmente nova e interessante para programar suas ideias e estratégias de negociação.

Espero que a programação baseada em autômatos:

  • com o passar do tempo, torne-se o padrão de programação e projeto para todos os negociadores e mesmo para os desenvolvedores de linguagem MetaQuotes.
  • seja a base para a tomada de decisões complexas durante a criação de um EA.
  • no futuro, seja transformado em uma nova linguagem - Linguagem MetaQuotes 6 - que suporte a abordagem de programação baseada em autômatos e em uma nova plataforma - MetaTrader 6.

Se todos os desenvolvedores de negociações seguirem essa abordagem de programação, a meta de criação de um EA sem perdas pode ser atingida. Este primeiro artigo é minha tentativa de mostrar a você uma nova válvula de escape para criatividade e a pesquisa no campo do projeto com base em autômatos e programação como impulso para novas invenções e descobertas.

Por fim - eu concordo totalmente com o artigo do autor e sinto que é importante apresentar a você uma versão em forma concisa (o texto completo pode ser acessado aqui http://is.ifmo.ru/works/open_doc/):

A razão pela qual os códigos fonte não são uma solução para entender programas

O principal problema na programação prática é a compreensão de códigos de programa. é sempre benéfico ter códigos fonte disponíveis, mas o problema é que isso nem sempre é suficiente. Uma documentação adicional é geralmente necessária para que se compreenda um programa não trivial. Essa necessidade cresce exponencialmente à medida que a quantidade de códigos aumenta.

A análise de código de programa que objetiva restaurar as decisões de projeto originais feitas por desenvolvedores e a compreensão de programas são dois ramos importantes da tecnologia de programação cujas existências caminham lado a lado com a insuficiência de códigos fonte para a compreensão de programas.

Todas as pessoas que já se envolveram em um grande projeto de reconstrução de software sempre se lembrarão do sentimento de impotência e perplexidade quando, pela primeira vez, observam um monte de códigos fonte mal documentados (embora nem sempre estejam mal escritos). A disponibilidade de códigos fonte não é de grande ajuda quando não há acesso aos desenvolvedores principais. Se o programa está escrito em linguagem de nível relativamente baixo e, além disso, está mal documentado, todas as principais decisões de projeto geralmente se dispersam nos detalhes de programação e precisam ser reconstruídas. Em casos como esse, o valor de uma documentação de alto nível, tal como especificação de interface e descrição de arquitetura, pode superar o próprio valor do código fonte.

A percepção do fato de que os códigos fonte são inadequados para compreender programas deu origem a tentativas de combinar o código e uma documentação de alto nível.

Se você perder as etapas iniciais do projeto, a complexidade e a quantidade de trabalho irá virtualmente "prender" os códigos fonte longe de você, considerando que não haja qualquer documentação de alto nível. Compreender o código "pré-histórico" na ausência dos desenvolvedores que originalmente trabalharam no projeto ou de documentação adequada que permita organizar as decisões arquiteturais relevantes é provavelmente um dos desafios mais difíceis encontrados pelos programadores.


A razão pela qual o programa não tem projeto

Então, enquanto que a ausência de códigos fontes pode ser algo ruim, a sua presença pode ser igualmente pouco benéfica. O que ainda falta para uma vida "feliz por toda a eternidade"? A resposta é simples - uma documentação de projeto detalhada e precisa que inclui a documentação do programa como um de seus componentes.

Pontes, estradas e arranha-céus normalmente não podem ser construídos sem documentação, o que não é verdade para os programas.

A situação atual da programação pode ser definida da seguinte forma: "Se os construtores construíssem prédios da forma que os programadores escrevem programas, o primeiro pica-pau que surgisse destruiria a civilização."

Por que será que uma documentação de projeto detalhada e clara é emitida para hardware e pode ser facilmente compreendida e modificada por um especialista comum mesmo anos após a emissão, mas uma documentação ou é inexistente para software ou foi escrita de maneira totalmente formal, sendo necessário um especialista altamente qualificado para modificá-la. (E se não encontrarmos o desenvolvedor?)

Aparentemente, essa situação pode ser explicada da seguinte maneira. Primeiramente, o desenvolvimento e a manufatura de hardware são dois processos diferentes realizados por organizações diferentes. Assim, se a documentação tem má qualidade, o engenheiro de desenvolvimento irá passar o resto da sua vida trabalhando na "planta", o que certamente não é o que ele deseja. Quando se trata de desenvolvimento de software, a situação muda e, nesse caso, tanto o desenvolvedor como o fabricante são geralmente uma única empresa e, assim, independentemente da lista de documentos, o conteúdo será, em regra, bastante superficial.

Em segundo lugar, o hardware é "duro", enquanto que o software é "macio". Isso faz com que seja fácil modificar programas, mas, no geral, não oferece base para emissão de documentação de projeto. Sabe-se que a maioria dos programadores são patologicamente relutantes à leitura e, mais mais ainda, à escrita de documentação.

A experiência sugere que quase nenhum dos programadores recém-qualificados, mesmo os mais inteligentes, podem preparar documentação de projeto. E, apesar do fato de que muitos deles fizeram e passaram por longos e complexos cursos de matemática, isso não tem qualquer efeito em sua lógica e rigor para escrita de documentação. Eles podem usar diferentes notações para o mesmo objeto ao longo de toda a documentação (independentemente do seu tamanho), chamando, por exemplo, o bulbo, o bulbo de luz, a lâmpada ou Lâmpada, escrevendo em letras maiúsculas ou minúsculas quando desejarem. Imagine o que acontece quando eles demonstram todo o seu potencial de decoração!

Aparentemente, isso acontece devido ao fato de que, durante a programação, o compilador alerta para as inconsistências enquanto que a documentação do projeto é escrita sem qualquer tipo de lembretes.

O problema da qualidade da documentação de software está se tornando um problema de crescente importância social. O desenvolvimento de software se assemelha cada vez mais à indústria do entretenimento, com sua forte motivação de lucrar. Tudo é feito rapidamente, sem reflexão sobre o que acontecerá com o produto no futuro. Assim como a indústria do entretenimento, a programação mede tudo em termos de "perdas e lucros" e não "bom e ruim". Na maioria dos casos, uma boa tecnologia não é aquela que é realmente boa, e sim aquela que tem retorno financeiro.

A relutância em escrever documentação de projeto é também provavelmente associado ao fato de que, quanto mais restrito (não documento) é o projeto, mais indispensável se torna o autor.

Infelizmente, esse comportamento de trabalho se espalha para o desenvolvimento de software de sistemas altamente críticos. Isso se dá amplamente pelo fato de que os programas são, na maioria dos casos, escritos, e não projetados. "Ao projetar, qualquer técnica mais complicada que Cartões CRC ou o uso de diagramas de caso é considerada muito complexa e, assim, não é utilizada. Um programador sempre pode se recusar a aplicar qualquer tecnologia determinada ao relatar ao chefe que não poderá cumprir o prazo".

Isso leva a situações em que mesmo os "usuários não consideram que os erros no software sejam algo incomum".

Atualmente, existe uma concepção generalizada de que o projeto e a documentação adequada devem existir quando se trata de grandes prédios, mas não de software.

Concluindo, deve-se notar que essa situação não existia na programação do passado - quando os computadores de larga escala eram utilizados, os programas eram projetados ou desenvolvidos com muito cuidado porque, em caso de erro, a próxima tentativa somente aconteceria, no mínimo, dentro de um dia. Assim, o progresso técnico nos levou a uma programação menos cuidadosa.


Infelizmente, nossos problemas e preocupações não podem ser detectados no website do departamento do instituto em que o A.A. Shalyto trabalha. Eles têm os seus próprios problemas, não estão familiarizados e não conhecem nossos conceitos e definições. Por isso, não há exemplos relevantes para o nosso assunto.


Os principais livros/compêndios de A.A. Shalyto:

  1. Programação baseada em autômatos. http://is.ifmo.ru/books/_book.pdf
  2. Utilizando gráficos de fluxo e gráficos de transição na implementação de algoritmos de controle de lógica. http://is.ifmo.ru/download/gsgp.pdf
  3. Programação baseada em autômatos. http://is.ifmo.ru/works/_2010_09_08_automata_progr.pdf
  4. Transformação de algoritmos iterativos em algoritmos baseados em autômatos. http://is.ifmo.ru/download/iter.pdf
  5. Tecnologia switch: Abordagem baseada em autômatos para desenvolvimento de software para sistemas reativos. http://is.ifmo.ru/download/switch.pdf
  6. Projeto de programa baseado em autômatos. Algoritmização e programação de problemas de controle de lógica. http://is.ifmo.ru/download/app-aplu.pdf
  7. Uso de algoritmo genético para projetar piloto automático para um modelo de helicóptero simplificado. http://is.ifmo.ru/works/2008/Vestnik/53/05-genetic-helicopter.pdf
  8. Programação explícita baseada em estados. http://is.ifmo.ru/download/mirpk1.pdf
  9. Algoritmização e programação para controle de lógica e sistemas reativos. http://is.ifmo.ru/download/arew.pdf
  10. Abordagem orientada a objetos para programação baseada em autômatos. http://is.ifmo.ru/works/ooaut.pdf
  11. Notação gráfica para herança de classes baseadas em autômatos. http://is.ifmo.ru/works/_12_12_2007_shopyrin.pdf
  12. Programando em... 1 (Um) Minuto. http://is.ifmo.ru/progeny/1minute/?i0=progeny&i1=1minute

Projetos:

  1. Modelando a operação de caixas automáticos. http://is.ifmo.ru/unimod-projects/bankomat/
  2. Modelando o processo de controle de reator nuclear. http://is.ifmo.ru/projects/reactor/
  3. Sistema de controle de elevador. http://is.ifmo.ru/projects/elevator/
  4. Desenvolvimento de sistema de controle de máquina de café baseado em autômatos. http://is.ifmo.ru/projects/coffee2/
  5. Projeto e pesquisa de autômatos para direção de veículos. http://is.ifmo.ru/projects/novohatko/
  6. Modelando uma câmera digital com uso de programação baseada em autômatos. http://project.ifmo.ru/shared/files/200906/5_80.pdf
  7. Utilizando programação baseada em autômatos para modelar um sistema de agentes múltimos para veículos não tripulados. http://project.ifmo.ru/shared/files/200906/5_41.pdf
  8. Sistema de solução visual para cubo de Rubik. http://is.ifmo.ru/projects/rubik/

e outros artigos e projetos interessantes: http://project.ifmo.ru/projects/, http://is.ifmo.ru/projects_en/ e http://is.ifmo.ru/articles_en/.


Observação

O número de eventos diferentes possíveis de um Cubo de Rubik é (8! × 38−1) × (12! × 212−1)/2 = 43 252 003 274 489 856 000. Mas esse número não leva em consideração o fato de que os quadrados centrais podem ter diferentes orientações.

Assim, considerando as orientações das faces centrais, o número de eventos se torna 2048 vezes maior ou seja, 88 580 102 706 155 225 088 000.

O mercado Forex e as negociações não têm tantas variantes de sucessão de eventos, mas os problemas associados a eles pode ser facilmente resolvido em 100-200 passos através do uso desse paradigma de programação. é verdade! O mercado e os EAs estão em constante competição. é como um jogo de xadrez em que ninguém sabe os próximos movimentos do oponente (assim como nós). Entretanto, há programas de computador impressionantes, tal como o Rybka (um mecanismo de xadrez muito poderoso) projetado com base em algoritmos de poda alfa-beta.

Que esses sucessos de outras áreas de programação lhes dê energia e comprometimento com o trabalho! Entretanto, todos nós sabemos que não sabemos de nada.

Traduzido do russo por MetaQuotes Software Corp.
Artigo original: https://www.mql5.com/ru/articles/446

Oportunidades ilimitadas com o MetaTrader 5 e MQL5 Oportunidades ilimitadas com o MetaTrader 5 e MQL5

Neste artigo, eu gostaria de dar um exemplo de como um programa de negociação pode ser, bem como os resultados que podem ser alcançados em 9 meses, tendo começado a aprender MQL5 a partir do zero. Este exemplo também mostrará quanto multifuncional e informativo tal programa pode ser para um negociante, tendo um espaço mínimo no gráfico de preços. E vamos ser capazes de ver quanto colorido, brilhante e intuitivamente claro os painéis de informações comerciais dos usuários podem ser. Assim como muitos outros recursos...

OpenCL: Da programação ingênua até a mais perceptível OpenCL: Da programação ingênua até a mais perceptível

Este artigo foca em alguns recursos de otimização que se abrem quando pelo menos alguma consideração é dada ao hardware subjacente em que kernel OpenCL é executado. Os valores obtidos estão longe de serem os valores de teto, mas eles mesmos sugerem que tendo os recursos existentes disponíveis aqui e agora (OpenCL API como implementado pelos desenvolvedores do terminal não permite controlar alguns parâmetros importantes para otimização - particularmente, o tamanho do grupo de trabalho), o ganho de desempenho ao longo da execução do programa anfitrião é muito importante.

Os membros mais ativos do website MQL5.community ganharam iPhones! Os membros mais ativos do website MQL5.community ganharam iPhones!

Após termos decidido premiar os participantes mais proeminentes do website MQL5.com, selecionamos os critérios-chave para determinar a contribuição de cada participante para o desenvolvimento da comunidade. Como resultado, temos os seguintes vencedores que publicaram a maior quantidade de artigos no website - investeo (11 artigos) e victorg (10 artigos), e os que enviaram os seus programas à Base de códigos – GODZILLA (340 programas), Integer (61 programas) e abolk (21 programas).

Documentação gerada automaticamente para o código MQL5 Documentação gerada automaticamente para o código MQL5

A maioria dos codificadores Java estará familiarizada com a documentação gerada automaticamente com o JavaDocs. A ideia é adicionar comentários no código de uma maneira semi-estruturada que possam ser extraídos em um arquivo de ajuda fácil de navegar. O mundo do C++ também possui vários geradores automáticos de documentação, com os dois líderes sendo o SandCastle da Microsoft e o Doxygen. O artigo descreve o uso do Doxygen para criar o arquivo de ajuda HTML a partir dos comentários estruturados no código MQL5. O experimento funcionou muito bem, acredito que a documentação de ajuda que o Doxygen produz do código MQL5 irá agregar uma grande quantidade de valor.