Tudo o que você precisa saber sobre a estrutura de um programa MQL5
Introdução
Todo programa em qualquer linguagem de programação possui uma estrutura. Ao entender essa estrutura, podemos criar e melhorar nossos próprios programas com facilidade. Os programas no MQL5 também têm sua própria estrutura, e os desenvolvedores devem compreendê-la para garantir o alcance sem percalços e eficaz dos objetivos de seus projetos. Vamos explorar a estrutura de um programa desenvolvido no MQL5, abordando os seguintes tópicos:
- Pré-processador
- Substituição de macro (#define)
- Propriedades do programa (#property):
- Inclusão de arquivos (#include):
- Importação de funções (#import):
- Compilação condicional (#ifdef, #ifndef, #else, #endif)
- Variáveis de entrada e globais
- Funções, classes
- Manipuladores de eventos
- Exemplos de programas MQL5
- Considerações finais
Após a leitura deste artigo, você terá um profundo entendimento da estrutura de qualquer programa MQL5 e será capaz de criar ou desenvolver qualquer software com base nessa estrutura de forma fluida e eficiente.
Pré-processador
Nesta seção, examinaremos detalhadamente o pré-processador como um conceito de programação. O pré-processador (preparação prévia) é uma etapa importante no processo de compilação. Ele entra em ação antes da compilação real do programa. Durante a pré-processamento, várias ações são executadas, como inclusão de arquivos, definição de propriedades de software, definição de constantes e importação de funções.
Todas as diretivas do pré-processador começam com (#). Essas diretivas não são consideradas declarações de linguagem, ou seja, não devem terminar com ponto e vírgula (;). Incluir um ponto e vírgula no final de uma diretiva do pré-processador pode levar a erros, dependendo do tipo de diretiva.
Em outras palavras, podemos dizer que o pré-processador é destinado a preparar o código-fonte do programa antes do processo de compilação. Existem vários tipos de diretivas do pré-processador com base nos parâmetros que precisamos definir em um programa MQL5, como:
- Macro substituição (#define)
- Propriedades do programa (#property)
- Inclusão de arquivos (#include)
- Importação de funções (#import)
- Compilação condicional (#ifdef, #ifndef, #else, #endif)
Macro substituição (#define):
A diretiva do pré-processador #define pode ser usada para criar constantes simbólicas ou para definir constantes que serão usadas no programa. Uma constante é um identificador cujo valor não muda. A diretiva #define pode ser usada para atribuir nomes mnemônicos a constantes, já que usaremos um valor substituto para um identificador específico. O primeiro formato dessa diretiva do pré-processador é o seguinte:
#define identifier replacement-value
Assim, em nosso programa, essa linha de código significa que, antes da compilação, o identificador será substituído pelo valor substituto. Este formato representa a diretiva #define sem parâmetros, ou formato sem parâmetros. No MQL5, há outro formato, que é o formato paramétrico com um máximo de oito parâmetros que podem ser usados com a diretiva #define, como mostrado abaixo:
#define identifier (param1, param2,... param5)
As mesmas regras das variáveis se aplicam aos identificadores de constantes:
- O valor pode ser de qualquer tipo, como inteiro, duplo ou string.
- A expressão pode consistir em vários tokens. Ele termina quando a linha termina e não pode ser transferido para a próxima linha de código.
Aqui está um exemplo:
//Parameter-free format #define INTEGER 10 //int #define DOUBLE 10.50 //double #define STRING_VALUE "MetaQuotes Software Corp." //str #define INCOMPLETE_VALUE INTEGER+DOUBLE //Incomlete #define COMPLETE_VALUE (INTEGER+DOUBLE) //complete //Parametic format #define A 2+3 #define B 5-1 #define MUL(a, b) ((a)*(b)) double c=MUL(A,B); //function to print values void defValues() { Print("INTEGER Value, ",INTEGER); //result: INTEGER Value, 10 Print("DOUBLE Value, ",DOUBLE); //result: DOUBLE Value, 10.50 Print("STRING Value, ",STRING_VALUE); //result: STRING Value, MetaQuotes Software Corp. Print("INCOMPLETE Value, ",INCOMPLETE_VALUE*2); //result: INCOMPLETE Value, 31 Print("COMPLETE Value, ",COMPLETE_VALUE*2); //result: STRING Value, 41 Print("c= ",c); //result: c= 41 }
Também existe a diretiva do pré-processador (#undef), que anula o que foi declarado ou definido anteriormente.
Propriedades do programa (#property):
Ao criar um programa, podemos precisar especificar parâmetros adicionais. Podemos fazer isso usando #property. Essas propriedades devem ser especificadas no arquivo principal MQL5 e não no arquivo incluído, e as que forem especificadas nos arquivos incluídos serão ignoradas. Desse modo, a diretiva #property define propriedades adicionais para o programa. Se você perguntar o que precisamos especificar nesse contexto, direi que temos muitas coisas, como indicadores, scripts, informações descritivas e propriedades de bibliotecas. Como outras diretivas do pré-processador, #property será declarado na parte superior do código-fonte e será exibido na guia geral na janela do programa durante a execução.
Aqui está um exemplo da diretiva do pré-processador deste tipo:
#property copyright "Copyright 2023, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property description "Property preprocessor"
Esses valores podem ser vistos na janela do programa:
Como podemos ver na imagem anterior, temos certas propriedades que precisamos na guia geral ao iniciar o Expert Advisor (EA). O texto 'Copyright 2023, MetaQuotes Ltd.' é um hiperlink. Ao passar o mouse sobre ele, vemos para onde ele leva (propriedade link).
Inclusão de arquivos (#include):
Como de costume, todas as diretivas #include são colocadas no início do programa. Elas apontam para o arquivo que deve ser incluído no programa para utilizar seu conteúdo, como variáveis, funções e classes.
Existem dois formatos para inclusão de arquivos com a diretiva #include:
#include <File_Name.mqh> #include "File_Name.mqh"
A diferença entre esses dois formatos está em onde o compilador deve procurar o arquivo incluído: o primeiro permite que o compilador procure o arquivo na pasta "Include" da instalação do MetaTrader 5 ou no arquivo de cabeçalho da biblioteca padrão, enquanto o segundo permite que o compilador procure o arquivo no mesmo diretório que o arquivo do programa.
Importação de funções (#import):
A diretiva #import é usada para importar funções para o programa a partir de módulos MQL5 compilados (arquivos *.ex5) e módulos do sistema operacional (arquivos *.dll). A função deve ser completamente descrita, e seu formato deve ser o mesmo que o seguinte:
#import "File_Name" func1 define; func2 define; ... funcN define; #import
Compilação condicional (#ifdef, #ifndef, #else, #endif):
A compilação condicional nos permite controlar a execução das diretivas de pré-processamento, além da compilação do programa. Isso nos permite controlar a compilação ou pular partes do código do programa com base em uma condição específica, que pode estar em um dos seguintes formatos:
#ifdef identifier //If the identifier has been defined, the code here will be compiled. #endif
#ifndef identifier // If the identifier is not defined, the code here will be compiled. #endif
Como mencionei antes, se pulamos para uma nova linha, as diretivas do pré-processador não serão continuadas. No entanto, neste caso, qualquer quantidade de linhas pode seguir uma diretiva desse tipo quando usamos #else e #endif. Quando a condição é verdadeira, as linhas entre #else e #endif serão ignoradas, mas se a condição não for atendida, as linhas entre o #ifdef (ou #ifndef) e o #else (ou #endif, se o primeiro estiver ausente) serão ignoradas.
Você pode aprender mais sobre o pré-processador MQL5 na documentação.
Variáveis de entrada e globais
Nesta seção, vamos abordar outros componentes da estrutura de um programa MQL5 após as diretivas do pré-processador, que são as variáveis de entrada e globais. Começaremos com as variáveis de entrada (input), que definem uma variável externa. Após a escrita do modificador de entrada, especificamos o tipo de dados. Desse modo, temos o modificador de entrada e os valores da variável de entrada. O modificador de entrada não pode ser alterado dentro do programa MQL5, apenas os valores podem ser alterados pelo usuário do programa na janela "Parâmetros de entrada" ou na guia de propriedades do programa. Quando definimos essas variáveis externas com o modificador de entrada, elas sempre são reinicializadas antes da chamada OnInIt().
Aqui está o formato das variáveis de entrada:
input int MA_Period=20; input int MA_Shift=0; input ENUM_MA_METHOD MA_Method=MODE_SMA;
Após isso, podemos encontrar a janela de entrada definida pelo usuário:
Como podemos ver, podemos configurar o período, o deslocamento e o tipo da média móvel. Também podemos definir como os parâmetros de entrada aparecem na guia "Parâmetros de entrada", adicionando um comentário sobre o que queremos ver na janela, como mostrado abaixo no mesmo exemplo anterior:
input int MA_Period=20; //Moving Average Period input int MA_Shift=0; //Moving Average Shift input ENUM_MA_METHOD MA_Method=MODE_SMA; //Moving Average Type
Na guia "Parâmetros de entrada", podemos encontrar os seguintes parâmetros:
Como podemos observar, os parâmetros têm uma aparência diferente em comparação com a imagem anterior. Você pode aprender mais sobre as variáveis de entrada (input) no MQL5 na documentação.
As variáveis globais devem ser criadas fora dos manipuladores de eventos ou dentro de funções no mesmo nível das funções:
int Globalvar; // Global variable before or outside the event handler and functions int OnInit() { ... }
Por esse motivo, podemos dizer que as variáveis globais têm escopo em todo o programa e são acessíveis a partir de todas as funções no programa. Elas são inicializadas uma vez durante o carregamento do programa e antes do tratamento do evento OnInit ou do tratamento do evento OnStart(). Falaremos sobre manipuladores de eventos mais tarde. Aqui, apenas são mencionados para apresentar a posição das variáveis globais na estrutura do programa MQL5.
Você pode aprender mais sobre as variáveis globais do MQL5 na documentação.
Funções, classes
Nesta seção, abordaremos outros componentes da estrutura de programas MQL5, nomeadamente funções e classes. As funções são detalhadamente descritas em um dos artigos anteriores, "Funções em Aplicativos MQL5". Também recomendo ler o artigo sobre classes no contexto da programação orientada a objetos (POO) no MQL5, "Programação Orientada a Objetos (POO) no MQL5". Espero que eles sejam úteis para você.
Aqui, mencionaremos a posição deste importante componente em qualquer programa, pois podemos defini-lo em qualquer lugar do programa, incluindo arquivos incluídos que podem ser incluídos com a diretiva #include. Eles podem ser colocados antes ou depois dos manipuladores de eventos, bem como após variáveis de entrada e globais.
O formato das funções é o seguinte:
returnedDataType functionName(param1, param2) { bodyOfFunction }
O formato das classes é o seguinte:
class Cobject { int var1; // variable1 double var2; // variable1 void method1(); // Method or function1 };
Você pode aprender mais sobre funções e classes no MQL5 na documentação.
Manipuladores de eventos
Nesta seção, abordaremos os manipuladores de eventos, que são componentes muito importantes dos programas MQL5. Um manipulador de eventos é uma função executável. Quando ocorre um evento específico, como um novo preço, que representa um novo evento de tick, o manipulador de eventos OnTick() se torna executável, pois ele contém o trecho de código que pode ser executado quando um novo preço ou tick é recebido.
Dependendo do tipo de programa, existem diferentes manipuladores de eventos:
Manipulador de eventos | Descrição | Formato |
---|---|---|
OnStart | Pode ser usado em programas como scripts para chamar uma função quando ocorre um evento de acionamento. |
int OnStart(void);
void OnStart(void); |
OnInit | Ele pode ser usado em programas de Expert Advisor e indicadores para chamar a função na inicialização do programa. |
int OnInit(void);
void OnInit(void); |
OnDeinit | Pode ser usado em programas de Expert Advisors e indicadores para chamar a função quando o programa for desinicializado | void OnDeinit( const int reason // deinitialization reason code ); |
OnTick | Pode ser usado em Expert Advisors e indicadores para chamar a função ao receber novas cotações. | void OnTick(void); |
OnCalculate | Pode ser usado em indicadores para chamar a função ao enviar o evento Init e a qualquer alteração dos dados de preço. |
int OnCalculate( const int rates_total, // price[] array size const int prev_calculated, // number of handled bars at the previous call const int begin, // index number in the price[] array meaningful data starts from const double& price[] // array of values for calculation );
int OnCalculate( const int rates_total, // size of input time series const int prev_calculated, // number of handled bars at the previous call const datetime& time{}, // Time array const double& open[], // Open array const double& high[], // High array const double& low[], // Low array const double& close[], // Close array const long& tick_volume[], // Tick Volume array const long& volume[], // Real Volume array const int& spread[] // Spread array ); |
OnTimer | Pode ser usado em Expert Advisors e indicadores para chamar a função no evento Timer. | void OnTimer(void); |
OnTrade | Pode ser usado em Expert Advisors para chamar a função quando uma operação de negociação for concluída no servidor de negociação. | void OnTrade(void); |
OnTradeTransaction | Pode ser usado em Expert Advisors para chamar a função ao executar determinadas ações na conta de negociação. | void OnTradeTransaction() const MqlTradeTransaction& trans, // trade transaction structure const MqlTradeRequest& request, // request structure const MqlTradeResult& result // response structure ); |
OnBookEvent | Pode ser usado em Expert Advisors para chamar uma função quando o livro de ofertas muda. | void OnBookEvent( const string& symbol // symbol ); |
OnChartEvent | Pode ser usado em indicadores para chamar uma função quando o usuário trabalha com um gráfico. | void OnChartEvent() const int id, // event ID const long& lparam, // long type event parameter const double& dparam, // double type event parameter const string& sparam // string type event parameter ); |
OnTester | Pode ser usado em Expert Advisors para chamar a função quando o EA terminar de testar com dados históricos. | double OnTester(void); |
OnTesterInit | Pode ser usado em Expert Advisors para chamar uma função com o início da otimização no testador de estratégia antes da primeira passagem da otimização. |
int OnTesterInit(void);
void OnTesterInit(void); |
OnTesterDeinit | Pode ser usado para chamar a função depois que o EA tiver sido otimizado no testador de estratégias. | void OnTesterDeinit(void); |
OnTesterPass | Pode ser usado em Expert Advisors para chamar uma função quando uma nova porção de dados é recebida. | void OnTesterPass(void); |
Você pode aprender mais sobre o tratamento de eventos lendo a documentação do MQL5.
Exemplo de programa no MQL5
Nesta seção, aplicaremos o conhecimento adquirido para criar um aplicativo simples usando a estrutura certa respetiva ao MQL5. Mencionamos que podemos usar os componentes da estrutura do MQL5, dependendo do tipo de programa e da tarefa necessária. Não há obrigações de usar alguns desses componentes, como a diretiva #include, pois pode não ser necessário incluir componentes externos. O mesmo se aplica ao #property. Criar classes ou funções personalizadas no programa também pode não ser necessário. De qualquer forma, você usará o que for necessário para o seu programa. Abaixo, estão exemplos simples de aplicação de todos os componentes estruturais necessários, com base em diferentes tipos de programas.
Script:
Aqui está um exemplo simples de um script MQL5 que pode calcular e somar dois números inseridos pelo usuário usando dados de entrada e imprimir o resultado na guia "Experts" usando a função Print. Vamos adicionar a propriedade #property, que permitirá exibir os dados de entrada do script para que o usuário possa inserir os números.
//+------------------------------------------------------------------+ //| Script program example.mq5 | //| Copyright 2023, MetaQuotes Ltd.| //| https://www.mql5.com | //+------------------------------------------------------------------+ //property preprocessor #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property script_show_inputs //inputs input int userEntryNum1; input int userEntryNum2; //global variable int result; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ //event handler void OnStart() { result=userEntryNum1+userEntryNum2; Print("Result: ", result); } //+------------------------------------------------------------------+
Se desejarmos criar outro EA ou indicador, precisaremos usar manipuladores de eventos diferentes, dependendo do tipo de programa. Por exemplo, um EA pode realizar uma ação quando receber um novo tick, usando o manipulador OnTick().
Agora que definimos a estrutura de um programa MQL5, podemos ver que alguns componentes variam de acordo com o tipo de programa e seus objetivos. Esse entendimento nos ajuda a determinar a posição de cada componente no programa.
Para aplicar esse conhecimento, podemos começar com um simples script, como mencionado anteriormente.
Considerações finais
Analisamos a estrutura de um programa MQL5 e podemos identificar quais componentes são necessários:
- Pré-processador
- Substituição de macro (#define)
- Propriedades do programa (#property):
- Inclusão de arquivos (#include):
- Importação de funções (#import):
- Compilação condicional (#ifdef, #ifndef, #else, #endif)
- Variáveis de entrada e globais
- Funções e classes
- Manipuladores de eventos
- OnStart
- OnInit
- OnDeinit
- OnTick
- OnCalculate
- OnTimer
- OnTrade
- OnTradeTransaction
- OnBookEvent
- OnChartEvent
- OnTester
- OnTesterInit
- OnTesterDeinit
- OnTesterPass
Espero que este artigo tenha sido útil para você. Se desejar aprender mais sobre a criação de um sistema de negociação usando indicadores técnicos populares, você pode consultar meus outros artigos.
Além disso, escrevi sobre a criação e o uso de indicadores personalizados em qualquer EA e outros tópicos importantes de programação no MQL5, como programação orientada a objetos (POO) e funções. Acredito que esses artigos serão úteis para aprendizado e negociação.
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/13021
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso