English Русский 中文 Español Deutsch 日本語
Mais uma vez vamos falar sobre mapas de Kohonen

Mais uma vez vamos falar sobre mapas de Kohonen

MetaTrader 5Exemplos | 6 setembro 2016, 11:08
1 384 0
Mykola Demko
Mykola Demko

Introdução

Este artigo é uma continuação do artigo publicado anteriormente "Usar mapas auto-organizáveis (mapas de Kohonen) no Metatrader 5". Grande parte do material foi reformulado e adaptado para facilitar seu uso em projetos paralelos. Em geral, o artigo tem como objetivo ajudar os programadores novatos e experientes a conectar aos seus projetos o algoritmo de rede neural para mapas de Kohonen e a fazer alterações no algoritmo básico. Este artigo apresenta apenas uma amostra dos padrões, no entanto, dá ênfase á diversidade de exemplos de como utilizar o código.


Teoria de mapas de Kohonen

Os mapas de Kohonen são uma rede de camada única, cujos neurônios estão conectados a todos os componentes do vetor de entrada n-dimensional (padrão). O vetor de entrada (padrão) é a descrição de um dos objetos que estão sujeitos a clustering.

Na rede de Kohonen, são uados treinamentos sem supervisor. Para esses fins são aplicados mecanismos de concorrência. Ao enviar uma rede padrão para entrada, ganha o neurônio cujo vector é menos diferente do padrão de entrada. Para o neurônio vencedor, aplica-se a seguinte relação:

fórmula 1

Onde:

  • n — número de neurônios,
  • j — número do neurônio vencedor,
  • d(x,w) — distância entre vetores x e w.

O mais comum é utilizar a medida de distância euclidiana.

fórmula 2

Nessa implementação, a busca do neurônio vencedor ocorre na função BestMatchingNode da classe CSOM_Net_Base.

Em torno do neurônio vencedor, gera-se o ambiente (neighborhood) ou o raio de aprendizagem (radius of learning). O raio de aprendizagem determina quais neurônios passam por um treinamento nessa iteração. No início do treinamento, esse raio se encontra no máximo e, depois, diminui com o aumento do número de iterações de aprendizagem, de modo que, na última etapa, o neurônio vencedor aparece no raio de aprendizagem.

Arredores do neurônio vencedor

Os pesos dos neurônios, que se encontram dentro do raio de aprendizagem, são adaptados de acordo com a regra de Kohonen:

Regra de Kohonen

Onde:

  • x — padrão de entrada,
  • k — número de iterações de aprendizagem,
  • ni(k) — rácio de aprendizagem de i-neurônio a partir da do raio de aprendizagem na k-iteração.

Os pesos dos neurônios, que se encontram dentro do raio de aprendizagem, são adaptados de acordo com a regra de Kohonen: Nessa implementação, a adaptação dos pesos dos neurônios ocorre na função AdjustWeights da classe CSOMNode.

O rácio de velocidade de aprendizagem ni(k) está dividido em duas partes:

  • função vizinhança ni (d,k)

função de vizinhança

  • função de velocidade de aprendizagem a(k)

função da velocidade de aprendizagem

onde A e B são constantes selecionadas.

Esta função é inversamente proporcional ao número de ciclo da aprendizagem, por isso, na fase inicial de aprendizagem, a velocidade e raio de treinamento é suficientemente grande para que aconteça a média de padrões. Então, é no final da aprendizagem que acontece o ajuste final de pesos para os padrões de entrada.

Em geral, a dinâmica de adaptação de um neurônio específico pode ser representada como uma descida em um gradiente:

Descida de gradiente

Durante a aprendizagem da rede de Kohonen, acontece o problema dos chamados "neurônios mortos." Neurônios com rácios de peso iniciais, consideravelmente distantes dos padrões de entrada, nunca ganham a concorrência, não importa quanto dure o treinamento. Nesta implementação, este problema sistêmico do algoritmo de aprendizagem foi resolvido mediante duas modificações.

Primeiro, foi modificada a função padrão de seleção do padrão aleatório a partir do conjunto de aprendizagem. Em vez de rand()/N, com o qual não há garantia de que em N iterações serão emitidos todos os valores, usa-se a classe C_PRNG_UD. Ele garante a seleção aleatória, uniforme e distribuída dos padrões. Em segundo lugar, a inicialização de pesos dos neurônios acontece com valores aleatórios, mas, somente, a partir do intervalo encontrado nos padrões.

Assim, se aparecerem neurônios que nunca ganharam a concorrência ("neurônios mortos"), pelo menos, permanecerão nos arredores do vencedor e também serão submetidos a aprendizagem, fazendo o papel de ponte entre os padrões durante o clustering.


Implementação de rede de Kohonen e exemplos de uso

Agora vamos analisar a implementação de software de mapas de Kohonen. A implementação em si baseia-se em duas dimensões: a dimensão de padrões m_dimension e o número de nós m_total_nodes. No entanto, os mapas são representados visualmente como uma imagem tridimensional, em que o número de nós m_total_nodes é dobrado no retângulo m_xcells * m_ycells. Portanto os nodos nodes armazenam não só informações sobre pesos, mas também a localização no plano.

class CSOMNode
  {
protected:
   
   //--- coordenadas da zona do nó
   int               m_x1;
   int               m_y1;
   int               m_x2;
   int               m_y2;
   
   //--- coordenadas do centro do nó
   double            m_x;
   double            m_y;
   
   //--- peso do nó
   double            m_weights[];
   ...

A classe CSOMNode, em termos de composição, está incluída na classe base CSOM_Net_Base como uma matriz unidimensional das instâncias de classe CSOMNode m_som_nodes[]. Esta é a rede de Kohonen em si. As restantes funções só servem de aprendizagem e uso da rede.

No artigo anterior, a ênfase foi colocada na variedade de exemplos de padrões e na demostração da diversidade gráfica da interface. Neste artigo, será considerado apenas um exemplo de padrões, mas em cinco opções de conexão. Eu reescrevi o código-fonte para que seja fácil de usar para se conectar a projetos paralelos. A implementação é dividida em cinco classes.

class CSOM_Net_Base
class CSOM_Net_Data   : public CSOM_Net_Base
class CSOM_Net_Train  : public CSOM_Net_Data
class CSOM_Net_Img    : public CSOM_Net_Train
class CSOM_Net_Demo   : public CSOM_Net_Img

A declaração revela uma conexão de classes em cascata. Assim, se algumas funções não forem requeridas pelo projeto conectado, então será suficiente não conectar as classes filhas, e todas as funções a seguir serão cortadas.

A lista de funções públicas é dada abaixo:

class CSOM_Net_Base
  {
public:
   //--- mó público de rede Kohonen
   CSOMNode         *public_node;
   //--- a função envio o nó especificado ind para a parte pública public_node
   void              GetNode(int ind){ public_node=m_som_nodes[ind].GetObjPointer(); };
   //--- a função retorna a dimensão dos padrões
   int               GetDimension(){return(m_dimension);};
   //--- função de carregamento da rede a partir do arquivo                 
   bool              DownloadNet(string file_name);
   //--- função de localização, usando máscaras, do melhor nó de rede de acordo com o vetor definido
   int               BestMatchingNode(const double &vector[]);
   //--- função de localização do melhor nó de rede com base no vetor definido com corte de dimension
   int               BestMatchingNode(const double &vector[],int dimension);
   //--- função de preenchimento de máscara de bits para localização de nós similares aos padrões (a máscara define os campos de pesquisa)
   bool              InitSetByteMap(int num,bool value);
  };
  
class CSOM_Net_Data : public CSOM_Net_Base
  {
public:
   //--- função de carregamento da dados para aprendizagem a partir do arquivo definido
   bool              LoadPatternDataFromFile(string filename);
   //--- função de adicionando do vetor no conjunto de aprendizagem
   void              AddVectorToPatternsSet(double &vector[],string title);
   //--- função de cópia do padrão a partir do conjunto de aprendizagem    
   bool              GetPatterns(int ind_pattern,double &vector[]);
   //--- função de retorno do título do padrão a partir do conjunto de aprendizagem  
   string            GetTitlesPatterns(int ind_pattern);
   //--- função de retorno do número de padrões
   int               GetTotalsPatterns();
  }; 
  
class CSOM_Net_Train : public CSOM_Net_Data
  {
public:
   //--- função de inicialização de rede, obtenção de parâmetros
   void              InitParameters(int iterations,int xcells,int ycells);
   //--- função de aprendizagem da rede A
   void              Train();
   //--- função de armazenamento de rede no arquivo 
   void              SaveNet(string file_name);
   //--- funções virtuais (o corpo é descrito no descendente CSOM_Net_Img) 
   virtual void      Render(){};
   virtual void      ShowBMP(bool back){};
  }; 
  
class CSOM_Net_Img : public CSOM_Net_Train
  {
public:
   //--- função de inicialização de rede, obtenção de parâmetros
   void              InitParameters(int iterations,int xcells,int ycells,
                                    int bmpwidth,int bmpheight,
                                    bool p_HexagonalCell,bool p_ShowBorders,bool p_ShowTitles,
                                    int p_ColorScheme,int p_MaxPictures);
   //--- função de exibição do estado da rede
   void              Render();
   //--- função de exibição de imagem bmp no gráfico  
   void              ShowBMP(bool back);
   //--- função de armazenamento do recurso no arquivo bmp
   void              SaveBMP();
   //--- a função de anulação da inicialização exclui a imagem bmp do gráfico
   void              NetDeinit();
  };
  
class CSOM_Net_Demonstration : public CSOM_Net_Img
  {
public:
   //--- função - exemplo de uso do descendente para ampliação dos recursos
   void              ShowTrainPatterns();
  };

Nos arquivos anexados, há cinco exemplos que apresentam opções de uso para mapas de Kohonen. Eles são numerados em ordem de cascata de classes. Consideremos os exemplos em ordem.


Estabelecimento de uma rede, classe básica

O primeiro exemplo requer a extensão somnet, ela é usada para salvar a rede previamente treinada. No exemplo, é examinada a opção de conectar a rede treinada ao Expert Advisor para reconhecer padrões fornecidos a partir da implementação de software. Para simplicidade, os dados do arquivo são obtidos usando FileReadArray. Isto não requer sistemas complexos para leitura e reconhecimento de cadeia de caracteres (analisadores - parsers -). Além disso, liberar e receber dados usando matrizes torna-se mais rápido.

No exemplo Sample1_SOM_Net_Base, é carregada a rede treinada a partir do arquivo binário especificado no parâmetro (sem extensão):

input string SOM_Net="SOM\\SOM_Net";

A extensão somnet é substituída automaticamente. Isso foi feito para evitar qualquer confusão ao baixar um arquivo que não é adequado para o algoritmo de reconhecimento.

O carregamento da rede acontece na função DownloadNet(string file_name). Tendo considerado em detalhe o corpo da função, torna-se claro o formato do arquivo somnet. No início do arquivo, é gravado o título do arquivo (cabeçalho - HEADER -), ele é composto por três tipos de células de memória do tipo duplo (como a matriz derivada de todo o arquivo). O primeiro campo armazena a dimensão dos padrões mais seis. São necessários seis campos para armazenar as coordenadas do nó. Mas, uma vez que os seis têm um valor constante, podemos facilmente obter as dimensões dos padrões subtraindo seis a partir do primeiro campo do cabeçalho da matriz. O segundo e terceiro campos armazenam as variáveis m_xcells e m_ycells são as dimensões X e Y, respetivamente, na exibição visual da rede. A partir deles, é possível obter o número de nós na rede, multiplicando.

Em seguida, é preciso obter os dados da rede, vetor trás vetor, até que toda a rede esteja carregada.

Continuando o exemplo, após o carregamento da rede, ela é preenchida com a constante padrão vector[]. A inicialização pelas constantes é mencionada como exemplo. A função BestMatchingNode localiza o índice do nó mais semelhante. Depois disso, o nó é passado para a parte pública, para garantir o acesso às funções da classe CSOMNode.

Consideremos em detalhe a função BestMatchingNode. A função tem três opções de uso. Ao chamar a sobrecarga BestMatchingNode(const double &vector[]), sem inicialização da máscara, será executada uma pesquisa por todos os campos do vetor, visto que a própria função inicializa a máscara com as unidades, isto é, permite a pesquisa em todos os campos. Se chamarmos antecipadamente a inicialização da máscara InitSetByteMap(int num,bool value) para cada campo, se ativará a filtragem de pesquisa por campos. Assim, consegue-se a possibilidade de busca do nó de acordo com informações incompletas. Se usarmos a sobrecarga BestMatchingNode(const double &vector[],int dimension), então a busca será realizada em ordem até o campo com o número enviado para a função dimension.


Carregamento de dados de padrões

No segundo exemplo Sample2_SOM_Net_Data, é mostrada conexão da seguinte extensão de funcionalidade, isto é, a classe CSOM_Net_Data. A classe é declarada como um descendente da classe CSOM_Net_Base, por isso ela pode utilizar, além de suas funções, todas as funções do antepassado. A classe é criada para introduzir, no funcional, um analisador para carregar padrões. Os padrões obtidos pelo analisador podem posteriormente ser usados para baixar tanto os padrões de aprendizagem quanto os padrão para reconhecimento.

O nome do arquivo com padrões é definido pelo parâmetro:

input string DataFileName="SOM\\optim.csv";

Preste atenção, o nome do arquivo é especificado com uma extensão, ou seja, o nome completo do arquivo. O arquivo é aberto pelo analisador como arquivo com a bandeira FILE_CSV.

A seguir, são chamadas as funções como no exemplo anterior: carregamento da rede, carregamento do arquivo, análise de arquivo, reconhecimento no ciclo de padrões e saída para exibição.

Aqui é necessário considerar o formato de arquivo com os padrões para o qual foi criado o analisador.

A primeira cadeia de caracteres do arquivo deve ser preenchida com os nomes de coluna Title. Este é um pré-requisito, se o cabeçalho do arquivo não for preenchido, o analisador irá cortar o exemplo acima localizado na primeira cadeia e criará a partir dele os nomes das colunas.

Arquivo com padrões

As colunas no arquivo são usadas para armazenar dados de padrões de uma profundidade. Por conseguinte, a cadeia de caracteres são utilizadas para armazenar padrões individuais. Em outras palavras, os vectores são dispostos horizontalmente, enquanto os mesmos campos de todos os vetores, verticalmente.

Ao trabalhar, o analisador não só coloca os dados dos padrões em todas as matrizes em linha m_patterns_sets_array, más também reconhece os cabeçalhos dos campos, armazena-os na matriz m_som_titles (declarada na classe ancestral) e preenche com números as cadeias da matriz m_patterns_titles. Desse modo, não é difícil encontrar o padrão necessário no arquivo segundo sua cadeia de caracteres.


Aprendizagem da rede

O terceiro exemplo Sample3_SOM_Net_Train é o mais interessante. Em primeiro lugar, à ele está ligado a segunda classe base - CSOM_Net_Train -, isto é, a classe de aprendizagem de mapas de Kohonen. Em segundo lugar, está é a última classe, ela é suficiente para uma aprendizagem automática sem visualização; as seguintes classes apenas ligam o shell gráfico. Isto é, tudo o que foi descrito na seção "Teoria de mapas de Kohonen" foi implementado nas primeiras três classes. Em terceiro lugar, na classe foi organizado uma bifurcação de herança.

Para as seguintes classes é necessário que na função de aprendizagem da rede Train() sejam chamadas as funções de cálculo e desenho de imagens bmp que exibem as etapas de aprendizagem. Mas, como no terceiro exemplo, não há gráficos, então não são necessários os corpo destas funções. Para resolver esta contradição, as funções Render() e ShowBMP(bool back) são declaradas como virtuais (virtual) e têm corpos vazios, enquanto o código exigido é definido no descendente CSOM_Net_Img.

Vamos agora seguir diretamente para o treinamento. Os parâmetros devem ser enviados para a rede antes do treino. Para o efeito, existe a função de serviço InitParameters(int iterations,int xcells,int ycells), nela são transferidos os parâmetros: número de iterações de aprendizagem - iterations - e tamanho da rede dividida em dois parâmetros, isto é, xcells, ycells (tamanhos em X e Y respetivamente).

O ciclo de aprendizagem é organizado na função Train(). É necessário inicializar a rede antes de chamar o ciclo de aprendizagem. Isso implica inicializar a classe de números igualmente distribuídos, definir os tamanhos de matriz, calcular os valores máximos e mínimos usando as colunas dos padrões, inicializar os nós com dados aleatórios a partir do intervalo definido.

A iteração de aprendizagem é especificamente transformada em uma função separada -TrainIterations(int &p_iter) - para uma melhor compreensão do código e mais fácil acesso ao finalizar. Essa implementação foi escrita para que outros programadores pudessem entender a essência do trabalho e fazer suas próprias alterações, se necessário. A função contém o algoritmo descrito na seção "Teoria de mapas de Kohonen", portanto, não há nenhuma necessidade de explicá-la mais uma vez.

Em geral, o terceiro exemplo mostra a lógica de conexão de rede a partir da classe CSOM_Net_Train: carregar um arquivo com padrões de aprendizagem, enviar parâmetros, chamar a aprendizagem, salvar a rede em um arquivo.

Ao descrever a função de leitura do arquivo de rede, que foi mencionada acima, as funções de armazenamento e leitura devem ser consideradas simultaneamente a fim de compreender o formato.

void CSOM_Net_Train::SaveNet(string file_name)
bool CSOM_Net_Base::DownloadNet(string file_name)

Representação binária do arquivo somnet

Entre este tipo de dados de rede, o tipo double prevalece. Por conseguinte, a rede é armazenada em uma matriz unidimensional do tipo double. Os dados restantes são deste tipo.

Para iniciar, o cabeçalho é mantido na rede. Estes são os cinco primeiros campos double, em que são armazenados os dados necessários da rede.

  1. 6+dimension_node — comprimento do padrão mais 6 (seis campos adicionais necessários no nó de coordenadas de armazenamento).
  2. m_xcells — número de nós na horizontal.
  3. m_ycells — número de nós na vertical.
  4. m_xsize — tamanho bmp na horizontal.
  5. m_ysize — tamanho bmp na vertical.

Em seguida, é executada a cópia na rede de nó. Primeiro, 6 dados de coordenadas de nó, em seguida, o peso do nó. Assim, são copiados todos os dados, nó por nó.

No final, a cadeia de caracteres com a enumeração Titles é adicionada à rede e transferida de modo binário para o formato double.

Então, o que obtemos. A partir do cabeçalho sabemos o tamanho do padrão e o número de nós. Estes dados podem ser usados para calcular onde começam e terminam os dados de nó. Desde o ponto final do nó até o fim do arquivo, são armazenados os Titles da rede. Eles são colocados no final do ficheiro, uma vez que é impossível de antecipar, a quantidade de memória que necessitam.


Shell gráfico

No quarto exemplo, Sample4_SOM_Net_Img é exibida a conexão do shell gráfico. Para chamá-la, no artigo anterior, era necessária conexão da biblioteca gráfica cintbmp.mqh, criada por Dmitry Fedoseev. No entanto, eu tive que modificá-la de modo que todas as chamadas WinAPI DLL fossem excluídas. Isso permite o uso do código no Mercado. No arquivo atualizado, foram armazenadas as informações sobre o autor, vale a pena dizer que mudei o nome para cintbmp2.mqh.

No código, foram alteradas apenas as funções de armazenamento de arquivo no diretório Image, a partir do qual, geralmente, são carregados os arquivos bmp. Agora os arquivos são armazenados apenas ao salvar e não para exibição. Para exibição eles são imediatamente carregados nos recursos. Isso ajuda a evitar chamar bibliotecas DLL.

A seqüência de chamada de funções é semelhante ao exemplo anterior. Mas, como agora está conectado o shell gráfico, são necessários parâmetros de configuração adicionais para seu funcionamento. É por isso que a função de inicialização, atualizada na anterior classe ancestral, foi sobrecarregada para acomodar os novos parâmetros para o shell gráfico.

void   InitParameters(int iterations,int xcells,int ycells,
                       int bmpwidth,int bmpheight,
                       bool p_HexagonalCell,bool p_ShowBorders,bool p_ShowTitles,
                       int p_ColorScheme,int p_MaxPictures);

Os parâmetros são enviados através da interface de funções para que no código de classes não fiquem variáveis declaradas de modo global. Isso dificultaria a conexão a projetos paralelos, onde os nomes das variáveis podem ser outros.

Agora é executada a chamada da função de aprendizagem Train() a partir da instância da classe CSOM_Net_Train. No entanto, como agora nos corpos das funções Render() e ShowBMP(bool back) existe um código de trabalho com o gráfico, é executada a exibição do processo de aprendizage para cada centésima interação. Após a saída da função Train(), estas funções são chamadas para exibição das últimas alterações.

Fim da aprendizagem


Expansão da funcionalidade

No quinto exemplo Sample5_SOM_Net_Player é mostrado um modelo de expansão de classes. Ele apenas mostra como modificar o código existente, e não faz parte da base da rede. Para levar a cabo esse tipo de modificações, basta declarar a classe como um descendente de uma das classes básicas.

Por que é necessário escrever uma classe-descendente? Para que nela estejam disponíveis todos os comandos escondidos protected da função de todas as classes, a partir da qual a nossa classes é herdada. Por exemplo, após a conexão como descendete da classe CSOM_Net_Img, nós obtemos o acesso a todas as funções e dados declarados como protected e public de todas as classes anteriores. Assim, é possível compor o programa de acordo a seu critério, dependendo do que você queira obter.

A expansão da classe CSOM_Net_ Player consiste em um painel gráfico de controle de rede neural Kohonen. Para sua criação, liguei o arquivo IncGUI_v3.mqh à biblioteca gráfica do Dmitry Fedoseev, introduzindo pequenas modificações. As modificações abrangem a saída das etiquetas gráficas (não de lado, senão acima dos objetos) e as cores delas. Eu não fiz alterações no arquivo original, senão só declarei os herdeiros a partir das classes da biblioteca.

Embora a criação do painel gráfico ocupa a maior parte do código, é simples de fazer. Quero fazer enfase na organização da interação - de painel gráfico - entre a rede neural de Kohonen e o shell gráfico.

A primeira coisa que eu gostaria de salientar é que a execução da rede é dividida em duas partes. A primeira parte realiza a aprendizagem e armazena a rede treinada no arquivo binário somnet. A segunda parte carrega a rede a partir do arquivo, e busca pelos padrões carregados códigos adequados. Ambas as partes são independentes, embora elas usem as mesmas caixas de edição de dados: caixa de edição de caminho para o arquivo com padrões, caixa de edição de caminho para o arquivo com rede neural.

No entanto, os regimes são realmente independentes. Não necessariamente os padrões para aprendizagem são tomados a partir do arquivo para reconhecimento. O mesmo acontece com a rede neural. Você pode treinar a rede em um único arquivo, em seguida, mudar o modo para "operacional" e baixar outra rede para reconhecimento.

Importante: a alternância de modos redefine os modos para estado zero.

Assim, os modos são independentes. Como foi possível alcançar a resposta rápida do programa para alterar o estado dos botões? A coisa é que o programa não usa padrões de ciclos para a aprendizagem e pesquisa. No entanto, o ciclo é organizado nos acontecimentos.

Quando o programa entra em modo de aprendizagem, ele faz a inicialização, carga de padrões, preparação da memória e a primeira interação, após isso, envia, para si próprio, o evento de usuário número 333. A entrada para o manipulador de eventos é filtrada com o clique do mouse sobre o objeto, com a conclusão da edição do objeto e com o evento de usuário 333.

Assim, se não houver interrupção (se, por um lado, não for alterado o estado dos botões "Start" e "Aprendizagem" e, por outro, nós ainda tivermos acesso à aprendizagem), acontece uma nova iteração da aprendizagem e o envio da nova mensagem 333, até que a rede não seja treinada, interrompendo o ciclo em si, ou os botões de usuário não parem a aprendizagem.

Esse mesmo esquema de interrupção é implementada no modo de busca padrão.

Eu tentei fazer com que a interface do painel ficasse intuitiva. Basicamente ela repete input variáveis ​dos exemplos anteriores. Ainda assim, mostramos o valor de alguns dos botões e caixas de edição:


Para a execução do painel é necessário:

  • Organizar, por diretórios, os arquivos do arquivo zip.
  • Organizar os arquivos com padrões no diretório MQL5\Files\SOM\.
  • Organizar os arquivo com imagens bmp de botões no diretório MQL5\Images\SOM\.
  • Organizar os arquivos com programas no diretório MQL5\Projects\SOM\.
  • Executar a compilação de todos os arquivos mq5.


Conclusão

Há quarenta anos, as redes neurais foram a vanguarda do pensamento científico. Ainda há vinte anos, as pessoas familiarizadas com algoritmos de redes neurais eram consideradas peritos únicos. Agora ninguém tem medo de o nome "rede neural". Os algoritmos de lógica difusa (fuzzy) e redes neurais se tornaram parte da negociação e, ao que parece, não são tão complicados. Espero que este artigo seja de ajuda para dissipar ainda mais a aura de mistério e começar a usar os mapas de Kohonen.

Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/2043

Arquivos anexados |
project_som.zip (267.78 KB)
Tratamento de erros e registro em log na MQL5 Tratamento de erros e registro em log na MQL5
Este artigo aborda questões sobre o tratamento de erros comuns no software. Além disso, trata do registro em log e monstra uma forma de empregar o registrador de logs via MQL5.
Interfaces Gráficas IV: O Modo Multi-Janela e o Sistema de Prioridades (Capítulo 2) Interfaces Gráficas IV: O Modo Multi-Janela e o Sistema de Prioridades (Capítulo 2)
Neste capítulo, nós vamos estender a implementação da biblioteca para possibilitar a criação de interfaces de multi-janela para as aplicações MQL. Nós também vamos desenvolver um sistema de prioridades para clique esquerdo do mouse sobre os objetos gráficos. Isso se faz necessário para evitar problemas quando os elementos não respondem as ações do usuário.
Expert Advisor Universal: Integração com os Módulos de Sinais Padrão do MetaTrader (parte 7) Expert Advisor Universal: Integração com os Módulos de Sinais Padrão do MetaTrader (parte 7)
Esta parte do artigo descreve as possibilidades de integração do motor CStrategy com os módulos de sinais incluídos na biblioteca padrão no MetaTrader. O artigo descreve como trabalhar com sinais, assim como demonstra uma forma de criar estratégias personalizadas com base nas mesmas.
Interfaces Gráficas IV: Elementos Informativos da Interface (Capítulo 1) Interfaces Gráficas IV: Elementos Informativos da Interface (Capítulo 1)
No atual estágio de desenvolvimento, a biblioteca para a criação de interfaces gráficas contém um formulário e vários controles que podem ser ligados a ele. Foi mencionado antes que um dos artigos futuros seria dedicado ao modo multi-janela. Agora, nós já temos tudo preparado para considerar tal questão, desse modo, nós vamos lidar com isso no capítulo seguinte. Neste capítulo, nós vamos escrever as classes para criar os elementos de interface barra de status e dica de contexto.