preview
Do básico ao intermediário: Operadores

Do básico ao intermediário: Operadores

MetaTrader 5Exemplos | 7 agosto 2024, 15:35
28 0
CODE X
CODE X

Introdução

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

No artigo anterior Do básico ao intermediário: Variáveis (III), foi explicado um pouco sobre variáveis predefinidas. Assim como também foi demonstrado uma maneira bastante interessante de se interpretar funções. Porém tudo que foi explicado até este momento esbarra em uma questão. E esta é justamente uma das maiores dificuldades encontrada por parte de novos programadores. Principalmente quem visa fazer pequenos trabalhos voltadas para uso pessoal. Tal dificuldade nasce justamente por conta de existir tipos diferentes de dados.

Como foi explicado, de maneira bastante breve, no artigo Do básico ao intermediário: Variáveis (II), no MQL5 existem uma classificação de dados em termos de tipos que podem ser utilizados. No entanto, para que a explicação sobre tipos de dados, pudesse ser de fato dada de maneira adequada. Precisamos fazer isto dentro de um determinado contexto. E é justamente este o tema principal deste artigo. Ou seja, operadores básicos. Que é o que cria o contexto necessário para que possamos falar sobre tipos de dados.

Sei que muitos irão achar que o tema a ser visto aqui, é simples e totalmente desnecessário falar sobre o mesmo. No entanto, justamente por ser um tema aparentemente desnecessário, é que o mesmo se torna imprescindível. Já que muitas falhas de código, nasce justamente pelo mal entendimento sobre o tema em questão.

Assim sem mais delongas, vamos iniciar o que será o primeiro tópico deste artigo.


Tipos de dados e operadores

Em linguagem não tipadas, falar sobre operadores e tipos de dados, muitas vezes é algo completamente desnecessário. Já que uma operação do tipo 10 dividido por 3, irá gerar um resultado adequado. Porém em uma linguagem tipada, como é o caso do MQL5, assim como C e C++. Esta simples operação de divisão, não tem uma resposta, mas duas respostas completamente diferente. E em alguns casos, pode haver mais de duas respostas. Mas isto será tratado em outro momento mais oportuno. Para o que iremos ver e pretendo tratar aqui, podemos focar apenas na possibilidade de haver duas respostas.

Espera um pouco. Como assim duas respostas? Você está maluco ou está viajando na maionese? Pois toda a vez que dividimos 10 por 3 iremos encontrar a resposta que é 3.3333... e não uma outra resposta qualquer. Bem meu caro leitor, se você pensa assim, então este artigo definitivamente é para você. E por isto ele foi criado. Justamente para explicar que as coisas, quando se fala em programação, não são bem assim como muitos pensam.

Para iniciar, vamos fazer algo um pouco mais simples do que gerar um valor que seria uma dizima periódica. Mas que ainda assim, poderá gerar duas respostas completamente diferentes entre si. Para exemplificar isto, vamos ver um código bastante simples. Este é mostrado logo abaixo.

1. //+------------------------------------------------------------------+
2. #property copyright "Daniel Jose"
3. //+------------------------------------------------------------------+
4. void OnStart(void)
5. {
6.     Print(5 / 2);
7. }
8. //+------------------------------------------------------------------+

Código 01

Este código 01, que é extremamente simples irá servir para ilustrar algo muito interessante. Porém que causa uma tremenda de uma confusão. Acredito que você, meu caro leitor, deve saber o resultado desta operação que está sendo feita na linha seis. Isto sem olhar o resultado que será mostrado no terminal do MetaTrader 5. Mas duvido, que você sabe qual é o valor que será mostrado. Isto por que existe uma dependência do tipo a ser utilizado na resposta. Obviamente o resultado esperado é 2.5. Porém se você executar este código 01 irá ver que o terminal imprimirá o valor dois. Por que? Será que o computador não sabe como calcular esta simples expressão? Bem, a resposta para esta pergunta é: NÃO. O computador não sabe fazer contas. Na verdade, o computador é muito bom para efetuar somas. Porém é péssimo para todas demais operações.

Cara você está querendo fazer uma pegadinha com todos nós. Só pode. Porém, apesar de aparentemente ser uma pegadinha. O que estou dizendo é um fato real. Computadores NÃO sabem fazer nenhuma operação que não seja somar. E mesmo assim existe um problema. Isto por que se você o mandar somar duas frações ele, muito provavelmente não conseguirá lhe apresentar o resultado correto. E tudo isto tem a ver com a forma como os valores são representados dentro da memória do computador.

Computadores entendem apenas zeros e uns. Ou ligado e desligado. Ele não sabe a diferença de dois para três, ou qualquer coisa do tipo. Ele apenas trabalha com a conhecida lógica booleana. E ao fazer isto de uma determinada maneira, ele consegue efetuar os cálculos que repassamos a ele. Ok, mas se eu digitar em uma calculadora 5 dividido por 2 irei conseguir a resposta 2.5. Porém não entendo por que ao fazer isto aqui no MQL5, estou tendo como resposta dois. E não 2.5.

É justamente neste ponto que entra a questão do tipo de dados meu caro leitor. Nesta linha seis, ambos dos dados são do tipo inteiro. Assim o compilador irá considerar que a resposta a ser dada, deverá ser do tipo inteiro. Porém para a calculadora, a resposta pode ser do tipo inteiro ou do tipo, conhecido em programação, como ponto flutuante. Mas é neste ponto que a coisa fica confusa, para muitos. Já que linguagens não tipadas irá lhe dar sempre a mesma resposta. Porém linguagens tipadas irão lhe dar mais de uma resposta. E tudo depende, de você, como programador dizer qual tipo deverá ser utilizado na resposta.

Então, uma forma de corrigir o código 01, a fim de que a resposta seja 2.5 é usando o código logo abaixo.

1. //+------------------------------------------------------------------+
2. #property copyright "Daniel Jose"
3. //+------------------------------------------------------------------+
4. void OnStart(void)
5. {
6.     Print((double)(5 / 2));
7. }
8. //+------------------------------------------------------------------+

Código 02

Ao fazermos as mudanças que você pode ver no código 02. A resposta passará a ser uma somente. E isto que foi feito é conhecido como TYPECASTING, ou conversão de tipo. Existe toda uma explicação para isto dentro da documentação do MQL5. Mas também de outras linguagens.

No caso do MQL5 você pode ver a explicação olhando Conversão de tipo. Lá existe algumas imagens que ajudarão você a entender como esta conversão é feita de maneira implícita em direção a um tipo mais complexo. No caso todos tendem ao tipo double. Uma destas imagens pode ser vista logo abaixo.


Imagem 01

Como na documentação este tipo de coisa está muito bem esclarecido. Pelo menos no que rege mostrar como os dados podem ser escalonados entre si. Não é necessário entrar em detalhes aqui, sobre o que está sendo explicado lá. Porém uma dúvida pode surgir em pessoas mais curiosas e que querem entender os detalhes envolvidos nesta conversão de tipos. Que é justamente: Por que isto acontece?

Entender isto, irá lhe permitir compreender diversas outras coisas meu caro leitor. Como por exemplo: Por que quando fazemos alguma operação entre dois valores, as vezes não conseguimos a resposta correta. Mas sim uma resposta que não faz muito sentido. E outras vezes a resposta está correta, mas quando vou usar ela, a mesma aparentemente fica incorreta.

Este tipo de coisa de fato ocorre, e está diretamente ligado ao como os dados são representados dentro da memória do computador. Mas para explicar isto de maneira adequada, vamos para um novo tópico.


Largura de bits

No final do artigo Do básico ao intermediário: Variáveis (II), foi visto uma pequena tabela. Ali é mostrado o limite para cada valor que pode ser representado na memória do computador. Mas existe um detalhe: Valores do tipo ponto flutuante, double e float, não são representados da mesma maneira que valores inteiros. Como por exemplo int, ou ushort. Então o que será explicado aqui neste momento diz respeito a somente valores do tipo inteiro. A questão referente aos valores de ponto flutuante, serão tratados em outro momento. Já que é necessária toda uma explicação para compreender de fato como eles funcionam e por que é perigoso confiar cegamente em um valor calculado pelo computador. Isto quando envolve valores do tipo ponto flutuante.

Mas vamos entender primeiro a questão dos valores inteiros. Primeiramente, todos eles podem ser resumidos a sua entidade mais básica. Ou seja, bits. O maior valor que pode ser representado por algum tipo é o equivalente a dois, elevado ao número de bits presentes na representação. Por exemplo: Se você tem quatro bits sendo utilizados, você pode representar 16 valores diferentes. Se você tem 10 bits pode representar 1024 valores, e assim por diante.

Porém isto se aplica somente a valores positivos. Valores negativos sofrem uma pequena defasagem nesta contagem. Neste caso, quando tratamos de valores negativos, o range que pode ser representado irá ser de dois elevado o número de bits menos um. Até o mesmo valor, só que negativo menos um. Parece um pouco confuso. Mas é bem simples de entender na prática. Por exemplo com os mesmos quatro bits, só que desta vez representado valores tanto positivos quanto negativos. Teríamos a possibilidade de ir de -8 até 7. No caso de 10 bits poderíamos ir de -512 até 511. Mas espere um pouco. Se ignorarmos o fato de o valor ser negativo e somarmos ambos, 8 mais 7 são 15 e não 16, como foi mencionado acima. Assim com 512 somado com 511 são 1023 e não 1024. Por que desta diferença? O motivo é o zero meu caro leitor. O valor quando você soma 8 com 7, você estará somando os valores possíveis. Porém o zero, não é contabilizado nesta soma. Ocupando assim uma posição.

Para tornar isto bastante claro, precisaremos entender como os valores negativos são representados na memória. Para isto vamos usar a imagem logo abaixo, para explicar isto com mais clareza.


Imagem 02

Aqui temos o que seria um valor do tipo uchar ou char. Já que temos 8 bits sendo mostrados. Porém a diferença entre um valor uchar e um valor char, é justamente o que estará no bit MSB, ou bit mais significativo. No caso de valores uchar, onde todos os valores são positivos, isto por conta do u que está sendo o prefixo do tipo. O MSB não representa problema. Já que os valores, são sempre positivos. Por isto, podemos contar de 0 até 255. Totalizando 256 valores possíveis de serem representados. Porém quando estamos usando um tipo char. O MSB indica se o valor é negativo ou positivo. Quando o MSB for igual a um, temos valores negativos. Quando o MSB for igual a zero, temos valores positivos. Justamente por conta disto, iremos poder contar de 0 até 127. Porém como o zero não tem sinal, e podemos ter apenas o MSB ligado. Indicamos isto como sendo o valor -128, e não zero negativo, já que isto não existe. Por isto que em valores negativos a contagem sempre terá um valor extra, além da metade dos valores possíveis.

Interessante esta questão não é mesmo meu caro leitor? Mas fica ainda mais. Pois se você entendeu esta explicação acima, logo consegue entender como a função ABS, ou MathAbs, presente em diversas linguagens consegue transformar um valor negativo em um valor positivo e vice-versa. Basta que mudemos o MSB e termos a troca sendo efetivada.

Mas existe um pequeno problema, se você não prestar atenção ao que estará sendo feito. Pois se você somar dois valores, por exemplo: 100 com 40, que são positivos, poderá obter um valor negativo. Mas que doideira é esta que você está me dizendo? Como assim, se estamos somando valores positivos, obviamente teríamos uma resposta positiva. Jamais poderíamos ter um valor negativo sendo representado nesta soma. Bem meu caro leitor, quando o assunto é computação, nem sempre a verdade é o que o senso comum nós diz. Para que isto fique claro vamos usar o seguinte código mostrado abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     char    value1 = 100,
07.             value2 = 40,
08.             Result;
09. 
10.     Result = value1 + value2;
11.     Print(value1, " + ", value2, " = ", Result);
12. }
13. //+------------------------------------------------------------------+

Código 03

Ao executar este código você irá ver o resultado mostrado abaixo.


Imagem 03

Pela santa virgem Maria. Que coisa mais bizarra é esta? Isto é IMPOSSÍVEL. Não meu caro leitor, isto definitivamente não é impossível. Isto tem tudo a ver como o motivo pelo qual este artigo precisou ser escrito. Você precisa entender que se a linguagem é tipada. Fazer a escolha correta do tipo irá influenciar no resultado que estará sendo calculado. Muita gente, costuma ter serias dificuldades na programação, justamente por não entender isto que estou lhe mostrando. E muitos são enganados justamente por desconhecer estas questões, que aparamente são simples. Mas que sem o devido conhecimento, você ficará a mercê de falsas promessas de segurança.

Ok. Neste caso você pode estar pensando: Tudo bem, estamos usando um tipo que pode representar até 127 para valores positivos e -128 para valores negativos. Não seria o ideal usar um tipo maior. Como por exemplo um tipo int, que ao invés de 8 bits tem 32 bits? Sim meu caro leitor. Mas não é este o problema aqui. O problema é que em algum momento, o limite, ou valor máximo que pode ser representado irá ser atingido. E quando isto ocorrer a contagem irá falhar de alguma maneira. E olha que ainda estamos trabalhando apenas e somente com os tipos inteiros. Os de ponto flutuante ainda são mais complicados de entender.

Assim sendo você precisa de fato, entender os inteiros antes de entender os de ponto flutuante. Mas existe uma questão, que vale mencionar neste momento. Que é a impossibilidade de se trabalhar com um tipo maior a todo instante. Isto ocorre muito quando estamos tratando de strings. Pois é justamente neste ponto que a coisa fica complicada. Pois strings, ou cadeia de caracteres. Podem tanto usar 16 bits como 8 bits. Normalmente, salvo em momentos específicos, computadores usam o que é conhecida como tabela ASCII. Esta tabela de 8 bits foi criada nos primórdios da computação. Porém como ela não era adequada para representar certos caracteres, foi necessário criar outros tipos de tabelas. Daí o fato de que alguns programas, usam 16 bits para se escrever textos. Mas o fato de usar 16 bits, apenas muda o MSB para o bit de número 15. E isto não faz com que tenhamos um número infinito de possibilidades. Apenas faz com que deixemos de usar 256 valores para podermos usar 65356 valores diferentes.

Porém ainda assim, uma string nada mais é do que um array de valores mais simples. Só que com um valor muito maior podendo ser representado. Como por exemplo, você pode criar um valor de 128 bits usando o MQL5. Mesmo que o maior valor possível seja quando usamos o tipo ulong, que é um tipo de 64 bits. Mas como podemos fazer tal coisa? Simples meu caro leitor. Se você conhece os valores para cada bit ligado ou desligado dentro de uma sequência de bits. Tudo que você precisa fazer é somar os valores que os bits ligados representam. Ao fazer isto, algo mágico acontece. Pois passamos a poder representar qualquer valor imaginável.

Por isto ao somar 100 com 40, como foi feito no código 03 obtemos o valor de -116. Isto por que, este valor -116, representa o valor de 140 positivo. O que parece bastante doido a princípio. Mas olhando os valores em binário, você iria ver o seguinte:


Imagem 04

Ou seja, o mesmo valor que em um caso é interpretado como sendo positivo em outro é interpretado como sendo negativo. Justamente por conta do MSB. Por isto tome cuidado, principalmente quando for criar laços. Isto por conta justamente deste tipo de coisa. Sem o devido cuidado, tanto cálculos como também laços podem fazer o seu programa ficar completamente maluco. Mesmo que aparentemente tudo esteja devidamente sendo calculado. Mas por falhas na escolha do tipo, ou no limite máximo que o tipo comporta. A coisa pode sair do controle.

Muito bem, mas foi mencionando em algum momento que poderíamos usar um tipo maior para resolver este mesmo problema. Por que este tipo de solução funciona em alguns casos, enquanto em outros não funciona? Bem, isto se deve justamente ao fato de que o MSB estaria sendo deslocado. Como você pode ver na imagem logo abaixo.


Imagem 05

Algo bem simples de entender não é mesmo? Ok. Com relação ao básico sobre operações é isto que podemos mencionar neste momento. Mas tudo que foi visto até aqui está ligado ao fato de estamos trabalhando com operadores aritméticos. No entanto existe uma outra classe de operadores. Que são os operadores lógicos. Para explicar estes e tornar as coisas devidamente separadas, vamos a um novo tópico.


Operadores lógicos

Um operador lógico trabalha no âmbito dos bits. Apesar de em diversos momentos podermos usar bytes ou conjuntos inteiros de bits em operações lógicas. Normalmente este tipo de operador deverá ser pensado, isto a princípio, sendo voltado para trabalhar com bits e não bytes. Isto talvez possa ser um tanto quanto confuso. Mas com o tempo, você notará que faz algum sentido. Isto por que, diferente dos operadores aritméticos, que visam calcular algo. Operadores lógicos visam testar algo. Normalmente o teste é feito a fim de verificar se valores correspondem ou não a algum tipo de condição. Como estes operadores fazem mais sentido quando usados junto de outros comandos. Aqui iremos apenas dar uma rápida passada por eles. Isto para que você comece a se preparar para o que será visto em breve.

No entanto, mesmo que eles façam mais sentido, junto de outros comandos. Podemos sim usar operadores lógicos para efetuar pequenas operações. Para falar a verdade, qualquer operação em uma CPU, é de fato uma operação que envolve mais lógica do que necessariamente aritmética. Apesar de que a parte principal e mais importante de uma CPU se chamar ALU. Ou Unidade Lógica e Aritmética. Isto por que ela é a principal responsável pelo fato da CPU funcionar.

Então basicamente dentro dos operadores lógicos temos a operação AND, a operação OR, a operação NOT e em muitas linguagens, mas não em todas, a operação XOR. Além destes temos a operação de deslocamento para a direita e deslocamento para a esquerda. Com base nestas simples operações podemos desenvolver diversas coisas. Para ser sincero, podemos fazer qualquer coisa possível e imaginável. Tanto que é com base nisto que uma ALU que é a mente da CPU trabalha.

Neste exato momento você pode estar olhando a documentação do MQL5, ou de outra linguagem e estar pensando: Mas existem mais operadores lógicos, como maior e menor. Entre outros presentes nesta ou naquela linguagem. Sim meu caro leitor. Algumas linguagens implementam mais tipos de operadores, ou funções de comparação lógica. No entanto, apesar disto, muitas destas operações, em termos de ALU, são bem mais simples do que aquilo que muitas linguagens implementam. E não me entenda mal. Não é que acho errado ou desnecessário tais coisas serem implementadas. Muito pelo contrário. Elas são implementadas como forma de tornar parte do trabalho de programação mais simples. Por exemplo: Se você quer compara um valor com outro, a forma mais simples de fazer isto é subtrair um valor pelo outro. Mas existe uma outra forma, que seria aplicando uma operação XOR bit a bit. Se todos os bits forem iguais, o valor final será igual a zero. Se algum bit for diferente, podemos estar diante de um valor que seja maior ou menor que o outro. Porém quando efetuamos a subtração, e temos uma forma de analisar o MSB, podemos verificar se o resultado foi zero, menor que zero ou maior que zero. Dependendo deste valor, saberemos se estamos lidando com um valor maior, menor ou igual ao outro.

Para que isto fique claro, vamos ver um exemplo bem simples de comparação. A fim de descobrir se um valor é maior, menor ou igual ao outro. Para isto, vamos usar o código logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     short   value1 = 230,
07.             value2 = 250;
08. 
09.     Print("Result #1: ", value1 - value2);
10.     Print("Result #2: ", value2 - value1);
11.     Print("Result #3: ", value2 ^ value1);
12. }
13. //+------------------------------------------------------------------+

Código 04

Aqui temos um típico e simples sistema de análise de valores. Quando este código for executado, você verá no terminal o seguinte resultado:


Imagem 06

Agora preste atenção para entender o que foi dito a pouco, sobre saber se um valor é maior, menor ou igual. Para tornar as coisas interessantes, estamos usando um tipo de valor cuja largura é de 16 bits. Isto nos permite ter 65536 valores diferentes. No entanto por ele ser um valor sinalizado. Ou seja, que permite ter valores negativos e positivos. Iremos ter uma variação que irá de -32768 até 32767. Porém se nos mantivermos analisando valores de um range de 8 bits não teremos problemas em saber se o valor é maior, menor ou igual um ao outro. Porém diferente do que seria possível usando apenas 8 bits, aqui podermos usar valores que poderão ir de -255 até 255. O que é excelente. No entanto, existem forma de tornar isto ainda melhor. Mas não iremos entrar em detalhes disto por hora. Isto por que seria necessário que você soubesse de algumas coisas, que não foram ainda explicadas. No entanto, ainda assim este código 04 é bastante interessante e divertido.

Então vamos entender o que ocorreu aqui. Como value1 é nitidamente menor que value2. Quando subtraímos um do outro, o primeiro resultado será negativo. Nos dizendo que de fato o primeiro é menor. Isto é feito pela linha nove do código 04. No entanto, quando subtraímos o value2 de value1, e isto na linha dez, o valor é positivo, nos dizendo que value2 é maior que value1. Assim como na linha onze. Só que neste caso, o teste que está sendo feito é se os valores são iguais. Como o resultado é diferente de zero, sabemos com toda a certeza que os valores não são iguais.

De fato, este tipo de coisa é muito interessante. E fica mais divertido ainda, quando você passa a compreender que não existe uma operação de subtração dentro da ALU. Na verdade toda e qualquer operação que será feita ali, será sempre uma operação de soma. Junto com outras operações lógicas. E mesmo a própria operação de soma, se resume em sua mais profunda essência em operações lógicas.

Porém, toda via e, entretanto, para demonstrar isto, iremos precisar usar algumas funções de controle. E como ainda não foi explicado nenhuma função de controle de código. Não iremos, neste artigo, demonstrar como seria feito, em nível de ALU, o que é mostrado no código 04. Mas em breve, poderemos fazer isto. Pois é algo que se você entender como fazer, irá lhe permitir usar o MQL5, para algo ainda mais sensacional do que criar indicadores, scripts e Expert Advisores.

Ainda não sei se irei mostrar como implementar algo deste tipo. Já que o objetivo aqui, é pura e simplesmente a didática. Mas vou pensar.

Ok, ainda ficou faltando os operadores de deslocamento para serem apresentados de maneira adequada. Já que na documentação do MQL5, os mesmos praticamente são apenas mencionados. Mas de certa forma, tais operadores tem um objetivo muito focado em determinadas tarefas. Sendo muito pouco utilizados em grande parte das atividades normais de um código em MQL5. Principalmente os voltados a trabalhar em indicadores e Expert Advisores. Porém quando trabalhamos com imagens dentro de uma aplicação feita em MQL5, tais operadores são de fato bem mais utilizados.

No entanto, mesmo sendo voltados para atividades muito especificas, ainda assim existem forma de os utilizar para outras coisas. Entre estas uma que veremos assim que for explicado como trabalhar com funções de controle.


Considerações finais

Neste artigo, tratamos de entrar em certos detalhes da programação, que de fato fazem muita diferença quando trabalhamos em uma linguagem que faz uso de tipos na classificação dos dados. No entanto, mesmo que tenhamos visto coisas que para muitos possa ser novidade. Aqui apenas arranhei parte do que existe disponível sobre este assunto. Então meu caro leitor, fica a dica do seguinte: Procure estudar a documentação básica do MQL5, a fim de entender melhor alguns dos conceitos mostrados aqui. Além disto, vale também muito a pena você procurar estudar um pouco sobre lógica booleana. Isto por que, ao contrário do que possa parecer. Entender a lógica booleana, que é bastante simples, diga-se de passagem. Irá lhe ajudar a simplificar muitos dos cálculos que você normalmente precisará fazer em seus códigos. Entender quando um valor é ou não positivo ou negativo, e saber trabalhar com esta nuances faz toda a diferença no logo prazo.

No anexo, irei deixar, três dos quatro códigos vistos aqui. Assim você poderá estudar os mesmos com mais calma. E no próximo artigo, começaremos a tratar das funções, ou operadores de controle. Aí sim, as coisas irão ficar muito mais divertidas e a brincadeira começará a tomar forma e corpo. Então até breve.

Arquivos anexados |
Anexo.zip (0.98 KB)
Rede neural na prática: Esboçando um neurônio Rede neural na prática: Esboçando um neurônio
Neste artigo, faremos a confecção de um neurônio básico. Apesar de ele ser algo simples, e muitos acharem que o código é totalmente bobo e sem nenhum propósito. Quero que você, meu caro leitor, e entusiasta pelo tema de redes neurais. Brinque e se divirta estudando este simples esboço de neurônio. Não precisa ficar com receio de mexer no código a fim de entender o mesmo.
O escore de propensão na inferência causalidade O escore de propensão na inferência causalidade
O artigo examina o tema de pareamento na inferência causal. O pareamento é utilizado para comparar observações semelhantes em um conjunto de dados. Isso é necessário para determinar corretamente os efeitos causais e eliminar o viés. O autor explica como isso ajuda na construção de sistemas de negociação baseados em aprendizado de máquina, que se tornam mais estáveis em novos dados nos quais não foram treinados. O escore de propensão desempenha um papel central e é amplamente utilizado na inferência causal.
Desenvolvendo um EA multimoeda (Parte 5): tamanho de posição variável Desenvolvendo um EA multimoeda (Parte 5): tamanho de posição variável
Nos capítulos anteriores, o EA desenvolvido só podia usar um tamanho de posição fixo para negociações. Isso é adequado para testes, mas não é aconselhável ao negociar mediante uma conta real. Vamos adicionar a capacidade de operar com tamanhos de posição variáveis.
Algoritmos de otimização populacional: Resistência a ficar preso em extremos locais (Parte I) Algoritmos de otimização populacional: Resistência a ficar preso em extremos locais (Parte I)
Este artigo apresenta um experimento único que visa examinar o comportamento dos algoritmos de otimização populacional no contexto de sua capacidade de escapar eficientemente de mínimos locais quando a diversidade populacional é baixa e alcançar máximos globais. Trabalhar nessa direção fornecerá uma visão mais aprofundada sobre quais algoritmos específicos podem continuar sua busca com sucesso usando coordenadas definidas pelo usuário como ponto de partida e quais fatores influenciam seu sucesso.