![Lite_EXPERT2.mqh: Kit Funcional para Desenvolvedores de Expert Advisors](https://c.mql5.com/i/articles/overlay.png)
Lite_EXPERT2.mqh: Kit Funcional para Desenvolvedores de Expert Advisors
Introdução
Nos artigos da série "Expert Advisors Baseados nos Sistemas de Negociação Populares e na Alquimia da Otimização de Robô de Negociação": 1, 2, 3, 4, 5, 6, 7, apresentei aos desenvolvedores novatos a minha abordagem para escrever um Expert Advisor que permite facilmente transformar estratégias de negociação em códigos de programas muito simples e rapidamente implementados, utilizando as funções de negociação personalizadas no Lite_EXPERT1.mqh. A fim de garantir a simplicidade máxima de informações, o número de funções personalizadas utilizadas neste arquivo são mínimas, sendo suficiente para obter o entendimento sem qualquer problema.
No entanto as funcionalidades oferecidas por esta série de artigos não é o suficiente para trabalhar com um código do programa em escala mais ampla. Lite_EXPERT2.mqh foi escrito com este objetivo, pois contém um conjunto mais universal de funções personalizadas que é complexo para um usuário de primeira viajem. Supõe-se que o leitor já está familiarizado com as informações publicadas no artigo "Expert Advisors Baseados nos Sistemas de Negociação Populares e na Alquimia da Otimização de Robô de Negociação 1" e considero este novo artigo como o próximo passo no desenvolvimento e melhoramento de suas habilidades necessárias para utilizar essas funções personalizadas.
O Conteúdo do Arquivo Lite_EXPERT2.mqh
De um modo geral, todas as funções disponíveis no Lite_EXPERT2.mqh podem ser mostradas na forma de fluxograma:
Além das funções, o Lite_EXPERT2.mqh contém o número inteiro da variável LastTime declarado no seu âmbito global e utilizado em todas as funções de negociação, bem como a variável extern int inteiro Slippage_ para derrapagem em pontos, que serão visíveis a partir dos parâmetros externos do Expert Advisor.
1. Funções para Posição de Abertura
Todas as funções deste bloco podem ser divididas em dois grandes grupos. Funções do primeiro grupo têm "Open" no início de seus nomes e as do segundo grupo começam com dOpen. As Funções do primeiro grupo usam distâncias relativas a partir da abertura do preço da posição expressa em pontos, bem como as variáveis externas do Stop Loss e Take Profit, ou seja, elas são representados por variáveis inteiras.
bool OpenBuyOrder1_ (bool& BUY_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT) bool OpenSellOrder1_ (bool& SELL_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT) bool OpenBuyOrder2_ (bool& BUY_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT) bool OpenSellOrder2_ (bool& SELL_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT)
O Stop Loss e Take Profit nas funções do segundo grupo são representados por variáveis de pontos flutuantes. Neste caso, os valores dessas variáveis são valores absolutos das correspondentes ordens, obtidas a partir do gráfico de preços. Isso possibilita escrever o código de um Expert Advisor que serve a um propósito específico de forma muito mais conveniente.
bool dOpenBuyOrder1_ (bool& BUY_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT) bool dpenSellOrder1_ (bool& SELL_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT) bool dOpenBuyOrder2_ (bool& BUY_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT) bool dOpenSellOrder2_ (bool& SELL_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT)
Todas as funções cujos nomes terminam em "1_" destinam-se às corretoras que permitem o ajuste do Stop Loss e Take Profit ao executar um negócio. Funções cujos nomes contenham "2_" são utilizadas junto das corretoras que permitem definir estas ordens para as posições que já estão abertas.
Em contraste com as funções existentes no Lite_EXPERT1.mqh, agora são oito funções que têm duas novas variáveis externas (datetime TimeLevel e int Margin_Mode). Então a primeira coisa que devemos fazer é olhar com atenção para elas. O valor da variável TimeLevel representa um certo limite de tempo, após a execução da operação atual. Todas as funções de negociação deste arquivo não abrirão qualquer nova posição ou ordem com o número mágico em andamento até que o limite de tempo especificado seja alcançado. O valor dessa variável externa ao executar um negócio é salvo numa variável global no disco rígido do computador e não será perdido quando reiniciar o terminal de negociação ou o sistema operacional do Windows. O uso mais básico dessa variável é bloquear a reabertura de uma posição ou a colocação de uma ordem pendente na mesma barra.
//---- static datetime TimeLevel; TimeLevel = Time[0] + Period() * 60; //---- if (!OpenBuyOrder1_ (BUY_Signal, MagicNumber, TimeLevel, Money_Management, Margin_Mode, STOPLOSS, TAKEPROFIT)) return(-1);
Supõe-se que a variável estática TimeLevel será inicializado no mesmo bloco que a variável BUY_Signal. Agora, se a função OpenBuyOrder1_() abre uma posição, ela vai salvar o valor da variável TimeLevel na variável global no disco rígido e as funções do arquivo do Lite_EXPERT2.mqh que abrem posições ou colocam ordens pendentes não vão abrir qualquer ordem com esse número mágico até o momento em que última cotação torna-se maior ou igual a este valor.
Basicamente as funções de negociação deste arquivo não zeram a variável externa do tipo bool& BUY_Signal pela referência, pois isso não é necessário, zerar somente se for executada a variável TimeLevel é inicializado para "-1"! Se definir o valor desta variável igual a zero, a função para abertura de posição não vai zerar ou salvar nada e abrirá posições a qualquer momento com base nos sinais da variável externa BUY_Signal, quando não existir encomendas com o número mágico igual ao valor da variável externa MagicNumber int.
O nome da string usado por uma variável global salva no disco rígido é gerado para testes e otimização utilizando a seguinte fórmula:
string G_Name_ = "TimeLevel", "_", AccountNumber(), "_", "_Test_", OrderSymbol(), "_", OrderMagicNumber());
Em outros casos:
string G_Name_ = "TimeLevel", "_", AccountNumber(), "_", OrderSymbol(), "_", OrderMagicNumber());
Este nome não deve ser usado para outras variáveis globais!
As funções de negociação disponíveis no Lite_EXPERT1.mqh usam apenas um método de cálculo para lote (MM com base na margem livre). Este método de cálculo do tamanho do lote pode não ser adequado para todas as estratégias. Esta questão tem sido levada em conta nas funções de negociação previstas no Lite_EXPERT2.mqh e o método de cálculo do tamanho do lote é determinado usando a variável externa int Margin_Mode. Ao determinar o método de cálculo do tamanho do lote, a variável externa Margin_Mode podem assumir valores de zero a cinco:
- 0 - MM com base na margem livre
- 1 - MM com base no saldo da conta
- 2 - MM com base nas perdas sobre a margem livre
- 3 - MM com base em perdas sobre o saldo da conta
- 4 - Lote mínimo entre 0 e 2
- 5 - Lote mínimo entre 1 e 3
- por padrão - MM com base na margem livre
Por favor, tenha em mente que se você usar o segundo ou terceiro método de cálculo do tamanho do lote, o seu Stop Loss é dinâmico e varia de negócio para negócio, você deve levar em conta os valores de limite do Stop Loss e MM. Por exemplo, se as variáveis têm os seguintes valores: Money_Management = 0.1, Margin_Mode = 3 e int StopLoss = 100 (cinco casas decimais), o Expert Advisor vai usar todo o depósito para abrir uma posição!
Então vou explicar mais uma vez essas duas variantes para valores da variável Margin_Mode (2 e 3). A função de cálculo de tamanho do lote usa a margem livre ou o valor do saldo da conta e multiplica pelo valor da variável Money_Management. O valor resultante representa o montante das perdas que podem surgir se a posição for fechada ao nível Stop Loss! Essas perdas não dependem do tamanho do Stop Loss. Assim, a função de cálculo de tamanho do lote determina o volume da posição com base no tamanho Stop Loss para que as perdas da Stop Loss sejam atraentes!
Quando o valor da variável Margin_Mode for igual a 4 ou 5, as funções de negociação calculam o tamanho do lote utilizando duas variantes ao mesmo tempo e escolhe o menor valor. Por exemplo, se Margin_Mode = 5, a função de negociação irá calcular o tamanho do lote com base no saldo de conta e com base nas perdas no saldo da conta, então usa o menor valor.
Mais uma vez, eu gostaria de mencionar que se o valor da variável Money_Management é negativo, então todas essas funções vai desconsiderar os valores das variáveis Margin_Mode e usar os valores da variável Money_Management como tamanho de lote. Ao usar esses valores, o sinal de subtração será descartado e o próprio valor será arredondado para o valor normalizado mais próximo que não pode ser maior do que o disponível. No cálculo do tamanho do lote, essas oito funções sempre verificam se a margem livre é suficiente para a execução de uma determinada operação e reduzem o tamanho do lote calculado para o valor permitido, se necessário.
2. Funções para Colocação de Ordens Pendentes
Este é o segundo grande grupo de funções, também divididas em dois grupos semelhantemente ao tópico anterior.
bool OpenBuyLimitOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT, int LEVEL, datetime Expiration) bool OpenBuyStopOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT, int LEVEL, datetime Expiration) bool OpenSellLimitOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT, int LEVEL, datetime Expiration) bool OpenSellStopOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT, int LEVEL, datetime Expiration)
bool dOpenBuyLimitOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT, double dLEVEL, datetime Expiration) bool dOpenBuyStopOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT, double dLEVEL, datetime Expiration) bool dOpenSellLimitOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT, double dLEVEL, datetime Expiration) bool dOpenSellStopOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT, double dLEVEL, datetime Expiration)
Tudo o que foi dito sobre as funções anteriores também é verdade para estas oito funções. Há apenas dois fatores que podem ser considerados como exceções. É basicamente impossível calcular o tamanho do lote quando a ordem está sendo colocada. E se o tamanho do lote é calculado no momento de colocar uma ordem pendente e de fato é feito assim, dificilmente se pode esperar que o cálculo seja em estrita conformidade com o valor da variável Money_Management. Pela mesma razão, estas funções não verificam se existem fundos suficientes para o tamanho do lote.
3. Funções para Fechamento das Posições Abertas
Este bloco consiste somente de quatro funções
bool CloseBuyOrder1_(bool& CloseStop, int MagicNumber) bool CloseSellOrder1_(bool& CloseStop, int MagicNumber) bool CloseAllBuyOrders1_(bool CloseStop) bool CloseAllSellOrders1_(bool CloseStop)
Estas funções são bastante simples e não requerem quaisquer explicações adicionais. As duas primeiras funções fecahm as posições com os números mágicos pelo símbolo (ativo) da gráfico onde o Expert Advisor está em execução. As outras duas funções fecham todas as posições abertas em execução.
4. Funções para Excluir Ordens Pendentes
A lista de funções nesta seção consiste em apenas duas funções básicas:
bool CloseOrder1_(bool& CloseStop, int cmd, int MagicNumber) bool CloseAllOrders1_(bool CloseStop, int cmd)
As variáveis externas das quais contêm a nova variável - int cmd. Os seus valores são apresentados a seguir:
- OP_BUYLIMIT 2 Ordem pendente BUY LIMIT
- OP_SELLLIMIT 3 Ordem pendente SELL LIMIT
- OP_BUYSTOP 4 Ordem pendente BUY STOP
- OP_SELLSTOP 5 Ordem pendente SELL STOP
5. Modificação da Posição e Funções do Trailing Stop
Este bloco inclui três grupos de funções:
1) modificadores de posição
bool dModifyOpenBuyOrder_ (bool& Modify_Signal, int MagicNumber, datetime ModifyTimeLevel_, double dSTOPLOSS, double dTAKEPROFIT) bool dModifyOpenSellOrder_ (bool& Modify_Signal, int MagicNumber, datetime ModifyTimeLevel_, double dSTOPLOSS, double dTAKEPROFIT) bool dModifyOpenBuyOrderS (bool& Modify_Signal, double dSTOPLOSS, double dTAKEPROFIT) bool dModifyOpenSellOrderS(bool& Modify_Signal, double dSTOPLOSS, double dTAKEPROFIT)
Todas as quatro funções deste grupo utilizam valores absolutos do Stop Loss e Take Profit numa escala do gráfico de preços e são representadas por variáveis de pontos flutuantes. Tudo escrito no que diz respeito das variáveis do primeiro e segundo grupo é verdadeiro e aplicam-se nas variáveis desse grupo também.
Por favor, note que a data e hora do valor da variável ModifyTimeLevel_ é usado apenas nas duas primeiras funções deste grupo e em nenhum outro lugar! Esta variável está completamente ausente nas duas últimas funções. Para chamar uma das duas últimas funções no código do Expert Advisor, é necessário primeiro selecionar uma ordem do tipo OP_BUY ou OP_SELL a fim de continuar trabalhando com elas, usando a função OrderSelect()! Essas funções são planejadas para trabalhar com posições abertas que não têm números mágicos. As fórmulas do nome da string da variável global com o propósito de salvar o valor da variável ModifyTimeLevel_ no disco rígido são as seguintes:
string G_Name_ = "ModifyTimeLevel_", "_", AccountNumber(), "_", "_Test_", Symbol(), "_", MagicNumber;
string G_Name_ = "ModifyTimeLevel_", "_", AccountNumber(), "_", Symbol(), "_", MagicNumber;
2) Trailing Stops
bool Make_BuyTrailingStop_ (bool& TreilSignal, int MagicNumber, datetime TrailTimeLevel, int TRAILINGSTOP) bool Make_SellTrailingStop_ (bool& TreilSignal, int MagicNumber, datetime TrailTimeLevel, int TRAILINGSTOP) bool dMake_BuyTrailingStop_ (bool& TreilSignal, int MagicNumber, datetime TrailTimeLevel_, double dTRAILINGSTOP) bool dMake_SellTrailingStop_ (bool& TreilSignal, int MagicNumber, datetime TrailTimeLevel_, double dTRAILINGSTOP)
Este grupo contém quatro Trailing Stops clássicos para mover o Stop Loss em relação ao preço atual. Dois deles têm valor em pontos com relação ao preço atual como parâmetro externo, enquanto os outros dois utilizam o valor Trailing Stop absoluto para o mesmo fim. Como nas funções anteriores, estas quatro funções usam prazos na forma das variáveis TrailTimeLevel e TrailTimeLevel_ com o valor similar. Se você pretende mudar Stops em cada tick, estas variáveis devem ser definidas como zero.
3) e mais um grupo de quatro modificadores de posição
bool BuyStoplossCorrect (int MagicNumber, int ExtPointProfit, int StoplossProfit) bool SellStoplossCorrect (int MagicNumber, int ExtPointProfit, int StoplossProfit) bool AllBuyStoplossCorrects (int ExtPointProfit, int StoplossProfit) bool AllSellStoplossCorrects(int ExtPointProfit, int StoplossProfit)
que realizam mudanças de uma única vez nos níveis de Stop Loss. As primeiras duas funções verificam o lucro em pontos, relacionando uma posição aberta com o número mágico fixado e se não for inferior ao valor da variável ExtPointProfit, então o Stop Loss é movido para ao preço atual da distância StoplossProfit, contando a partir do preço de abertura da posição.
As duas últimas funções deste grupo rastream o lucro de todas as posições abertas do símbolo (ativo) onde está funcionando com qualquer número mágico e realizam mudanças de uma única vez nos seus níveis de Stop Loss correspondentes.
6. Funções Adicionais
Este é o último e provavelmente o maior grupo de funções no arquivo Lite_EXPERT2.mqh. Muitas funções deste grupo são usadas como adicionais dentro do código de outras funções acima descritas e em muitos casos, de pouco interesse prático. Então, vou me limitar a uma revisão do mais essencial.
Primeiro de tudo, eu gostaria de voltar sua atenção para a função TimeLevelGlobalVariableDel():
void TimeLevelGlobalVariableDel(string symbol, int MagicNumber)
Após o teste e otimização, esta função apaga todas as variáveis globais que foram geradas pelas funções de negociação existentes no arquivo e salvos no disco rígido do seu computador. Esta função deve ser chamada no bloco desinicialização do Expert Advisor, como por exemplo:
//+X================================================================X+ //| Função de desinicialização do Expert personalizado | //+X================================================================X+ int deinit() { //----+ TimeLevelGlobalVariableDel(Symbol(), 1); TimeLevelGlobalVariableDel(Symbol(), 2); TimeLevelGlobalVariableDel(Symbol(), 3); TimeLevelGlobalVariableDel(Symbol(), 4); //---- Completando desinicialização do Expert Advisor return(0); //----+ }
Se isso não for feito, as variáveis globais com os últimos valores do tempo restante, após o teste ou otimização, irão bloquear esta finalidade do Expert Advisor!!!
É o caso onde frequentemente os timeframes do gráfico somente podem ser selecionados a partir da série padrão, cujo os valores são usados como variáveis externas do Expert Advisor. Manualmente pode-se sempre cometer um erro e definir o valor errado, nesses casos você pode fazer uma verificação utilizando a função TimeframeCheck(),
void TimeframeCheck(string TimeframeName, int Timeframe)
que verifica os valores de timeframe nas variáveis externas ao inicializar o Expert Advisor.
Inicialmente todos os cálculos feitos no Expert Advisor para qualquer nível de preços são baseados nos valores do gráfico de preços, isto pode nem sempre é muito claro com os preços que são mostrados nos gráficos - ASK ou BID. Então os valores obtidos a partir de gráficos de preços necessitam de ajustes para que a diferença possa ser usada nas funções de negociação. Isto pode ser feito usando a função dGhartVelueCorrect():
double dGhartVelueCorrect(int cmd, double& GhartVelue)
O objetivo da variável cmd é absolutamente idêntica à descrição fornecida no Ajuda do MetaEditor. Ao chamar esta função, o parâmetro externo GhartVelue só pode ser representado por uma variável cujo valor é alterado para aquele ajustado pela referência. Por exemplo:
//---- obter o nível de preços GhartVelue_ price double GhartVelue_ = Low[0]; //---- corrigir o nível de preços GhartVelue_ price dGhartVelueCorrect(OP_BUY, GhartVelue_);
Existem mais duas funções com o objetivo de selecionar ordens e continuar usando-as adicionalmente.
bool OrderSelect_(string symbol, int cmd, int MagicNumber, int pool) bool Order_Select(string symbol, int MagicNumber)
A variável pool pode assumir dois valores apenas: MODE_TRADES - a ordem é selecionada a partir das ordens abertas e pendentes; MODE_HISTORY - a ordem é selecionada a partir das ordens fechadas e excluídas. Se forem bem sucedidas as funções retornam como verdadeiras, caso contrário são falsas.
Em certos casos você pode precisar usar a função MarginCheck(), ela verifica o tamanho do lote em relação aos fundos disponíveis na conta e se necessário, diminui o tamanho do lote a ser adequado para os fundos disponíveis:
bool MarginCheck(string symbol, int Cmd, double& Lot)
O parâmetro Cmd nesta função só pode assumir dois valores: OP_BUY e OP_SELL. Se o cálculo for bem sucedido, a função retornará verdadeira. Em caso de erros na operação da função, o retorno é falso.
Às vezes você pode querer calcular o tamanho do lote, para este fim temos mais duas funções:
double BuyLotCount(double Money_Management, int Margin_Mode, int STOPLOSS) double SellLotCount(double Money_Management, int Margin_Mode, int STOPLOSS)
Se não houver erros as funções retornam o valor do lote, caso contrário retornam -1.
Temos mais três funções para aqueles que gostam de quebrar um código de indicador dentro dos Expert Advisors:
int IndicatorCounted_(int Number, string symbol, int timeframe) int ReSetAsIndexBuffer(string symbol, int timeframe, double& array[]) int ReSetAsIndexBuffer_(string symbol, int timeframe, double& Array[], int ArrSize)
A primeira função é equivalente à função IndicatorCounted() operando nos EAs. O número da variável externa representa o número de chamada da função no código do Expert Advisor (um número por indicador). O objectivo da segunda função é converter um array de dados declarado no escopo global para um buffer de indicador análogo, assim a função sincroniza os elementos do array cujo nome representa a variável double& array[] com os correspondente arrays das "time series". Esta função deve ser chamada na função start(), fora do alcance dos operadores de loop da iteração sobre as barras do gráfico. A terceira função é uma análoga completa da segunda, mas o número de elementos no Array[] é derivado a partir do valor limitado da variável ArrSize. Em outras palavras, neste caso o array contém o número ArrSize apenas nas últimas barras mais recentes. Esta função pode ser mais útil do que a anterior, em muitos casos os valores de código do indicador somente são adicionados a esse Array e o número ArrSize dos últimos valores é usado no código do Expert Advisor.
Finalmente as duas últimas funções:
bool IsNewBar(int Number, string symbol, int timeframe) bool MinBarCheck(string symbol, int timeframe, int MinBarTotal)
A função IsNewBar() retorna Verdadeira no ponto de tempo onde a barra é alterada nos arrays das "time series". Em todos os outros casos essa função retorna Falso. A variável Number representa o número de chamada de função no código do Expert Advisor. A função MinBarCheck() compara o número de barras do gráfico contra o valor da variável MinBarTotal. Se o número de barras é menor, então retorna Falso. Esta função é usada com o objetivo de não permitir a negociação do Expert Advisor, caso o número de barras necessárias para o cálculo não seja suficiente.
Conclusão
Isto é basicamente toda a lista das funções mais utilizadas no Lite_EXPERT2.mqh que representam o mínimo necessário para uma prática e eficiente estratégia escrita em MQL4. Nos próximos artigos desta série, vou dar exemplos específicos que ilustram o uso destas funções acima em EAs.
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/1380
![Otimização Visual de Indicador e Sinal de Rentabilidade](https://c.mql5.com/2/17/820_9.gif)
![Notificações SMS do Status do EA](https://c.mql5.com/2/17/831_34.png)
![Análise Avançada de uma Conta de Negociação](https://c.mql5.com/2/17/830_31.png)
![Expert Advisor para Negociação no Canal](https://c.mql5.com/2/17/834_22.gif)
![MQL5 - Linguagem para estratégias de negociação inseridas no terminal do cliente MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- 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