English Русский 中文 Español Deutsch 日本語
preview
Funções em Aplicativos MQL5

Funções em Aplicativos MQL5

MetaTrader 5Negociação | 23 novembro 2023, 09:34
369 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Introdução

No mundo da programação, existe um termo muito popular que usamos com frequência e ouvimos devido à sua importância em qualquer software, nomeadamente a função. É exatamente isso que abordaremos neste artigo, para aprender a criar software funcional e de qualidade. Vamos explorar o que são funções, por que precisamos usá-las e como aplicá-las em nossos aplicativos. Após isso, examinaremos algumas funções simples que podem ser usadas em qualquer sistema de negociação. Ao longo do artigo, abordaremos os seguintes tópicos:

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 oferece nenhuma 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.


Definição de Função

Nesta seção, forneceremos uma definição de funções na programação, bem como seus tipos e benefícios. Uma função é um bloco de código declarado com um nome significativo que pode ser usado em qualquer parte do programa, chamando-o repetidamente para realizar uma tarefa específica. Se tivermos uma tarefa específica que o programa deve executar em várias partes ou em vários programas, criamos uma função ou um bloco de código para realizar essa tarefa e, em seguida, a chamamos apenas nessas partes, sem reescrever o código completo novamente. Desse modo, podemos dizer que uma função é um método de abstrair nosso código. As funções são divididas em funções embutidas e funções personalizadas. As embutidas são funções prontas da própria linguagem de programação, enquanto as personalizadas são criadas pelo usuário de acordo com suas necessidades ou tarefas. Neste artigo, focaremos em funções personalizadas.

Suponhamos que precisemos que o programa feche todas as ordens abertas quando o patrimônio atingir o máximo rebaixamento. Essa tarefa deve ser executada em várias partes do programa. Nesse caso, é melhor criar uma função e incorporar o código ou lógica necessários para realizar essa tarefa e, em seguida, chamá-la em outras partes, em vez de repetir o mesmo código em todos os lugares necessários.

Para responder à pergunta de por que devemos usar esse tipo de função, é necessário examinar as características do uso de funções personalizadas:

  • Funções personalizadas permitem a aplicação do método DRY (don't repeat yourself, não se repita): Criamos uma função que pode realizar uma tarefa uma vez e, em seguida, chamá-la em qualquer parte apropriada do software.
  • Reutilização: Após a criação de uma função, podemos reutilizá-la a qualquer momento.
  • "Dividir e Conquistar": Podemos dividir uma tarefa complexa em tarefas menores e resolvê-las com a ajuda de funções.
  • O código se torna mais legível e compreensível: Cada elemento do código resolve uma tarefa específica.
  • Abstração: Sem funções, precisaríamos de mais linhas de código.
  • Encapsulamento: Funções permitem proteger o código e os dados, além de simplificar o controle sobre eles.
  • Simplificação da depuração: Funções tornam significativamente mais fácil localizar e corrigir erros.


Estrutura da Função

Nesta seção, abordaremos:

  • Declaração ou definição de uma função
  • Chamada de função

Em primeiro lugar, precisamos definir ou declarar uma nova função, portanto, devemos realizar aproximadamente o seguinte:

returnedDataType functionName(param1, param2)
{
        bodyOfFunction
}
  • (returnedDataType) - o tipo de dados que a função deve retornar após a execução.
  • (functionName) - o nome da função (correspondente à tarefa a ser executada).
  • (param1, param2) - variáveis ou espaços reservados (se necessário).
  • (bodyOfFunction) - todo o código que executa a tarefa. 

Vou apresentar um exemplo simples. Se precisarmos criar uma função simples para realizar a tarefa de adicionar dois valores, podemos fazer isso com o seguinte bloco de código:

//addition function
// returned data type is an integer - the name of the function is add - parameters or arguments are two int variables val1 and val2
int add(int val1, int val2)
  {
   //body of function that we need the function to perform when calling it
   //create a result new variable to be assigned by the result of val1 and val2 addition
   int result = val1+val2;
   //Print result in the experts tab
   Print(result);
   //returning value
   return result;
  }

Após definirmos nossa função, precisamos chamá-la. Isso pode ser feito chamando o nome da função e especificando os parâmetros desejados de acordo com nossa função na parte apropriada do código. Em nosso exemplo, a chamada da função ficaria assim:

   //calling our defined function by its name and specifying arguments
   add(5,15);

Ao chamar, podemos obter o resultado de 20 na guia de Experts de acordo com nossa função e os argumentos especificados, como mostrado na figura a seguir.

adicionar resultado da função

O exemplo anterior demonstra o que podemos fazer com uma função, mas existem muitas características disponíveis que podemos usar em funções. Alguns deles são listados abaixo.

Função com Argumentos

No último exemplo, usamos duas variáveis inteiras: val1 e val2. Essas variáveis são consideradas argumentos em nossa função. Esses argumentos podem ser inteiros, strings, etc. No nosso último exemplo, eram variáveis inteiras. Vamos considerar um exemplo semelhante com argumentos de string:

//sayHello function
// returned data type is string - name of function is sayHello - parameters or arguments are two string variables greeting and name
string sayHello(string greeting, string name)
  {
   //body of function that we need the function to perform when calling it
   //create a result new variable to be assigned by the result of greeting and name addition
   string result = greeting+name;
   //Print result in the experts tab
   Print(result);
   //returning value
   return result;
  }

Podemos chamar esta função da mesma forma mencionada anteriormente e encontrar seu resultado após a execução, como mostrado abaixo:

resultado da função sayhello

Eles também podem ser uma combinação desses tipos de dados, dependendo do que precisamos em nossa função como parâmetros ou argumentos para executar o corpo da função. Esses argumentos também podem representar um número necessário.

Função sem Argumentos

Uma função pode ser declarada ou definida sem especificar parâmetros ou argumentos e simplesmente dar a ela um nome significativo, e então deixar os argumentos em branco e preencher o corpo da função para realizar a tarefa, e então chamar a função sem especificar argumentos:

//sayHello function
// returned data type is a string - the name of the function is sayHello - no parameters
string sayHello()
  {
   //body of the function that we need the function to perform when calling it
   //create a result new variable to be assigned by the result of greeting and name addition
   string greeting= "Hello, ";
   string name= "World!";
   string result = greeting+name;
   //Print the result in the experts' tab
   Print(result);
   //returning value
   return result;
  }

Quando chamamos a função, ela ficará assim:

sayHello();

O resultado será o mesmo que mencionamos anteriormente na função com argumentos, pois o corpo da função é o mesmo.

Função com Valores Padrão

Também podemos definir uma função e atribuir valores iniciais ou padrão aos parâmetros, mas ainda podemos alterá-los ou atualizá-los, definindo os valores desejados.

//defining function with default values
string sayHello(string greeting= "Hello, ", string name="World!")
  {
   string result = greeting+name;
   Print(result);
   return result;
  }

Então, podemos chamar a função duas vezes para determinar a diferença entre os valores padrão. Se não especificarmos os parâmetros, a função retornará os valores padrão:

   sayHello();
   sayHello("Hi, ", "Developer!");

Resultado:

resultado da função sayhello

Passagem de Parâmetros

Como mencionado anteriormente, podemos passar dados de qualquer tipo para a função: inteiros, strings, arrays, etc. Ao passar parâmetros por valor, as variáveis originais na função permanecerão inalteradas, assim como ao passar valores de parâmetros para a função. Também podemos passar parâmetros da função por referência se precisarmos atualizar as variáveis originais.

Aqui está um exemplo simples para entender o que falamos sobre passagem por referência.

//passing by reference
void updateNums(int &val1, int &val2)
  {
   val1*=2;
   val2/=2;
  }

Em seguida, criaremos novas variáveis, imprimiremos seus valores e chamaremos nossa função com essas novas variáveis como parâmetros e imprimiremos seus valores após a chamada, para ver a diferença:

//new variables
   int firstNum = 10;
   int secondNum = 20;
   
//before calling function
   Print("before calling: ");
   Print(firstNum, " - " ,secondNum, "\n"); 
   
// calling   
   updateNums(firstNum, secondNum);

// after calling  
   Print("after calling: ");
   Print(firstNum, " - " ,secondNum, "\n"); 

Como resultado, obtemos os valores das novas variáveis 10 e 20, e após a chamada, eles são alterados para 20 e 10 de acordo com o corpo da função. Resultado:

passagem por referência

Operador return

Se tivermos uma função que retorna um valor, ela deve ter um operador return. Dependendo da tarefa da função, podemos ter mais de um operador return na função, mas se a função retornar um valor, a última linha da função deve ter pelo menos um operador return. Ele pode ser de qualquer tipo, exceto um array. No entanto, podemos retornar um elemento de um array. Se quisermos que a função retorne um array, podemos passar o array para a função por referência, como mencionado anteriormente.

Aqui está um exemplo com o operador return.

string sayHello(string greeting= "Hello, ", string name="World!")
  {
   string result = greeting+name;
   Print(result);
   return result;
  }

Função do tipo void

Se tivermos uma função que não retorna um valor, usamos a função do tipo void, pois esse tipo não retorna um valor. Normalmente, podemos passar parâmetros para uma função desse tipo, mas não é necessário ter um operador return. Aqui está um exemplo desse tipo de função.

void add(int val1, int val2)
  {
   int result= val1+val2;
  }

Sobrecarga de Funções

Em alguns casos, podemos ter funções com o mesmo nome para realizar a mesma tarefa, mas com diferentes parâmetros. Por exemplo, se tivermos a tarefa de adição, mas precisarmos realizar essa adição para dois valores e também precisarmos fazer a mesma tarefa para três valores, criamos duas funções com o mesmo nome, mas alteramos os parâmetros de acordo com a tarefa. Isso significa que temos uma função de sobrecarga que realiza a mesma tarefa, mas com diferentes parâmetros.

Esses diferentes parâmetros podem ser de tipos diferentes, números do mesmo tipo de dados ou ambos. Aqui está um exemplo de sobrecarga de função com o mesmo tipo de dados, mas com diferentes números de parâmetros:

void overloadingFun(int val1, int val2)
{
   int result=val1+val2;
}

void overloadingFun(int val1, int val2, int val3)
{
   int result=val1+val2+val3;
}

Como podemos ver, temos a mesma função, mas os parâmetros são diferentes. Quando chamamos a função, vemos que essas duas funções aparecem quando digitamos o nome da função, e então podemos escolher o que precisamos de acordo com os detalhes de nossa tarefa. Aqui está um exemplo de sobrecarga de função com diferentes parâmetros, dependendo do tipo de dados:

void overloadingFun(int val1, int val2)
{
   int result=val1+val2;
}

void overloadingFun(string message, int val1, int val2)
{
   int result=message+val1+val2;
}

Também podemos selecionar a função desejada com base nos parâmetros ao chamar a função.


Aplicativos

Nesta seção, criaremos aplicativos simples usando funções. Depois de criar os aplicativos, podemos chamá-los em diferentes partes do software ou até mesmo em outro software.

Notificação de Notícias

Negociar durante eventos econômicos é considerado muito arriscado e indesejável. O calendário econômico contém notícias macroeconômicas e indicadores com descrições, datas, horários e graus de importância, bem como os valores desses eventos econômicos. Existem muitas fontes que fornecem atualizações desses valores importantes. O calendário econômico também está disponível na plataforma de negociação MetaTrader 5. Você pode encontrá-lo na guia "Ferramentas" e personalizá-lo de acordo com suas preferências em termos de importância, moedas e países. Também existem funções embutidas para trabalhar com o calendário econômico. Você pode encontrá-las na documentação do MQL5:

Funções do Calendário Econômico

Bem, precisamos verificar manualmente o calendário econômico para evitar a negociação durante notícias ou criar um aplicativo que nos alertará sobre a aproximação de notícias. Essa é uma tarefa constante que será necessária em qualquer sistema de negociação ou em muitas partes do software. Podemos criar a função necessária e, em seguida, chamá-la facilmente. É isso que faremos:

Este aplicativo será um EA. Na área global, criaremos um tipo bool com o nome de nossa função (isNewsComing), não adicionaremos parâmetros.

bool isNewsComing()

O corpo da função cria um array chamada valores, cujo tipo será (MqlCalendarValue), representando os valores das notícias, em particular o valor real.

MqlCalendarValue values[];

Precisamos determinar o dia atual, definindo o horário de início do dia com (iTime) para retornar o horário de abertura da barra após a declaração de uma nova variável datetime chamada (startTime) e o horário de término do dia, que será igual ao horário de início definido mais o número de segundos no dia com a função (PeriodSeconds) após a declaração de uma nova variável datetime para (endTime).

   datetime startTime=iTime(_Symbol,PERIOD_D1,0);
   datetime endTime=startTime+PeriodSeconds(PERIOD_D1);

Vamos obter um array de valores de todos os eventos do dia usando o horário de início e término definido para determinar o intervalo de tempo e ordenar por país e moeda atual com a função CalendarValueHistory. Os parâmetros são o array de valores, horário de início, horário de término, país e moeda.

CalendarValueHistory(values,startTime,endTime,NULL,NULL);

Vamos criar um laço começando com o valor (0) para a variável int (i) criada e continuaremos o laço se (i) for menor que o tamanho do array de valores e incrementaremos (i) em um.

for(int i=0; i<ArraySize(values); i++)

O corpo do laço for cria uma variável de evento e seu tipo (MqlCalendarEvent) para descrições de eventos. Isso pode ser usado em (CalendarEventById).

MqlCalendarEvent event;

Obtemos a descrição do evento pelo seu identificador usando (CalendarEventById), e seus parâmetros são event_id e o evento.

CalendarEventById(values[i].event_id,event);

Criamos uma variável de país, seu tipo será (MqlCalendarCountry) para descrições de países, e isso pode ser usado com (CalendarCountryById).

MqlCalendarCountry country;

Obtemos descrições de país pelo seu identificador usando a função (MqlCalendarCountry). Seus parâmetros são Country_id e o país.

CalendarCountryById(event.country_id,country);

Configuramos as condições para filtrar eventos pelo símbolo atual ou notícias de moeda. A importância das notícias é média ou alta.

      if(StringFind(_Symbol,country.currency)<0)
         continue;

      if(event.importance==CALENDAR_IMPORTANCE_NONE)
         continue;
      if(event.importance==CALENDAR_IMPORTANCE_LOW)
         continue;

Configuramos a condição com um intervalo de tempo de notificação (30 segundos antes das notícias).

      if(TimeCurrent()>=values[i].time-30*PeriodSeconds(PERIOD_M1) &&
         TimeCurrent()<values[i].time+30*PeriodSeconds(PERIOD_M1))

Em seguida, precisamos imprimir uma mensagem na guia "Experts" com o nome do evento e o texto (está chegando! Pare de negociar...)

Print(event.name, " is coming! Stop Trading...");

O valor de retorno é verdadeiro.

return true;

Se as condições não forem atendidas, encerraremos o laço e retornaremos falso para encerrar a função.

return false;

Em seguida, podemos chamar a função na função OnTick, e se ela retornar verdadeiro, precisamos imprimir a mensagem (Notícias estão chegando...!)

   if(isNewsComing())
     {
      Print("News is comming...!");
     }

Agora criamos a função, a chamamos e podemos usá-la em qualquer parte de nosso programa conforme necessário. O seguinte é destinado a facilitar a leitura do código completo em um único bloco. Os arquivos de código-fonte de todas as aplicações estão anexados ao artigo.

//+------------------------------------------------------------------+
//| News Alert Function                                              |
//+------------------------------------------------------------------+ 
void OnTick()
  {
   if(isNewsComing())
     {
      Print("News is comming...!");
     }
  }
//+------------------------------------------------------------------+
bool isNewsComing()
  {
   MqlCalendarValue values[];
   datetime startTime=iTime(_Symbol,PERIOD_D1,0);
   datetime endTime=startTime+PeriodSeconds(PERIOD_D1);
   CalendarValueHistory(values,startTime,endTime,NULL,NULL);
   for(int i=0; i<ArraySize(values); i++)
     {
      MqlCalendarEvent event;
      CalendarEventById(values[i].event_id,event);
      MqlCalendarCountry country;
      CalendarCountryById(event.country_id,country);
      if(StringFind(_Symbol,country.currency)<0)
         continue;
      if(event.importance==CALENDAR_IMPORTANCE_NONE)
         continue;
      if(event.importance==CALENDAR_IMPORTANCE_LOW)
         continue;
      if(TimeCurrent()>=values[i].time-30*PeriodSeconds(PERIOD_M1) &&
         TimeCurrent()<values[i].time+30*PeriodSeconds(PERIOD_M1))
        {
         Print(event.name, " is coming! Stop Trading...");
         return true;
        }
     }
   return false;
  }
//+------------------------------------------------------------------+

Cálculo do Tamanho do Lote

Precisamos criar um aplicativo que seja capaz de calcular o tamanho do lote ideal após determinar a porcentagem de risco e a perda máxima em pontos. Também precisamos criar uma função sobrecarregada para calcular o tamanho do lote ideal após determinar a porcentagem de risco, o preço de entrada e o preço do stop loss. Vamos criar este aplicativo como um script:

Criamos uma função chamada OptimalLotSize como double. A primeira função terá dois parâmetros, especificamente uma variável double para a porcentagem máxima de risco e uma variável double para a perda máxima em pontos.

double OptimalLotSize(double maxRiskPrc, double maxLossInPips)

Em seguida, indicamos o que precisa ser feito para esses parâmetros. Primeiro, determinamos o valor da equidade da conta usando a função (AccountInfoDouble), que retorna o valor da propriedade apropriada da conta. Neste caso, é o identificador da equidade da conta (ENUM_ACCOUNT_INFO_DOUBLE). Criamos uma notificação com o valor necessário.

   double accEquity = AccountInfoDouble(ACCOUNT_EQUITY);
   Alert("accEquity: ", accEquity);

Vamos determinar o tamanho do contrato do símbolo usando a função (SymbolInfoDouble), que retorna a propriedade correspondente do símbolo especificado com o nome do símbolo (_Symbol) para obter o símbolo atual e prop_id igual a (SYMBOL_TRADE_CONTRACT_SIZE) como um dos valores (ENUM_SYMBOL_INFO_DOUBLE). Vamos criar uma notificação com esse valor retornado.

   double lotSize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_CONTRACT_SIZE);
   Alert("lotSize: ", lotSize);

Vamos calcular o custo do ponto e criar uma notificação com o valor necessário.

   double tickValue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE);
   Alert("tickValue: ", tickValue);

Vamos calcular o valor máximo de perda com base no patrimônio líquido especificado e criar uma notificação com esse valor.

   double maxLossDollar = accEquity * maxRiskPrc;
   Alert("maxLossDollar: ", maxLossDollar);

Vamos calcular o valor máximo em moeda de cotação com base no valor máximo de perda calculado e retornar uma notificação com esse valor.

   double maxLossInQuoteCurr = maxLossDollar / tickValue;
   Alert("maxLossInQuoteCurr: ", maxLossInQuoteCurr);

Vamos calcular o tamanho ideal do lote e retornar uma notificação com o valor necessário.

   double OptimalLotSize = NormalizeDouble(maxLossInQuoteCurr / (maxLossInPips * 0.0001)/ lotSize,2);
   Alert("OptimalLotSize: ", OptimalLotSize);

O operador return retorna OptimalLotSize como um valor double.

return OptimalLotSize;

Em seguida, criaremos uma função de sobrecarga, passando três parâmetros double para a porcentagem máxima de risco, preço de entrada e preço do stop-loss.

double OptimalLotSize(double maxRiskPrc, double entryPrice, double stopLoss)

Vamos definir a perda máxima em pips como o valor absoluto com base nos parâmetros de preço de entrada e preço do stop-loss, seguido pela divisão por 0.0001.

double maxLossInPips = MathAbs(entryPrice - stopLoss)/0.0001;

O operador return utilizará a função OptimalLotSize criada com os parâmetros de porcentagem máxima de risco e perda máxima em pontos.

return OptimalLotSize(maxRiskPrc,maxLossInPips);

Então, podemos chamar qualquer uma das duas funções na parte OnStart() de acordo com o que precisamos.

OptimalLotSize(0.01, 1.12303, 1.11920);

Aqui está o código completo para criar uma função desse tipo.

//+------------------------------------------------------------------+
//| lotSize Calc Function                                            |
//+------------------------------------------------------------------+
void OnStart()
  {
   OptimalLotSize(0.01, 1.12303, 1.11920);
  }
//+------------------------------------------------------------------+
double OptimalLotSize(double maxRiskPrc, double maxLossInPips)
  {
   double accEquity = AccountInfoDouble(ACCOUNT_EQUITY);
   Alert("accEquity: ", accEquity);
   double lotSize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_CONTRACT_SIZE);
   Alert("lotSize: ", lotSize);
   double tickValue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE);
   Alert("tickValue: ", tickValue);
   double maxLossDollar = accEquity * maxRiskPrc;
   Alert("maxLossDollar: ", maxLossDollar);
   double maxLossInQuoteCurr = maxLossDollar / tickValue;
   Alert("maxLossInQuoteCurr: ", maxLossInQuoteCurr);
   double OptimalLotSize = NormalizeDouble(maxLossInQuoteCurr / (maxLossInPips * 0.0001)/ lotSize,2);
   Alert("OptimalLotSize: ", OptimalLotSize);
   return OptimalLotSize;
  }
//+------------------------------------------------------------------+
double OptimalLotSize(double maxRiskPrc, double entryPrice, double stopLoss)
  {
   double maxLossInPips = MathAbs(entryPrice - stopLoss)/0.0001;
   return OptimalLotSize(maxRiskPrc,maxLossInPips);
  }
//+------------------------------------------------------------------+

Ao executar este script, obteremos o seguinte aviso:

 lotSize

Assim como no caso do aplicativo anterior, temos a função lotSize Calc que podemos usar e chamar facilmente em várias partes do programa para realizar a tarefa sem reescrever o código.

Encerramento de Todas as Posições Abertas

Aqui, precisamos criar um script que possa fechar todas as ordens abertas e pendentes, criando uma função que possa ser usada ou chamada em qualquer parte apropriada do programa.

Vamos incluir a classe Trade no código usando uma diretiva de pré-processamento ou #include para incorporar todas as funções de negociação no arquivo (Trade.mqh).

#include <Trade/Trade.mqh>

Vamos criar um objeto com o tipo de classe CTrade, que será usado no programa.

CTrade trade;

Na área global, também precisamos criar uma função void closeAll sem argumentos.

void closeAll()

O corpo da função cria um laço for para verificar as ordens abertas.

for(int i=PositionsTotal()-1; i>=0; i--)

 No corpo do laço, criamos uma variável ulong posTicket e atribuímos a ela o número do bilhete das ordens abertas.

ulong posTicket=PositionGetTicket(i);

Vamos fechar a posição aberta usando trade.PositionClose(posTicket).

trade.PositionClose(posTicket);

Vamos remover as ordens pendentes, criando mais um laço for para identificá-las, atribuir seus bilhetes à variável ulong posTicket e removê-las com base no bilhete identificado da ordem pendente.

   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      ulong posTicket=OrderGetTicket(i);
      trade.OrderDelete(posTicket);
     }

Depois disso, podemos chamar essa função em OnStart().

closeAll();

O script fecha e remove todas as ordens. Abaixo está o código completo do closeAllApp:

//+------------------------------------------------------------------+
//| closeAll Function                                                |
//+------------------------------------------------------------------+ 
#include <Trade/Trade.mqh>
CTrade trade;
//+------------------------------------------------------------------+
void OnStart()
  {
   closeAll();
  }
//+------------------------------------------------------------------+
void closeAll()
  {
//close all open positions
   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      ulong posTicket=PositionGetTicket(i);
      trade.PositionClose(posTicket);
     }
//delete all pending orders
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      ulong posTicket=OrderGetTicket(i);
      trade.OrderDelete(posTicket);
     }
  }
//+------------------------------------------------------------------+

Os aplicativos discutidos são apenas exemplos do que podemos criar usando funções personalizadas. Você pode criar qualquer outro aplicativo ou função de acordo com suas necessidades, como aplicativos de trailing stop, gerenciamento de negociações, rebaixamento etc.


Considerações finais

O uso de funções possui várias vantagens incontestáveis:

  • As funções permitem a aplicação do princípio DRY.
  • Isso ajuda a simplificar a resolução de qualquer grande tarefa, dividindo-a em partes menores.
  • Torna o código mais legível.
  • Possibilita a reutilização.
  • Abstração do código.
  • Encapsulamento do código.
  • Melhora a depuração.

Também discutimos os tipos de funções (built-in e personalizadas), bem como sua criação e definição, examinamos a estrutura das funções e suas características, incluindo funções com argumentos e como passar esses argumentos ou parâmetros com ou sem argumentos, bem como funções com valores padrão. Supõe-se que você possa definir uma função usando qualquer tipo de dado e trabalhar com o operador return, além de saber como criar várias funções de sobrecarga com o mesmo nome, mas com argumentos diferentes para realizar a mesma tarefa.

Espero que os exemplos de aplicativos tenham ajudado a compreender melhor o tópico:

  • New Alert App - notificações sobre notícias importantes. Pode ser usado ou chamado em qualquer parte do programa. O código-fonte do aplicativo de alerta de notícias está anexado abaixo.
  • Lot size Calc App - obtenção do tamanho de lote ideal para abrir uma negociação com base em uma porcentagem de risco específica, preço de entrada e preço de stop loss. Ou com base em uma porcentagem de risco específica e perda máxima em pontos, o que significa que criamos uma função de sobrecarga neste aplicativo. Também pode ser usado ou chamado em qualquer parte do programa. O código-fonte do aplicativo de cálculo do tamanho do lote está anexado abaixo.
  • Close All App - fecha todas as ordens abertas e pendentes. O código-fonte do aplicativo de fechamento de todos está anexado abaixo.

O mundo das funções é muito interessante, e é fundamental prestar atenção a ele para poder criar facilmente fragmentos de código úteis. Espero que este artigo tenha sido útil para você e expandido seu arsenal de ferramentas de negociação. Se você deseja aprender mais sobre programação ou como criar sistemas de negociação com base nos indicadores técnicos mais populares, como média móvel, RSI, MACD, estocástico, Bandas de Bollinger, Parabolic SAR...e outros, você pode ler meus artigos anteriores e, talvez, encontrar algo útil.

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

Arquivos anexados |
newsAlertApp.mq5 (1.37 KB)
lotSizeCalcApp.mq5 (1.45 KB)
closeAllApp.mq5 (0.86 KB)
O modelo de movimento de preços e suas principais disposições (Parte 3): Cálculo dos parâmetros ótimos para negociação em bolsa O modelo de movimento de preços e suas principais disposições (Parte 3): Cálculo dos parâmetros ótimos para negociação em bolsa
Dentro da abordagem de engenharia desenvolvida pelo autor, baseada na teoria da probabilidade, são determinadas as condições para abrir uma posição lucrativa e calculados os valores ótimos - maximizadores do lucro - para o take profit e o stop loss.
StringFormat(). Visão geral, exemplos de uso prontos StringFormat(). Visão geral, exemplos de uso prontos
O artigo é uma continuação da revisão da função PrintFormat(). Veremos brevemente a formatação de strings usando StringFormat() e seu uso posterior no programa. Escreveremos modelos para exibir informações sobre um símbolo no log do terminal. Este artigo será útil tanto para iniciantes quanto para desenvolvedores experientes.
Transformada Discreta de Hartley Transformada Discreta de Hartley
Neste artigo, vamos nos familiarizar com um dos métodos de análise espectral e processamento de sinais - a transformada discreta de Hartley. Com ela, é possível filtrar sinais, analisar seus espectros e muito mais. As capacidades da DHT não são menores do que as da transformada discreta de Fourier. No entanto, ao contrário dela, a DHT utiliza apenas números reais, o que a torna mais conveniente para implementação na prática, e os resultados de sua aplicação mais visíveis.
Desenvolvendo um sistema de Replay (Parte 36): Ajeitando as coisas (II) Desenvolvendo um sistema de Replay (Parte 36): Ajeitando as coisas (II)
Uma das coisas que mais pode complicar a nossa vida como programadores é o fato de supor as coisas. Neste artigo mostrarei o perigo de fazer suposições. Tanto na parte da programação em MQL5, onde você supõem que um tipo terá um dado tamanho. Assim como no uso do MetaTrader 5, onde você supõem que servidores diferentes funcionam da mesma forma.