English Русский 中文 Español Deutsch 日本語
preview
Aprendendo MQL5 do iniciante ao profissional (Parte II): Tipos de dados básicos e uso de variáveis

Aprendendo MQL5 do iniciante ao profissional (Parte II): Tipos de dados básicos e uso de variáveis

MetaTrader 5Exemplos | 17 junho 2024, 17:27
349 0
Oleh Fedorov
Oleh Fedorov

Introdução

No meu artigo anterior, vimos os programas principais usados por programadores em MQL5 (e concluímos que, para iniciantes, o IDE MetaEditor é suficiente). Além disso, demos uma olhada rápida no conceito de funções e criamos um script simples que exibe uma mensagem no log do sistema. Esses registros podem ser vistos na aba "Experts" na parte inferior da janela do terminal.

Lembre-se: a função é a descrição de uma ação.

Usamos apenas funções predefinidas: OnStart e Print; a primeira foi "preenchida" por nós, enquanto a segunda, que exibia as informações necessárias, foi usada como pronta, apenas passando seus parâmetros. Em geral, um programador pode criar suas próprias funções para resolver suas tarefas específicas.

Cada função é composta de passos-ações elementares chamados operadores. Essas ações são bastante simples: comparar dois números, repetir um trecho de código várias vezes, colar dois trechos de texto, chamar outra função... e assim por diante. Não são muitas, vou abordar algumas neste artigo.

A sequência de operadores forma algoritmos.

Algoritmo é um conjunto claro e compreensível de instruções para o computador, que executa ações específicas para resolver uma tarefa concreta e mais ampla. Existem muitos algoritmos, pois geralmente uma mesma tarefa pode ser resolvida de várias maneiras diferentes.

Por exemplo, no trading, a entrada e saída de uma operação, a exibição dos logs — tudo pode ser feito de várias formas. É preciso explicar claramente ao computador o que você (ou seu cliente) deseja em um caso específico.

Podemos dizer que algoritmos complexos são compostos de algoritmos simples, e cada algoritmo é implementado por uma função que executa determinadas ações. E essas ações são realizadas sobre dados. Os dados podem ser preços Ask e Bid, volumes de transações, pontos na tela para desenhar linhas, sons para tocar em momentos específicos, textos como listas de cotações para um período, etc... Bem, espero que a ideia esteja clara.

O importante é que esses dados precisam ser armazenados em algum lugar.

Hoje, vamos falar sobre como os dados são armazenados na memória RAM. E eles são armazenados em variáveis ou constantes.

As diferenças são evidentes:

  • as variáveis mudam, podem ser reescritas;
  • as constantes permanecem inalteradas durante a vida do programa, e se o programador tentar reescrevê-las, receberá um erro de compilação.

No resto, elas são semelhantes: são uma área de memória que armazena dados, não instruções do processador. Normalmente, essas áreas de memória recebem nomes significativos para facilitar a compreensão do código.

O compilador posteriormente remove esses nomes, mas, se tivermos acesso ao código-fonte, sempre poderemos entender a finalidade de uma variável. Se, é claro, ela for descrita corretamente.

Em alguns casos, as constantes não têm nomes. O programador apenas escreve o que quer processar (como as strings passadas para a função Print). Essas constantes anônimas são chamadas de literais.

Neste artigo, vamos detalhar os tipos de dados básicos, formas de descrever variáveis e constantes, e os operadores principais que um programador pode usar para criar seus algoritmos. Isso nos permitirá criar programas mais úteis do que apenas "Hello, World".


Código básico para testar todas as expressões do artigo

No artigo anterior, criamos um programa simples: um script que exibe dados na aba "Experts" na parte inferior do terminal. Aqui está:

//+------------------------------------------------------------------+
//|                                                   HelloWorld.mq5 |
//|                                       Oleg Fedorov (aka certain) |
//|                                   mailto:coder.fedorov@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Oleg Fedorov (aka certain)"
#property link      "mailto:coder.fedorov@gmail.com"
#property version   "1.00"
//#property script_show_inputs

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
  Print("Hello, MQL5 world!");
  }

//+------------------------------------------------------------------+

Exemplo 1. Texto completo do script mais simples

Hoje vamos modificar este código, substituindo as linhas dos exemplos dentro das chaves (a menos que seja indicado outro local).


Literais

Vamos entender como podemos exibir dados.

Comecemos com strings.

O literal de string é delimitado por aspas "<">. Nem todos os caracteres podem ser exibidos diretamente, alguns têm propósitos especiais (como as aspas), outros nem são visíveis, como o caractere de nova linha.

Para esses casos, usamos a barra invertida:

Print(
    "Symbol <\"> can't be placed"
    " without (\\).\n  And we can carrying over the string now."
  );

Exemplo 2. Uso de barras invertidas para exibir caracteres especiais

No exemplo 2, as aspas verdes delimitam as strings a serem exibidas, e os caracteres especiais são amarelos. Por exemplo, o caractere "\n" representa uma nova linha.

Exemplo de exibição de literal de string

Figura 1. Exemplo de exibição de literal de string

Um detalhe importante: em MQL5, strings longas podem ser divididas em partes menores (colocando cada parte entre aspas). Não é necessário inserir ações adicionais para concatenar essas strings. Se o compilador encontrar dois literais de string consecutivos, ele os concatenará automaticamente em uma única string, e depois procurará os caracteres especiais nela.

A tabela completa de caracteres especiais e uma descrição mais detalhada das constantes de caractere podem ser encontradas na documentação oficial.

Números são os segundos mais usados.

Os números inteiros são exibidos normalmente:

Print(5);

Exemplo 3. Exibição de um número inteiro

Os números decimais também são fáceis de exibir. Quem já usou calculadora sabe que usamos ponto como separador decimal:

Print(5.5);

Exemplo 4. Exibição de número decimal

Para números muito grandes ou muito pequenos, podemos usar a notação científica (ou "forma exponencial"):

Print(5.5e3);
Print(5.5e-3);

Exemplo 5. Uso de literais em notação científica

O resultado do script com todas essas formas de números é mostrado na figura 2.

Exibição de números com a função Print

Figura 2. Resultado da exibição de números com a função Print

Note como a função converteu os dados nas duas últimas linhas. Isso mostra que os dados foram reconhecidos como números e processados corretamente.

Às vezes, os programadores trabalham com números hexadecimais. Os iniciantes raramente precisam disso, mas pode ser útil, por exemplo, para descrever cores. Os números hexadecimais são compostos por dígitos (0..9) e/ou letras (a..f).

Para garantir que o programa reconheça um número como hexadecimal, colocamos "0x" no início (0 e x).

As letras maiúsculas e minúsculas não importam.

Print(0xAF35);

Exemplo 6. Uso de número hexadecimal

Exibição de número hexadecimal

Figura 3. Resultado da exibição de número hexadecimal

O resultado do script é mostrado na Figura 3. O script converteu o número (em um inteiro comum), mostrando que o computador nos entendeu corretamente.

Em MQL5, datas são frequentemente usadas.

Para registrar data e hora, usamos a letra maiúscula "D", seguida de apóstrofo <'>, a data desejada com pontos ou barras, espaço para a hora, separando minutos e segundos com dois pontos, e outro apóstrofo:

  Print(D'24/12/23');
  Print(D'24.12');
  Print(D'24.12.2023 7:55:34');

Exemplo 7. Uso de data e hora

A segunda linha gerará um aviso de compilação indicando que a data está incompleta... Mas o arquivo será compilado, e todas as três linhas funcionarão corretamente:

Aviso de literal incompleto

Figura 4. Aviso (MetaEditor) de literal de data incompleto

Resultados do script (exibição de datas)

Figura 5. Resultados do script de exibição de datas (terminal)

Note que na compilação da primeira linha, o horário foi definido como o início do dia, e na segunda linha, como o horário da compilação. E a conversão do formato mostra que o programa nos entendeu corretamente...

E você pode executar qualquer ação com qualquer literal que seja permitido para esse tipo de dados.

Podemos realizar qualquer ação permitida sobre literais, como comparações, operações aritméticas, e passá-los como parâmetros para funções.

As strings podem ser concatenadas, mas não subtraídas.

Vejamos o exemplo a seguir:

Print( "This will be calculated: "+4+9 );
Print( "This will be calculated: "+(4+9) );

Exemplo 8. Uso de parênteses em expressões.

Aviso do compilador sobre uso de números em string

Figura 6. Aviso do compilador sobre uso de números em expressões de string

Resultados das operações

Figura 7. Função exibiu o resultado das operações

Note que, onde não havia parênteses, os números foram apenas "anexados" ao texto; onde havia, tudo foi calculado corretamente. Esse é um erro sutil, por isso o compilador nos avisa. Existem funções especiais para converter números em strings explicitamente. Por enquanto, lembre-se: parênteses são importantes.


Descrição de constantes com a diretiva de pré-processador #define

Se você não quiser se perder no próprio código, e quer entender "para que serve esse 5" ou "o que significa esses 72", é melhor dar nomes significativos às suas constantes. Para isso, usamos a diretiva de pré-processador #define:
#define название значение

Exemplo 9. Diretiva #define

Lembrando, o pré-processador é como um "idioma dentro do idioma", e ele descreve ações antes da compilação.

Geralmente, a tarefa do pré-processador é substituir partes do código por outras. Então, a diretiva #define indica ao compilador para substituir "nome" por "valor" em todo o código, antes de qualquer verificação sintática.

Por exemplo:

  #define MY_SUPER_CONSTANT 354
  Print(MY_SUPER_CONSTANT);

Exemplo 10. Diretiva #define

Programa exibe o valor, não o nome

Figura 8. Programa exibe o valor da constante, não o nome

O programa exibirá o número 354, não seu nome.

Note que após o literal do número não há ponto e vírgula.

Ao descrever constantes com a diretiva de pré-processador, o ponto e vírgula não é necessário.

Se o tivéssemos colocado, o pré-processador incluiria esse sinal dentro dos parênteses do Print, e obteríamos um erro de compilação.

Então, lembre-se: nomeie cada constante, e use o nome nas expressões, não o valor.

Os nomes ajudam muito se uma mesma constante for usada várias vezes ou se várias constantes tiverem o mesmo valor. Se o valor de uma constante mudar, é mais fácil alterá-lo em um só lugar, geralmente no início do documento ou em um arquivo separado, do que procurar em todos os outros lugares.


Descrição de variáveis

Lembre-se: se os dados na memória precisam mudar durante a execução, usamos variáveis.

Descrever variáveis é fácil. Apenas registramos o que queremos armazenar:

тип имя_переменной;

Exemplo 11. Modelo de descrição de variável

Isso significa que o compilador deve alocar uma quantidade específica de memória para nossos dados. Mais detalhes sobre tipos e tamanhos serão abordados abaixo.

Agora podemos acessar esses dados pelo nome (nome_variável).


Convenções sobre identificadores

O nome (ou "identificador") de uma variável — ou qualquer outro elemento — deve

  • ser informativo para nós (melhor "chartNumber" do que "sss");
  • ser composto por letras do alfabeto latino, números e sublinhado (_), 

O nome NÃO deve:

As maiúsculas e minúsculas importam. Assim, myVariable e MyVariable são nomes diferentes. (Usar ambos os nomes no mesmo arquivo não é recomendado).

Se confundir maiúsculas e minúsculas, o compilador dará um erro: "Variável não descrita", facilitando a correção. Mas se descrevermos ambas corretamente, porém com diferenças apenas no uso de uma letra maiúscula ou minúscula, será muito fácil nos confundirmos.

Fora isso, não há restrições. Você pode até nomear sua variável com o nome de uma função interna (espero que não).


Operação de atribuição

Para armazenar dados em uma variável, usamos a operação de atribuição. Às vezes, isso é feito na descrição, e é chamado de inicialização:

// Инициализация (при создании)
int counter = 0;
// Обычное присваивание
counter = 10;

Exemplo 12. Atribuição simples

A palavra int indica que a variável pode conter apenas dados inteiros.

O sinal "=" indica operação de atribuição. Aqui, um número inteiro é armazenado na variável counter.

Todos os dados anteriores são perdidos.

Podemos usar essa variável em qualquer parte do programa, pelo nome, por exemplo, passando-a como parâmetro ou em uma expressão (exemplos mais adiante).


Operação de atribuição — detalhes

A atribuição pode ser simples, como no exemplo anterior. Mas se usar essa operação em expressões, estas dicas podem ajudar a usá-la de forma mais eficiente.

  • A operação de atribuição tem a menor prioridade, portanto é executada da direita para a esquerda. Primeiro, o lado direito é calculado, e o resultado é atribuído à variável à esquerda:
a = b + c;

Exemplo 13. Atribuição tem a menor prioridade.

Neste exemplo, primeiro somamos b e c, e depois o resultado é armazenado em a.

  • Como consequência, podemos usar o valor da variável na expressão, e depois armazenar o resultado na mesma variável:
a = a — c;

    Exemplo 14. Podemos usar o valor anterior da variável na expressão

    • No MQL5, expressões onde a mesma variável aparece uma vez à direita e à esquerda (como no exemplo acima), podem ser abreviadas, movendo o operador para a esquerda da atribuição:
    a -= c;

    Exemplo 15. Uso abreviado da atribuição

    Essa abreviação é permitida para quaisquer operadores binários (como soma ou multiplicação): multiplicação, divisão, deslocamento... Desde que a variável possa ser facilmente destacada.

    Para a expressão a = a*(1+1/a), essa técnica não funciona, a menos que os parênteses sejam removidos, mas para a = a*(b+c), funciona: a *= b+c.

    • Para aumentar ou diminuir um inteiro em 1, podemos usar operações de incremento e decremento:
    a++; // Инкремент. Увеличит а на 1
    b--; // Декремент. Уменьшит b на 1

    Exemplo 16. Incremento e decremento

    Essas operações são unárias, ou seja, requerem apenas uma variável. Elas têm duas formas: prefixa e pós-fixa.

    Na forma prefixa, a ação é executada primeiro, depois o resultado é usado na expressão.

    Na forma pós-fixa, o valor antigo é usado na expressão, e depois a variável é alterada:

    int a = 1;
    Print (++a); // 2, и a == 2
    Print (a++); // 2, но a == 3

      Exemplo 17. Forma prefixa e pós-fixa do incremento (decremento é similar)

      • Podemos usar vários operadores de atribuição em sequência, "em cascata". A sequência de ações "da direita para a esquerda" é mantida.
      int a=1, c=3;
      a = c = a+c; // сначала a+c (4), потом c = 4, потом a = c (то есть a = 4)

      Exemplo 18. Atribuição em cascata


      Tipos de dados básicos

      Há relativamente muitos tipos de dados.

      Existem "simples" (ou "básicos") tipos de dados — como strings, números, datas, cores, etc. — e "complexos", que o programador em MQL5 desenvolve. Geralmente, os "complexos" combinam tipos simples para maior conveniência em um bloco.

      Neste artigo, abordaremos apenas os tipos básicos. Os complexos serão tratados na próxima parte.

      Tipos inteiros

      Primeiro, entenda que inteiros são a principal forma de "pensar" do computador.

      As operações com inteiros são simples e rápidas. Mas, se o resultado ultrapassar um certo intervalo, pode haver perda de dados.

      Segundo: inteiros podem ser "com sinal" e "sem sinal".

      Se forem "sem sinal", usamos de 0 ao máximo. Os números que ocupam 1 byte podem ir de 0 a 28-1 = 255 — totalizando 256 valores.

      Se tentar armazenar 256 ou -1, ocorre "overflow", mantendo-se nos limites [0..255] e perdendo o resto. Às vezes útil, mas geralmente, outros métodos são melhores para essas conversões. Por exemplo, usar a operação de módulo (mais adiante). Melhor usar variáveis de tipos que garantam todos os seus dados sem perdas.

      Antes dos nomes de tipos "sem sinal", usamos "u" (de unsigned).

      Números "com sinal" usam o mesmo intervalo, dividido ao meio. A primeira metade para números negativos, a segunda para positivos. Números de 1 byte vão de [-128..127].

      Tabela 1. Tipos de dados inteiros.

      Nome
      Tamanho (bytes)
       Valor mínimo
      Valor máximo
      char
      1 (8 bits)
      -128
      127
      uchar
      1 (8 bits)
      0
      255
      short
      2 (16 bits)
      -32 768
      32 767
      ushort
      2 (16 bits)
      0
      65 535
      int
      4 (32 bits)
      -2 147 483 648
      2 147 483 647
      uint
      4 (32 bits)
      0
      4 294 967 295
      long
      8 (64 bits)
      -9 223 372 036 854 775 808
      9 223 372 036 854 775 807
      ulong
      8 (64 bits)
       0  18 446 744 073 709 551 615

      Na prática, os tipos int (porque é rápido de escrever e grande o suficiente) e long (suficiente para a maioria das tarefas, com otimização de bytecode) são os mais usados.

      Outros tipos inteiros também são úteis.

      Tipo booleano (lógico)

      Chaveado como bool, ocupa 1 byte e pode ter dois valores: true ou false ("verdadeiro" ou "falso").

      Se necessário, qualquer número pode ser usado como lógico. Se igual a 0, é "falso"; diferente de 0, é "verdadeiro". Mas use isso com cuidado...

      Números reais (também chamados de números "com ponto flutuante")

      Tabela 2. Tipos de dados reais

      Nome
       Tamanho (bytes) Valor mínimo positivo  Valor máximo  
      float
      4 (32 bits)
      1.175494351e-38
      3.402823466e+38
      double
      8 (64 bits)
      2.2250738585072014e-308
      1.7976931348623158e+308

      Na prática, usamos mais o tipo double. Não vejo float em códigos há tempos, talvez para compatibilidade com versões antigas. Em grandes volumes de dados, pode ser útil para economizar memória.

      Números reais representam bem preços, quantidades de moeda, etc.

      Cobrem uma faixa maior de valores que os inteiros.

      Mas o computador não lida "confortavelmente" com eles. Operações com reais são um pouco mais lentas e quase sempre com erros nos últimos dígitos. Em vez de 1.0, podemos obter 1.00000001 ou 0.99999999.

      Então, comparamos reais usando a diferença com um valor pequeno, maior que o erro. É mais seguro.

      Data e hora

      Chaveado como datetime, ocupa 8 bytes.

      Cada variável deste tipo contém segundos desde 1º de janeiro de 1970 até a data desejada, ou seja, um número inteiro.

      Última data possível é 31 de dezembro de 3000. Isso deve ser suficiente por um bom tempo...

      Existem constantes predefinidas:

      • __DATE__ — data de compilação;
      • __DATETIME__ — data e hora de compilação;
      • __DATETIME__ — __DATE__ — hora de compilação, sem a data.

      Um literal pode ser registrado como D'' (D e dois apóstrofos), equivalente a __DATETIME__. Mas a legibilidade do código diminui.

      Cores

      Cores em MQL5 são um tipo específico, chamado color. Para descrever uma cor, usamos um literal:

        color myColor1=C'100,200,30';
        color myColor2=C'0xFF,0x00,0x5A';

      Exemplo 19. Descrição de cor com números decimais ou hexadecimais

      Podemos usar constantes de cores web predefinidas. Os nomes das constantes começam com clr (por exemplo, clrBlue — azul). O MetaEditor fornece uma lista completa ao digitar clr, ou consulte a documentação oficial.

      No exemplo 12, cada descrição de cor tem três componentes. Cada componente descreve a intensidade de vermelho, verde ou azul (RGB). Combinados, formam todas as cores. Vermelho e verde dão tons amarelo-alaranjados. Vermelho e azul formam tons violetas. Verde e azul produzem turquesa, azul-claro etc.

      Igual intensidade dos três dá tons de cinza: do preto (intensidade 0) ao branco (intensidade máxima 255 ou 0xFF). Se as intensidades diferem, obtemos todas as outras cores na tela. Geralmente, verde ilumina a cor geral, azul escurece, mas quanto mais brilhante a componente, mais clara a cor geral.

      Essas regras são ilustradas na tabela 3, com células coloridas.

      Na prática, não é preciso saber os valores numéricos, basta escolher da paleta ou usar uma constante predefinida. Mas entender como funciona é útil.

      Dados de cor ocupam 4 bytes, embora usem apenas 3. Isso é um padrão histórico, comum para programas que usam essa descrição de cor.

      Tabela 3. Exemplos de uso de cores

      0, 0, 0 156, 15, 15 106, 0, 86 0, 49, 110 0, 110, 41 56, 37, 9 56, 37, 9
      51, 51, 51 191, 3, 3 133, 2, 108 0, 67, 138 0, 137, 44 243, 195, 0 87, 64, 30
      102, 102, 102 226, 8, 0 160, 39, 134 0, 87, 174 55, 164, 44 255, 221, 0 117, 81, 26
      153, 153, 153 232, 87, 82 177, 79, 154 44, 114, 199 119, 183, 83 255, 235, 85 143, 107, 50
      204, 204, 204 240, 134, 130 193, 115, 176 97, 147, 207 177, 210, 143 255, 242, 153 179, 146, 93
      255, 255, 255 249, 204, 202 232, 183, 215 164, 192, 228 216, 232, 194 255, 246, 200 222, 188, 133

      As cores podem ser manipuladas como números inteiros.

      Por exemplo:

        color a = C'255,0,0';
        color b = C'0,255,0';
        color d = a+b;
        Print(a," ",b," ",d);

      Exemplo 20. Uso de cores em expressões aritméticas

      Resultado:

      Resultado do uso de cores em expressões aritméticas

      Figura 9. Resultado do uso de cores em expressões aritméticas

      Enumerações

      Último tipo básico — enumerações.

      Às vezes, uma variável deve ter valores específicos. Por exemplo, tendências podem ser descendente, ascendente ou lateral (lateral). Ordens de compra: comprar a mercado, pendente para certo preço (Buy Stop) ou recuo (Buy Limit). Dias da semana. Entendeu o princípio.

      Para isso, usamos enumerações (do inglês enumeration).

      Enumerações têm três etapas.

      1. Primeiro, criamos a lista e nomeamos. Esse nome é o nome do tipo para variáveis ou funções. A única diferença é que o nome foi inventado por nós.
      2. Segundo, criamos a variável desse tipo.
      3. Terceiro, usamos a variável.
      O exemplo 15 mostra a enumeração de direção (DIRECTION), com três valores: "Subida", "Descida", "Lateral".

      //--- Первый этап: создание нового списка (нового типа данных)
        enum ENUM_DIRECTION
         {
          Upward,
          Downward,
          Aside
         };
      
      //--- Второй этап: описание (и, при необходимости, инициализация) переменной этого типа
        ENUM_DIRECTION next=Upward;
      
      //--- Третий этап: использование переменной
        Print(next);

      Exemplo 21. Exemplo de descrição e uso de enumeração

      A lista de enumeração geralmente é no início do arquivo, após as diretivas do pré-processador. Então, fica acessível a todas as funções do aplicativo, globalmente.

      Embora possa ser descrita localmente, dentro de uma função, então será invisível para outras funções. Geralmente, não há grande sentido nisso, mas depende das suas tarefas...

      Nomes dos elementos são entre chaves, separados por vírgula.

      Após a chave fechada de qualquer tipo (inclusive enumeração) precisa de ponto e vírgula. Para outros blocos, isso pode não ser necessário.

      Enumerações internas têm nomes em maiúsculas, começando com ENUM_. Você pode nomear suas enumerações como quiser, mas é bom seguir esses padrões.

      Internamente, enumerações são números inteiros com sinal, ocupando 4 bytes.

      Ao executar o código do exemplo 21, vemos o número 0. Quando deixamos MQL5 atribuir números, ele começa do zero.

      Mas podemos definir outros números explicitamente:

      //--- Первый этап: создание нового списка (нового типа данных)
        enum DIRECTION
         {
          Upward = 1,
          Downward = -1,
          Aside = 0
         };

      Exemplo 22. Atribuindo valores explicitamente

      Não precisamos definir todos os valores.

      Ao definir alguns, MQL5 atribui os demais, baseando-se na ordem e no último valor. No exemplo 15, se definir Upward = 1 e remover o resto, Downward será 2, Aside 3. Recomendo testar isso.


      Expressões e operadores simples

      Ao trabalhar com dados, é importante compará-los, realizar operações matemáticas, etc. Para diferentes tipos de dados, temos diferentes expressões.

      Operadores de comparação

      Esses operadores fazem sentido para todos os tipos de dados.

      O resultado será lógico.

      Existem os seguintes operadores:

      • maior (>), 
      • menor (<), 
      • maior ou igual (>=), 
      • menor ou igual (<=), 
      • igual (==), 
      • diferente (!=)

      Todos têm a mesma prioridade.

      Ao comparar strings, o computador segue a ordem dos caracteres na codificação. Por exemplo, "A" maiúsculo vem antes de "a" minúsculo, então é menor, e

      "Assol" < "a salt?" //true

      Exemplo 23. Comparação de strings. Maiúsculas menores que minúsculas

      Se vários caracteres são iguais, o primeiro diferente é comparado.

      "Assol" > "A salt?" //true

      Exemplo 24. Primeiros caracteres iguais

      O exemplo 24 é verdadeiro porque o espaço vem antes dos caracteres alfabéticos, e os primeiros caracteres são iguais.

      Se uma string terminar, mas a outra continuar, e os caracteres até então eram iguais, a menor é a que terminou. Por exemplo:

      "Canção" < "Canção sobre coelhos" //true

      Exemplo 25. Strings de comprimentos diferentes

      Operações aritméticas

      O resultado depende do tipo de dados na expressão.

      Podemos realizar operações aritméticas com números:

      • sinal de número (-3) (às vezes "unário" negativo);
      • multiplicação (*), divisão (/) (em inteiros, arredonda para baixo), resto (%) (somente inteiros, 5%2 == 1);
      • soma (+), subtração (-);
      • incremento (++), decremento (--)

      A lista está em ordem de prioridade.

      Mas incremento e decremento em expressões comuns com outros operadores podem ter resultados indefinidos.

      Para strings, a operação + significa concatenação (transformar duas strings curtas em uma longa).

      Operações bit a bit

      O resultado é um inteiro.

      Para inteiros, temos operações bit a bit:

      • negação (~);
      • deslocamento à direita (>>);
      • deslocamento à esquerda (<<);
      • e (&);
      • ou (|);
      • ou exclusivo (^).

      Se precisar delas, você já não é iniciante e pode consultar a documentação.

      A lista está em ordem de prioridade.

      Operadores lógicos

      O resultado é lógico.

      • negação lógica (!);
      • multiplicação lógica (e lógico) (&&);
      • soma lógica (ou lógico) (||).

      A lista está em ordem de prioridade.

      Existem outras operações, abordadas em outros artigos. Também em outros artigos, veremos exemplos mais detalhados de uso de todos esses operadores. Use o que entende ou consulte a documentação. Não deve haver grandes dificuldades...


      Conversão de tipos

      Às vezes, expressões aritméticas envolvem dados de vários tipos. Por exemplo, na função Print, misturamos strings e números, até cores.

      Qual será o tipo do resultado? Temos duas opções: determinar o tipo nós mesmos ou deixar para o compilador.

      O compilador é esperto, mas não sempre.

      Então, vejamos o que o compilador faz e o que podemos fazer manualmente, sem perder dados importantes.

      Antes de tudo, o que o compilador faz?

      Primeiro, se uma expressão usa dados de um tipo, o resultado será do mesmo tipo. Isso é fácil.

      Se usar tipos diferentes, o compilador tenta expandir o resultado para o mais preciso. Por exemplo, somando um inteiro de 4 bytes (int) com uma data (datetime), obtemos uma data (porque seu intervalo é maior).

      Um literal inteiro é do tipo int, um literal de ponto flutuante geralmente é do tipo double, a menos que termine com "f":

      5 + 3.4f + 4.25 // Результат — double, так как сначала 5 преобразуется к типу float, а потом 4.25 задаёт двойную точность.

      Exemplo 26. Conversão de tipos ao usar literais

      A documentação tem um diagrama de prioridade de conversões:

      Prioridades de conversão de dados

      Figura 10. Prioridades de conversão de dados

      Lembre-se que conversões entre tipos com e sem sinal podem levar à perda de dados, e conversões para float podem levar à perda de precisão.

      Então, se não tiver certeza sobre a conversão automática, pense em especificá-la manualmente.

      Para converter um resultado (ou valor específico) para um tipo determinado:

      • Apenas armazene o resultado em uma variável desse tipo. Este método é uma forma de conversão automática, então use-o com cuidado;
      • Use funções de conversão de dados;
      • Use a forma abreviada de conversão de tipos.
      (int)a+b // преобразует а к целому. b остаётся неизменным
      double (c+d) // запись абсолютно аналогична предыдущей. В данном случае преобразуется результат суммирования
      
      // и т.д. — можно использовать любой подходящий тип
      

      Exemplo 27. Forma abreviada de conversão de tipos

      Lembre-se que parênteses alteram a ordem das operações, pois têm a maior prioridade. Não está seguro? Use parênteses para garantir.


      Considerações finais

      Cobrimos uma grande parte da teoria sobre tipos de dados básicos, variáveis e expressões. Se entender o material desta e da próxima matéria, você deixará de ser um iniciante e avançará um nível :-) Compreender variáveis (nesta matéria) e funções (na próxima) torna qualquer OOP fácil de aprender...

      OOP — programação orientada a objetos, é considerada complexa. Mas na verdade, se entender a base, as dificuldades são mais ideológicas do que técnicas.

      Se tiver dúvidas, releia o artigo (ou várias vezes), devagar, conceito por conceito, testando tudo no código.

      Se entendeu e não quer esperar, sugiro escrever um script que exiba informações úteis sobre seus instrumentos e saldo. Grande parte dessa informação pode ser obtida com as funções AccountInfo... e SymbolInfo...

      Tente encontrar os nomes completos de cada função com o MetaEditor, depois veja na documentação. E com o que você já sabe... Talvez criar esse script não seja tão difícil.

      P.S. Um exemplo de script está na biblioteca padrão. Se não quiser escrever o seu, tente entender o pronto. Aos que criarem algo, comparem...

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

      Algoritmos de otimização populacional: sistema imune micro-artificial (Micro Artificial Immune System, Micro-AIS) Algoritmos de otimização populacional: sistema imune micro-artificial (Micro Artificial Immune System, Micro-AIS)
      Este artigo fala sobre um método de otimização baseado nos princípios de funcionamento do sistema imunológico do organismo — Micro Artificial Immune System (Micro-AIS) — uma modificação do AIS. O Micro-AIS utiliza um modelo mais simples do sistema imunológico e operações mais simples de processamento de informações imunológicas. O artigo também aborda as vantagens e desvantagens do Micro-AIS em comparação com o AIS tradicional.
      Criando um algoritmo de market making no MQL5 Criando um algoritmo de market making no MQL5
      Como funcionam os market makers no mercado? Vamos explorar isso e criar um algoritmo simples de market making.
      Como ganhar dinheiro realizando pedidos de traders no serviço "Freelance" Como ganhar dinheiro realizando pedidos de traders no serviço "Freelance"
      MQL5 Freelance é um serviço online onde desenvolvedores criam aplicativos de negociação para traders em troca de remuneração. O serviço funciona com sucesso desde 2010: até o momento, mais de 100.000 trabalhos foram realizados, totalizando $7 milhões. Como podemos ver, há bastante dinheiro em circulação aqui.
      Desenvolvendo um sistema de Replay (Parte 53): Complicando as coisas (V) Desenvolvendo um sistema de Replay (Parte 53): Complicando as coisas (V)
      Neste artigo irei introduzir um tema muito importante, porém que poucos de fato compreender. Eventos Customizados. Perigos. Vantagens e falhas causados por tais coisas. Este assunto é muito importante para quem deseja se tornar um programador profissional em MQL5, ou em qualquer outro tipo de linguagem. Mas aqui iremos focar no MQL5 e no MetaTrader 5.