English Русский 中文 Español Deutsch 日本語
preview
Entendendo a programação orientada a objetos (POO) em MQL5

Entendendo a programação orientada a objetos (POO) em MQL5

MetaTrader 5Negociação | 13 outubro 2023, 08:55
538 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Introdução

Neste artigo, compartilharemos um dos tópicos mais importantes da programação, que facilita a escrita de código, e nos ajuda a aplicar o princípio DRY (Do Not Repeat Yourself, não se repita) como desenvolvedores e programadores. Além disso, aumenta a segurança de qualquer software criado e fornece outras características. Falaremos sobre programação orientada a objetos (POO) e como podemos usar esse conceito ao trabalhar com o MQL5 (MetaQuotes Language).

Assim, abordaremos esse tópico interessante e importante através das seções a seguir:

O principal objetivo deste artigo é entender os fundamentos da programação orientada a objetos (POO) em geral e como ela pode ser útil na criação de software. A partir daí, aprenderemos como podemos aplicar essa abordagem em MQL5 para utilizar o que pode nos ajudar a criar software mais eficaz e seguro.

Se necessário, você pode encontrar recursos informativos sobre esse conceito, uma vez que ele é aplicável a outras linguagens de programação, como C++, Java, Python e outras. Toda a informação necessária sobre a linguagem MQL5 pode ser encontrada na documentação oficial.

Atenção! Todo o conteúdo deste artigo é apresentado "tal qual como está", apenas para fins educacionais e não constitui uma recomendação de trading. O artigo não fornece qualquer garantia de resultados. Tudo o que você colocar em prática com base neste artigo, você faz exclusivamente por sua conta e risco, o autor não garante nenhum resultado.


O que é o POO?

Vamos começar com a definição de POO. A POO ajuda a criar e desenvolver software reutilizável sem duplicação de trabalho e código, aplicando o conceito DRY (don't repeat yourself, não se repita).

A POO nos ajuda a se aproximar da natureza do mundo, já que objetos nos cercam na vida cotidiana. Lidaremos com objetos e classes, onde objeto significa uma instância de uma classe e classe é um modelo para um objeto. Dentro do modelo, que é uma classe, detalhamos o comportamento do objeto.

Conceitos básicos de POO:

Ao usar POO no desenvolvimento, aplicam-se os seguintes princípios.

  1. Encapsulamento.
  2. Abstração.
  3. Herança.
  4. Polimorfismo.

POO

1. Encapsulamento:

O encapsulamento é um método que permite vincular funções e dados em uma única classe, onde os dados e funções podem ser privados - acessíveis apenas dentro da classe - ou públicos - acessíveis fora da classe. O encapsulamento ajuda a ocultar a complexidade da implementação da classe e dá ao desenvolvedor controle total sobre seus dados, ajudando a rastrear todos os valores dependentes sem conflitos.

O encapsulamento ajuda a manter a funcionalidade de nosso sistema e evita muitos erros possíveis, além de fornecer um alto nível de controle ao desenvolvedor e simplificar testes e manipulação de dados de classes sem afetar ou alterar todo o código de software. Também ajuda a corrigir erros e simplifica o código.

O próximo diagrama descreve o conceito de encapsulamento:

Encapsulamento

2. Abstração:

A abstração é um método de ocultar detalhes não essenciais e apresentar apenas os detalhes essenciais. É um conceito mais amplo do que a encapsulação, mas ajuda a alcançar o mesmo objetivo: proteger dados e implementar funções sem o conhecimento completo do processo de implementação de todas as classes, apenas com uma compreensão do que precisa ser feito para que a implementação seja concluída.

Para atingir esse objetivo, precisamos incorporar dois métodos importantes - interface e implementação. A interface é um método que permite que as classes interajam entre si, enquanto a implementação é um método que contém todos os detalhes do código ou lógica das classes. Assim, a abstração ajuda a aumentar a segurança do software e permite evitar a repetição do processo de codificação do zero, desenvolvendo e codificando mais aplicativos com base nos já criados.

3. Herança:

Pelo nome, o conceito de herança significa que obtemos uma nova classe a partir de uma antiga, e a nova herda as funções da antiga. Nesse caso, a classe antiga é chamada de classe pai ou superclasse, e a nova classe derivada é chamada de classe filha. Esse conceito ajuda a aplicar o princípio DRY (não se repita), mantendo a capacidade de reutilização.

Herança

4. Polimorfismo:

O polimorfismo permite que funções processem dados de diferentes tipos. Por exemplo, podemos usar um método de soma para obter valores da soma (a) e (b) e outro para obter a soma (a), (b) e (c).

Em termos simples, o polimorfismo significa uma única interface e múltiplos métodos.

Resumindo, podemos dizer que a programação orientada a objetos (POO) é um modelo de programação que se concentra na organização do desenvolvimento de software usando objetos, que podem ter comportamentos e características únicos. Este é um modelo útil em programas grandes e complexos, especialmente se eles são atualizados com frequência.

Características da POO:

  • Os programas que aplicam a POO incluem classes e funções.
  • Há um alto nível de segurança de dados devido ao uso dos princípios de encapsulamento e abstração.
  • Isso simplifica o trabalho em projetos complexos, pois o código pode ser dividido em pequenos blocos, o que pode reduzir a complexidade do projeto.
  • Os processos de atualização e desenvolvimento tornam-se mais simples.
  • A capacidade de reutilizar o código é alcançada por meio do princípio de herança.
  • A capacidade de criar várias instâncias da mesma classe sem conflitos.

Existem muitas linguagens de programação que podem aplicar a abordagem da POO. As mais populares incluem C++, C#, Python, Java, JavaScript, PHP e outras. MQL5 também está incluída nessa lista.


POO em MQL5

Nesta seção, abordaremos a POO em MQL5 e aprenderemos como usá-la.

Antes de aplicar a POO em MQL5, precisamos entender como podemos usá-la no MQL5 da seguinte forma:

  • Classes
  • Modificador de acesso
  • Construtores e destruidores
  • Classes derivadas (filhas)
  • Funções virtuais
  • Objetos

Classes:

Em MQL5, quando precisamos criar uma classe que servirá como um modelo para um objeto, devemos declarar essa classe na área de visibilidade global da mesma forma que fazemos com funções. Podemos criar essa classe usando a palavra-chave "class", seguida de um identificador único desejado. Em seguida, dentro das chaves, podemos colocar nossas variáveis e métodos que são membros da classe. Após o segundo conjunto de chaves, colocamos um ponto e vírgula para finalizar a declaração da classe. Podemos usar essa declaração de classe em nosso programa ou em um arquivo incluído.

Aqui está um exemplo da declaração dessa classe:

class Cobject
{
   int var1;       // variable1
   double var2;    // variable1
   void method1(); // Method or function1
};

Como podemos ver no exemplo anterior, temos três membros na classe: duas variáveis e um método ou função.

Modificadores de acesso:

Com esses modificadores de acesso, podemos definir quais variáveis e funções podemos usar fora da classe, e existem três palavras-chave de acesso: public, private e protected.

  • Public: membros que podem estar disponíveis para uso fora da classe.
  • Private: representa membros que não podem ser acessados para uso fora da classe, mas que só estão disponíveis para uso dentro da classe por meio de funções. A classe filha dessa classe não herdará esses membros privados.
  • Protected: representa elementos que serão herdados por classes filhas, mas que são privados por natureza.

Aqui está um exemplo:

class Cobject
{
   private:
   int var1;       // variable1
   protected:
   double var2;    // variable1
   public:
   void method1(); // Method or function1
};

Como podemos ver no exemplo anterior, temos três membros na classe com duas variáveis: uma é privada (private), outra é protegida (protected) e a terceira é pública (public).

Construtores e destruidores:

Se precisamos inicializar variáveis na classe, usamos um construtor. Se não o fornecermos, o compilador criará um por padrão, mas ele não será visível por padrão. O construtor também deve ser público. Um destrutor é uma função chamada automaticamente quando o objeto da classe é destruído. O destrutor tem o mesmo nome da classe, precedido pelo til (~). Independentemente de haver um destrutor ou não, strings, arrays dinâmicos e objetos requerem desalocação, então eles serão desalocados de qualquer maneira.

Abaixo está um exemplo de um construtor:

class CPrices
  {
private:
   double               open;         // Open price
   double               high;         // High price
   double               low;          // Low price
   double               close;        // Close price
public:
   //--- Default constructor
                     CPrices(void);
   //--- Parametric constructor
                     CPrices(double o,double h,double l, double c);
  };

Classes derivadas (filhas):

Como aprendemos anteriormente, o conceito de herança é uma das características mais valiosas e úteis da programação orientada a objetos (POO). Isso ocorre porque podemos criar uma classe filha de uma classe pai ou superclasse, e essa classe filha herda todos os membros da classe pai, exceto os privados. Depois disso, podemos adicionar novas variáveis e funções a essa classe filha.

Vejamos um exemplo: se tivermos uma classe pai para preços, podemos criar uma classe filha para preços diários, como mostrado abaixo:

class CDailyPrices : public CPrices
{
public:
   double               open;          // Open price
   double               high;          // High price
   double               low;           // Low price
   double               close;         // Close price
};

Como podemos ver, o nome da classe pai é "CPrices" e "CDailyPrices" é a classe filha. Todos os membros públicos e protegidos de "CPrices" fazem parte da classe "CDailyPrices" e ainda são públicos.

Funções virtuais:

Se quisermos atualizar a forma como um método ou função funciona em uma classe filha, podemos fazer isso usando uma função (virtual) na classe pai e, em seguida, definir a função na classe filha. Por exemplo, se tivermos duas versões diferentes de uma função com base em uma classe. Para a classe pai, definimos a função usando a palavra-chave "virtual".

class CVar
  {
public:
   virtual 
void varCal();
  };

Em seguida, atualizamos a mesma função na classe filha.

class CVar1 : public CVar
{
public:
 int varCal(int x, int y);
}; 

Objetos:

Os objetos têm um identificador único. Assim como ao criar uma variável, usaremos o nome da classe como o tipo antes do identificador do objeto. Podemos criar vários objetos pertencentes às nossas classes, pois só precisamos de um identificador único para cada um. Após declarar o objeto, podemos acessar qualquer membro público usando (.) - o ponto.

Vamos considerar um exemplo que mostra a criação de uma classe com uma variável inteira chamada "num_trades".

class CSystrades
{
public:
int num_trades;
};

Então, precisamos criar um objeto pertencente a esta classe, chamado "system1". Faremos isso seguindo estas etapas:

CSystrades system1;

Em seguida, podemos definir esse objeto com um valor (3):

system1.num_trades=3;

Exploramos como aplicar a programação orientada a objetos (POO) no MQL5, aprendendo alguns dos pontos mais importantes.

Exemplos de POOs

Nesta seção interessante, apresentaremos algumas aplicações simples da POO.

priceClass:

Neste aplicativo simples, precisamos verificar os preços em vários intervalos de tempo. Usamos três intervalos de tempo (diário, semanal e mensal). Também precisamos ver todos os preços (abertura, máxima, mínima, fechamento) em um só lugar, digamos, na guia "Experts". Após isso, podemos continuar a desenvolver programas mais complexos.

Em primeiro lugar, precisamos declarar uma classe seguindo estas etapas:

  • Declare uma classe para os preços na área global e torne todos os membros comuns públicos usando a palavra-chave "class". Use a palavra-chave "public".
  • Crie cinco variáveis (timeframe, open, high, low e close).
  • Crie uma função "void" para exibir todos os dados de preços.
  • Dentro da função OnInit, definiremos o seguinte para três timeframes:
class CPrices
  {
public:
   string            timeFrame;
   double            open;
   double            high;
   double            low;
   double            close;
   void              pricesPrint()
     {
      Print(timeFrame," Prices = Open: ",open," - ","High: ",high,"-","Low: ",low,"-","Close: ",close);
     }
  };

Vamos criar objetos da classe para os preços diários, semanais e mensais.

CPrices CDailyPrices;
CPrices CWeeklyPrices;
CPrices CMonthlyPrices;

Dentro da função OnInit, definiremos o seguinte para os três intervalos de tempo:

  • Uma string com o nome do timeframe.
  • O preço de abertura usando a função iOpen.
  • O preço máximo usando a função iHigh.
  • O preço mínimo usando a função iLow.
  • O preço de fechamento usando a função iClose.
  • Chamaremos a função ou método "print".
int OnInit()
  {
//--- Daily time frame
   CDailyPrices.timeFrame="Daily";
   CDailyPrices.open=(iOpen(Symbol(),PERIOD_D1,1));
   CDailyPrices.high=(iHigh(Symbol(),PERIOD_D1,1));
   CDailyPrices.low=(iLow(Symbol(),PERIOD_D1,1));
   CDailyPrices.close=(iClose(Symbol(),PERIOD_D1,1));
   CDailyPrices.pricesPrint();

//--- Weekly time frame
   CWeeklyPrices.timeFrame="Weekly";
   CWeeklyPrices.open=(iOpen(Symbol(),PERIOD_W1,1));
   CWeeklyPrices.high=(iHigh(Symbol(),PERIOD_W1,1));
   CWeeklyPrices.low=(iLow(Symbol(),PERIOD_W1,1));
   CWeeklyPrices.close=(iClose(Symbol(),PERIOD_W1,1));
   CWeeklyPrices.pricesPrint();

//--- Monthly time frame
   CMonthlyPrices.timeFrame="Monthly";
   CMonthlyPrices.open=(iOpen(Symbol(),PERIOD_MN1,1));
   CMonthlyPrices.high=(iHigh(Symbol(),PERIOD_MN1,1));
   CMonthlyPrices.low=(iLow(Symbol(),PERIOD_MN1,1));
   CMonthlyPrices.close=(iClose(Symbol(),PERIOD_MN1,1));
   CMonthlyPrices.pricesPrint();
   return(INIT_SUCCEEDED);
  }

Depois disso, podemos ver os preços após a execução do Expert Advisor na guia "Experts" da barra de ferramentas:

 Preços

Aqui vemos três linhas:

  • Na primeira linha, são exibidos os preços diários de abertura, máximo, mínimo e fechamento.
  • Na segunda linha, são exibidos os mesmos preços, mas em dados semanais.
  • Na terceira linha, são exibidos os mesmos preços, mas em dados mensais.

indicatorClass:

O programa deve exibir os valores de quatro tipos de médias móveis (simples, exponencial, suavizada e ponderada linearmente) usando POO. Aqui estão os passos simples para atingir esse objetivo:

Vamos declarar a classe do indicador CiMA usando a palavra-chave "class" e criar membros públicos para essa classe. São quatro variáveis públicas: MAType - para determinar o tipo de média móvel, MAArray - para determinar o array da média móvel, MAHandle - para determinar o handle de cada tipo, MAValue - para determinar o valor de cada média móvel. Também criaremos um método "void" ou uma função "valuePrint" e o corpo da função para exibir o valor de cada tipo de média móvel.

class CiMA
  {
public:
   string            MAType;
   double            MAArray[];
   int               MAHandle;
   double            MAValue;
   void              valuePrint()
     {
      Print(MAType," Current Value: ",MAValue);
     };
  };

Vamos criar os seguintes objetos para cada média móvel da classe:

  • Nome da média móvel
  • Handle da média móvel
  • Array da média móvel
//--- SMA
CiMA CSma;
CiMA CSmaHandle;
CiMA CSmaArray;

//--- EMA
CiMA CEma;
CiMA CEmaHandle;
CiMA CEmaArray;

//--- SMMA
CiMA CSmma;
CiMA CSmmaHandle;
CiMA CSmmaArray;

//--- LWMA
CiMA CLwma;
CiMA CLwmaHandle;
CiMA CLwmaArray;

Para cada tipo de média móvel, realizaremos as seguintes etapas dentro da função OnInit:

  • Definiremos o nome da média móvel.
  • Definiremos o handle da média móvel.
  • Configuraremos o sinalizador AS_SERIES para o array usando ArraySetAsSeries.
  • Obteremos os dados do buffer da média móvel usando a função CopyBuffer.
  • Definiremos o valor da média móvel e o normalizaremos usando a função NormalizeDouble.
  • Chamaremos o método ou função "Print".
int OnInit()
  {
   //--- SMA
   CSma.MAType="Simple MA";
   CSmaHandle.MAHandle=iMA(_Symbol,PERIOD_CURRENT,10,0,MODE_SMA,PRICE_CLOSE);
   ArraySetAsSeries(CSmaArray.MAArray,true);
   CopyBuffer(CSmaHandle.MAHandle,0,0,3,CSmaArray.MAArray);
   CSma.MAValue=NormalizeDouble(CSmaArray.MAArray[1],_Digits);
   CSma.valuePrint();

   //--- EMA
   CEma.MAType="Exponential MA";
   CEmaHandle.MAHandle=iMA(_Symbol,PERIOD_CURRENT,10,0,MODE_EMA,PRICE_CLOSE);
   ArraySetAsSeries(CEmaArray.MAArray,true);
   CopyBuffer(CEmaHandle.MAHandle,0,0,3,CEmaArray.MAArray);
   CEma.MAValue=NormalizeDouble(CEmaArray.MAArray[1],_Digits);
   CEma.valuePrint();

   //--- SMMA
   CSmma.MAType="Smoothed MA";
   CSmmaHandle.MAHandle=iMA(_Symbol,PERIOD_CURRENT,10,0,MODE_SMMA,PRICE_CLOSE);
   ArraySetAsSeries(CSmmaArray.MAArray,true);
   CopyBuffer(CSmmaHandle.MAHandle,0,0,3,CSmmaArray.MAArray);
   CSmma.MAValue=NormalizeDouble(CSmmaArray.MAArray[1],_Digits);
   CSmma.valuePrint();

   //--- LWMA
   CLwma.MAType="Linear-weighted MA";
   CLwmaHandle.MAHandle=iMA(_Symbol,PERIOD_CURRENT,10,0,MODE_LWMA,PRICE_CLOSE);
   ArraySetAsSeries(CLwmaArray.MAArray,true);
   CopyBuffer(CLwmaHandle.MAHandle,0,0,3,CLwmaArray.MAArray);
   CLwma.MAValue=NormalizeDouble(CLwmaArray.MAArray[1],_Digits);
   CLwma.valuePrint();
   return(INIT_SUCCEEDED);
  }

Após compilar e executar o código, veremos quatro linhas para cada tipo de média móvel. Cada linha exibirá o valor da média móvel:

 Valores do indicador

Como mencionado anteriormente, esses aplicativos podem ser aprimorados para realizar tarefas mais complexas. No entanto, nosso objetivo neste artigo é aprender os fundamentos da programação orientada a objetos (POO) e aplicá-los na prática.


Considerações finais

Neste artigo, exploramos os fundamentos de uma abordagem muito importante na programação. A programação orientada a objetos (POO) ajuda na criação de software seguro, simplificando o desenvolvimento ao dividir o código em pequenos blocos. Isso permite criar várias instâncias da mesma classe sem conflitos, mesmo que elas se comportem de maneira diferente, proporcionando maior flexibilidade e segurança nas atualizações.

Aprendemos também como aplicar essa abordagem importante no MQL5 para obter todas essas incríveis possibilidades. Em seguida, exploramos alguns aplicativos simples que podem ser criados aplicando a POO no MQL5.

Espero que o artigo tenha sido útil.

Se você deseja aprender mais sobre a criação de sistemas de negociação em MQL5 com base nos indicadores mais populares, bem como o desenvolvimento e aplicação de indicadores personalizados em Expert Advisors, você pode conferir meus outros artigos. Você pode encontrar a lista completa de artigos em meu perfil.

Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/12813

Arquivos anexados |
indicatorClass.mq5 (2.09 KB)
priceClass.mq5 (1.7 KB)
DoEasy. Controles (Parte 32): "ScrollBar" horizontal, rolagem com a roda do mouse DoEasy. Controles (Parte 32): "ScrollBar" horizontal, rolagem com a roda do mouse
Neste artigo, concluiremos o desenvolvimento do funcional do objeto de barra de rolagem horizontal. Vamos habilitar a capacidade de rolar o conteúdo do contêiner movendo o controle deslizante da barra de rolagem e girando a roda do mouse. Além disso, faremos adições à biblioteca para acomodar a nova política de execução de ordens e os novos códigos de erro de tempo de execução no MQL5.
ChatGPT da OpenAI dentro do framework de desenvolvimento MQL4 e MQL5 ChatGPT da OpenAI dentro do framework de desenvolvimento MQL4 e MQL5
Neste artigo, vamos experimentar e explorar a inteligência artificial ChatGPT da OpenAI, a fim de entender suas capacidades com o objetivo de reduzir o tempo e o esforço de desenvolvimento de seus Expert Advisors, indicadores e scripts. Vou rapidamente abordar essa tecnologia e tentar mostrar como usá-la corretamente para programar nas linguagens MQL4 e MQL5.
Redes neurais de maneira fácil (Parte 47): Espaço contínuo de ações Redes neurais de maneira fácil (Parte 47): Espaço contínuo de ações
Neste artigo, estamos ampliando o escopo das tarefas do nosso agente. No processo de treinamento, incluiremos alguns aspectos de gerenciamento de dinheiro e risco, que são partes integrantes de qualquer estratégia de negociação.
Desenvolvendo um sistema de Replay (Parte 30): Projeto Expert Advisor - Classe C_Mouse (IV) Desenvolvendo um sistema de Replay (Parte 30): Projeto Expert Advisor - Classe C_Mouse (IV)
Aqui demonstrarei uma técnica que pode lhe ajudar muito, em vários momentos durante a sua vida como programador. Diferente do que muitos dizem, não é a plataforma que é limitada, mas sim o conhecimento do individuo que diz que tal coisa. O que será explicado aqui, mostrar que com um pouco de bom senso e criatividade, você pode tornar a plataforma MetaTrader 5 muito mais interessante e versátil. E sem precisar de fato criar programas malucos ou coisas do estilo. Você pode criar um código simples, porém seguro e confiável. Usando de perspicácia, domar o código a fim de modificar algo já existente, sem se quer remover ou adicionar uma única linha se quer, no código original.